From 29a40862033a9cd80888f4b1d6681461288d3031 Mon Sep 17 00:00:00 2001 From: ColinLee Date: Tue, 7 Jul 2026 17:37:59 +0800 Subject: [PATCH 1/5] add zstd,lzma2 and some ending type. --- cpp/CMakeLists.txt | 17 + cpp/build.sh | 20 +- cpp/pom.xml | 4 + cpp/src/CMakeLists.txt | 26 + cpp/src/common/db_common.h | 14 +- cpp/src/common/global.cc | 17 +- cpp/src/common/global.h | 41 +- cpp/src/compress/CMakeLists.txt | 12 +- cpp/src/compress/compressor_factory.h | 23 +- cpp/src/compress/lzma2_compressor.cc | 164 + cpp/src/compress/lzma2_compressor.h | 54 + cpp/src/compress/zstd_compressor.cc | 132 + cpp/src/compress/zstd_compressor.h | 54 + cpp/src/cwrapper/tsfile_cwrapper.h | 18 +- cpp/src/encoding/bit_packing_utils.h | 183 + cpp/src/encoding/camel_decoder.h | 352 + cpp/src/encoding/camel_encoder.h | 444 + cpp/src/encoding/chimp_decoder.h | 270 + cpp/src/encoding/chimp_encoder.h | 314 + cpp/src/encoding/decoder_factory.h | 44 + cpp/src/encoding/encoder_factory.h | 47 + cpp/src/encoding/rlbe_decoder.h | 234 + cpp/src/encoding/rlbe_encoder.h | 260 + cpp/test/CMakeLists.txt | 18 + cpp/test/common/tsfile_common_test.cc | 33 + cpp/test/compress/lzma2_compressor_test.cc | 82 + cpp/test/compress/zstd_compressor_test.cc | 82 + cpp/test/cwrapper/cwrapper_test.cc | 31 + cpp/test/encoding/camel_codec_test.cc | 123 + cpp/test/encoding/chimp_codec_test.cc | 151 + cpp/test/encoding/rlbe_codec_test.cc | 160 + cpp/test/tools/output_format_test.cc | 5 + cpp/third_party/CMakeLists.txt | 42 +- cpp/third_party/xz-5.8.3/ABOUT-NLS | 1 + cpp/third_party/xz-5.8.3/AUTHORS | 58 + cpp/third_party/xz-5.8.3/CMakeLists.txt | 2536 ++ cpp/third_party/xz-5.8.3/COPYING | 70 + cpp/third_party/xz-5.8.3/COPYING.0BSD | 11 + cpp/third_party/xz-5.8.3/COPYING.GPLv2 | 338 + cpp/third_party/xz-5.8.3/COPYING.GPLv3 | 674 + cpp/third_party/xz-5.8.3/COPYING.LGPLv2.1 | 501 + cpp/third_party/xz-5.8.3/ChangeLog | 19452 +++++++++++ cpp/third_party/xz-5.8.3/INSTALL | 976 + cpp/third_party/xz-5.8.3/INSTALL.generic | 368 + cpp/third_party/xz-5.8.3/Makefile.am | 123 + cpp/third_party/xz-5.8.3/Makefile.in | 1105 + cpp/third_party/xz-5.8.3/NEWS | 3046 ++ cpp/third_party/xz-5.8.3/PACKAGERS | 245 + cpp/third_party/xz-5.8.3/README | 281 + cpp/third_party/xz-5.8.3/THANKS | 262 + cpp/third_party/xz-5.8.3/TODO | 88 + cpp/third_party/xz-5.8.3/aclocal.m4 | 1363 + cpp/third_party/xz-5.8.3/autogen.sh | 42 + cpp/third_party/xz-5.8.3/build-aux/compile | 364 + .../xz-5.8.3/build-aux/config.guess | 1818 ++ .../xz-5.8.3/build-aux/config.rpath | 751 + cpp/third_party/xz-5.8.3/build-aux/config.sub | 2364 ++ cpp/third_party/xz-5.8.3/build-aux/depcomp | 792 + cpp/third_party/xz-5.8.3/build-aux/install-sh | 541 + .../xz-5.8.3/build-aux/license-check.sh | 177 + cpp/third_party/xz-5.8.3/build-aux/ltmain.sh | 11625 +++++++ cpp/third_party/xz-5.8.3/build-aux/manconv.sh | 56 + cpp/third_party/xz-5.8.3/build-aux/missing | 236 + .../xz-5.8.3/build-aux/test-driver | 160 + cpp/third_party/xz-5.8.3/build-aux/version.sh | 21 + .../xz-5.8.3/cmake/remove-ordinals.cmake | 25 + .../xz-5.8.3/cmake/tuklib_common.cmake | 56 + .../xz-5.8.3/cmake/tuklib_cpucores.cmake | 184 + .../xz-5.8.3/cmake/tuklib_integer.cmake | 288 + .../cmake/tuklib_large_file_support.cmake | 54 + .../xz-5.8.3/cmake/tuklib_mbstr.cmake | 25 + .../xz-5.8.3/cmake/tuklib_physmem.cmake | 153 + .../xz-5.8.3/cmake/tuklib_progname.cmake | 19 + cpp/third_party/xz-5.8.3/config.h.in | 644 + cpp/third_party/xz-5.8.3/configure | 27060 ++++++++++++++++ cpp/third_party/xz-5.8.3/configure.ac | 1452 + cpp/third_party/xz-5.8.3/debug/Makefile.am | 27 + cpp/third_party/xz-5.8.3/debug/Makefile.in | 758 + cpp/third_party/xz-5.8.3/debug/README | 17 + cpp/third_party/xz-5.8.3/debug/crc32.c | 38 + cpp/third_party/xz-5.8.3/debug/full_flush.c | 102 + cpp/third_party/xz-5.8.3/debug/hex2bin.c | 52 + cpp/third_party/xz-5.8.3/debug/known_sizes.c | 128 + cpp/third_party/xz-5.8.3/debug/memusage.c | 50 + cpp/third_party/xz-5.8.3/debug/repeat.c | 35 + cpp/third_party/xz-5.8.3/debug/sync_flush.c | 124 + .../xz-5.8.3/debug/testfilegen-arm64.c | 116 + .../xz-5.8.3/debug/translation.bash | 95 + .../xz-5.8.3/doc/examples/00_README.txt | 31 + .../xz-5.8.3/doc/examples/01_compress_easy.c | 296 + .../xz-5.8.3/doc/examples/02_decompress.c | 286 + .../doc/examples/03_compress_custom.c | 192 + .../doc/examples/04_compress_easy_mt.c | 205 + .../xz-5.8.3/doc/examples/11_file_info.c | 205 + .../xz-5.8.3/doc/examples/Makefile | 21 + cpp/third_party/xz-5.8.3/doc/faq.txt | 244 + cpp/third_party/xz-5.8.3/doc/history.txt | 150 + .../xz-5.8.3/doc/lzma-file-format.txt | 173 + .../xz-5.8.3/doc/man/txt/lzmainfo.txt | 35 + cpp/third_party/xz-5.8.3/doc/man/txt/xz.txt | 1651 + .../xz-5.8.3/doc/man/txt/xzdec.txt | 74 + .../xz-5.8.3/doc/man/txt/xzdiff.txt | 37 + .../xz-5.8.3/doc/man/txt/xzgrep.txt | 67 + .../xz-5.8.3/doc/man/txt/xzless.txt | 36 + .../xz-5.8.3/doc/man/txt/xzmore.txt | 30 + .../xz-5.8.3/doc/xz-file-format.txt | 1174 + cpp/third_party/xz-5.8.3/dos/INSTALL.txt | 78 + cpp/third_party/xz-5.8.3/dos/Makefile | 150 + cpp/third_party/xz-5.8.3/dos/README.txt | 123 + cpp/third_party/xz-5.8.3/dos/config.h | 146 + cpp/third_party/xz-5.8.3/doxygen/Doxyfile | 45 + .../xz-5.8.3/doxygen/update-doxygen | 114 + .../xz-5.8.3/extra/7z2lzma/7z2lzma.bash | 113 + .../xz-5.8.3/extra/scanlzma/scanlzma.c | 90 + cpp/third_party/xz-5.8.3/lib/Makefile.am | 44 + cpp/third_party/xz-5.8.3/lib/Makefile.in | 625 + cpp/third_party/xz-5.8.3/lib/getopt-cdefs.h | 72 + cpp/third_party/xz-5.8.3/lib/getopt-core.h | 98 + cpp/third_party/xz-5.8.3/lib/getopt-ext.h | 79 + .../xz-5.8.3/lib/getopt-pfx-core.h | 68 + cpp/third_party/xz-5.8.3/lib/getopt-pfx-ext.h | 72 + cpp/third_party/xz-5.8.3/lib/getopt.c | 823 + cpp/third_party/xz-5.8.3/lib/getopt.in.h | 60 + cpp/third_party/xz-5.8.3/lib/getopt1.c | 163 + cpp/third_party/xz-5.8.3/lib/getopt_int.h | 120 + cpp/third_party/xz-5.8.3/m4/ax_pthread.m4 | 524 + cpp/third_party/xz-5.8.3/m4/build-to-host.m4 | 274 + cpp/third_party/xz-5.8.3/m4/getopt.m4 | 70 + cpp/third_party/xz-5.8.3/m4/gettext.m4 | 392 + cpp/third_party/xz-5.8.3/m4/host-cpu-c-abi.m4 | 529 + cpp/third_party/xz-5.8.3/m4/iconv.m4 | 324 + cpp/third_party/xz-5.8.3/m4/intlmacosx.m4 | 71 + cpp/third_party/xz-5.8.3/m4/lib-ld.m4 | 170 + cpp/third_party/xz-5.8.3/m4/lib-link.m4 | 815 + cpp/third_party/xz-5.8.3/m4/lib-prefix.m4 | 334 + cpp/third_party/xz-5.8.3/m4/libtool.m4 | 8880 +++++ cpp/third_party/xz-5.8.3/m4/ltoptions.m4 | 519 + cpp/third_party/xz-5.8.3/m4/ltsugar.m4 | 124 + cpp/third_party/xz-5.8.3/m4/ltversion.m4 | 24 + cpp/third_party/xz-5.8.3/m4/lt~obsolete.m4 | 99 + cpp/third_party/xz-5.8.3/m4/nls.m4 | 33 + cpp/third_party/xz-5.8.3/m4/po.m4 | 456 + cpp/third_party/xz-5.8.3/m4/posix-shell.m4 | 66 + cpp/third_party/xz-5.8.3/m4/progtest.m4 | 92 + cpp/third_party/xz-5.8.3/m4/tuklib_common.m4 | 23 + .../xz-5.8.3/m4/tuklib_cpucores.m4 | 181 + cpp/third_party/xz-5.8.3/m4/tuklib_integer.m4 | 260 + cpp/third_party/xz-5.8.3/m4/tuklib_mbstr.m4 | 31 + cpp/third_party/xz-5.8.3/m4/tuklib_physmem.m4 | 217 + .../xz-5.8.3/m4/tuklib_progname.m4 | 29 + cpp/third_party/xz-5.8.3/m4/visibility.m4 | 85 + cpp/third_party/xz-5.8.3/po/LINGUAS | 25 + cpp/third_party/xz-5.8.3/po/Makefile.in.in | 517 + cpp/third_party/xz-5.8.3/po/Makevars | 91 + cpp/third_party/xz-5.8.3/po/POTFILES.in | 19 + cpp/third_party/xz-5.8.3/po/Rules-quot | 66 + cpp/third_party/xz-5.8.3/po/boldquot.sed | 21 + cpp/third_party/xz-5.8.3/po/ca.gmo | Bin 0 -> 15587 bytes cpp/third_party/xz-5.8.3/po/ca.po | 1633 + cpp/third_party/xz-5.8.3/po/cs.gmo | Bin 0 -> 7983 bytes cpp/third_party/xz-5.8.3/po/cs.po | 1679 + cpp/third_party/xz-5.8.3/po/da.gmo | Bin 0 -> 9040 bytes cpp/third_party/xz-5.8.3/po/da.po | 1436 + cpp/third_party/xz-5.8.3/po/de.gmo | Bin 0 -> 29882 bytes cpp/third_party/xz-5.8.3/po/de.po | 1267 + .../xz-5.8.3/po/en@boldquot.header | 35 + cpp/third_party/xz-5.8.3/po/en@quot.header | 32 + cpp/third_party/xz-5.8.3/po/eo.gmo | Bin 0 -> 15060 bytes cpp/third_party/xz-5.8.3/po/eo.po | 1627 + cpp/third_party/xz-5.8.3/po/es.gmo | Bin 0 -> 29244 bytes cpp/third_party/xz-5.8.3/po/es.po | 1266 + cpp/third_party/xz-5.8.3/po/fi.gmo | Bin 0 -> 28225 bytes cpp/third_party/xz-5.8.3/po/fi.po | 1266 + cpp/third_party/xz-5.8.3/po/fr.gmo | Bin 0 -> 10232 bytes cpp/third_party/xz-5.8.3/po/fr.po | 1668 + cpp/third_party/xz-5.8.3/po/hr.gmo | Bin 0 -> 28799 bytes cpp/third_party/xz-5.8.3/po/hr.po | 1271 + cpp/third_party/xz-5.8.3/po/hu.gmo | Bin 0 -> 15949 bytes cpp/third_party/xz-5.8.3/po/hu.po | 1673 + cpp/third_party/xz-5.8.3/po/insert-header.sed | 31 + cpp/third_party/xz-5.8.3/po/it.gmo | Bin 0 -> 28688 bytes cpp/third_party/xz-5.8.3/po/it.po | 1270 + cpp/third_party/xz-5.8.3/po/ka.gmo | Bin 0 -> 46526 bytes cpp/third_party/xz-5.8.3/po/ka.po | 1264 + cpp/third_party/xz-5.8.3/po/ko.gmo | Bin 0 -> 29850 bytes cpp/third_party/xz-5.8.3/po/ko.po | 1266 + cpp/third_party/xz-5.8.3/po/nl.gmo | Bin 0 -> 28532 bytes cpp/third_party/xz-5.8.3/po/nl.po | 1269 + cpp/third_party/xz-5.8.3/po/pl.gmo | Bin 0 -> 29090 bytes cpp/third_party/xz-5.8.3/po/pl.po | 1266 + cpp/third_party/xz-5.8.3/po/pt.gmo | Bin 0 -> 28796 bytes cpp/third_party/xz-5.8.3/po/pt.po | 1278 + cpp/third_party/xz-5.8.3/po/pt_BR.gmo | Bin 0 -> 15660 bytes cpp/third_party/xz-5.8.3/po/pt_BR.po | 1683 + cpp/third_party/xz-5.8.3/po/quot.sed | 17 + .../xz-5.8.3/po/remove-potcdate.sed | 25 + cpp/third_party/xz-5.8.3/po/ro.gmo | Bin 0 -> 30418 bytes cpp/third_party/xz-5.8.3/po/ro.po | 1311 + cpp/third_party/xz-5.8.3/po/sr.gmo | Bin 0 -> 36503 bytes cpp/third_party/xz-5.8.3/po/sr.po | 1264 + cpp/third_party/xz-5.8.3/po/stamp-po | 1 + cpp/third_party/xz-5.8.3/po/sv.gmo | Bin 0 -> 28399 bytes cpp/third_party/xz-5.8.3/po/sv.po | 1271 + cpp/third_party/xz-5.8.3/po/tr.gmo | Bin 0 -> 28887 bytes cpp/third_party/xz-5.8.3/po/tr.po | 1264 + cpp/third_party/xz-5.8.3/po/uk.gmo | Bin 0 -> 39005 bytes cpp/third_party/xz-5.8.3/po/uk.po | 1268 + cpp/third_party/xz-5.8.3/po/vi.gmo | Bin 0 -> 16808 bytes cpp/third_party/xz-5.8.3/po/vi.po | 1671 + cpp/third_party/xz-5.8.3/po/xz.pot | 1264 + cpp/third_party/xz-5.8.3/po/xz.pot-header | 7 + cpp/third_party/xz-5.8.3/po/zh_CN.gmo | Bin 0 -> 14488 bytes cpp/third_party/xz-5.8.3/po/zh_CN.po | 1650 + cpp/third_party/xz-5.8.3/po/zh_TW.gmo | Bin 0 -> 26773 bytes cpp/third_party/xz-5.8.3/po/zh_TW.po | 1267 + cpp/third_party/xz-5.8.3/po4a/ar.po | 3905 +++ cpp/third_party/xz-5.8.3/po4a/de.po | 3919 +++ cpp/third_party/xz-5.8.3/po4a/fr.po | 3978 +++ cpp/third_party/xz-5.8.3/po4a/it.po | 3896 +++ cpp/third_party/xz-5.8.3/po4a/ko.po | 3904 +++ .../xz-5.8.3/po4a/man/ar/lzmainfo.1 | 41 + cpp/third_party/xz-5.8.3/po4a/man/ar/xz.1 | 1791 + cpp/third_party/xz-5.8.3/po4a/man/ar/xzdec.1 | 77 + cpp/third_party/xz-5.8.3/po4a/man/ar/xzdiff.1 | 52 + cpp/third_party/xz-5.8.3/po4a/man/ar/xzgrep.1 | 89 + cpp/third_party/xz-5.8.3/po4a/man/ar/xzless.1 | 45 + cpp/third_party/xz-5.8.3/po4a/man/ar/xzmore.1 | 47 + .../xz-5.8.3/po4a/man/de/lzmainfo.1 | 46 + cpp/third_party/xz-5.8.3/po4a/man/de/xz.1 | 2117 ++ cpp/third_party/xz-5.8.3/po4a/man/de/xzdec.1 | 88 + cpp/third_party/xz-5.8.3/po4a/man/de/xzdiff.1 | 59 + cpp/third_party/xz-5.8.3/po4a/man/de/xzgrep.1 | 97 + cpp/third_party/xz-5.8.3/po4a/man/de/xzless.1 | 50 + cpp/third_party/xz-5.8.3/po4a/man/de/xzmore.1 | 52 + .../xz-5.8.3/po4a/man/fr/lzmainfo.1 | 47 + cpp/third_party/xz-5.8.3/po4a/man/fr/xz.1 | 2027 ++ cpp/third_party/xz-5.8.3/po4a/man/fr/xzdec.1 | 90 + cpp/third_party/xz-5.8.3/po4a/man/fr/xzless.1 | 49 + .../xz-5.8.3/po4a/man/it/lzmainfo.1 | 45 + cpp/third_party/xz-5.8.3/po4a/man/it/xz.1 | 2080 ++ cpp/third_party/xz-5.8.3/po4a/man/it/xzdec.1 | 88 + cpp/third_party/xz-5.8.3/po4a/man/it/xzdiff.1 | 55 + cpp/third_party/xz-5.8.3/po4a/man/it/xzgrep.1 | 94 + cpp/third_party/xz-5.8.3/po4a/man/it/xzless.1 | 47 + cpp/third_party/xz-5.8.3/po4a/man/it/xzmore.1 | 50 + .../xz-5.8.3/po4a/man/ko/lzmainfo.1 | 38 + cpp/third_party/xz-5.8.3/po4a/man/ko/xz.1 | 1585 + cpp/third_party/xz-5.8.3/po4a/man/ko/xzdec.1 | 72 + cpp/third_party/xz-5.8.3/po4a/man/ko/xzdiff.1 | 52 + cpp/third_party/xz-5.8.3/po4a/man/ko/xzgrep.1 | 85 + cpp/third_party/xz-5.8.3/po4a/man/ko/xzless.1 | 41 + cpp/third_party/xz-5.8.3/po4a/man/ko/xzmore.1 | 44 + .../xz-5.8.3/po4a/man/pt_BR/lzmainfo.1 | 45 + cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xz.1 | 1994 ++ .../xz-5.8.3/po4a/man/pt_BR/xzdec.1 | 87 + .../xz-5.8.3/po4a/man/pt_BR/xzless.1 | 48 + .../xz-5.8.3/po4a/man/ro/lzmainfo.1 | 57 + cpp/third_party/xz-5.8.3/po4a/man/ro/xz.1 | 2111 ++ cpp/third_party/xz-5.8.3/po4a/man/ro/xzdec.1 | 101 + cpp/third_party/xz-5.8.3/po4a/man/ro/xzdiff.1 | 70 + cpp/third_party/xz-5.8.3/po4a/man/ro/xzgrep.1 | 107 + cpp/third_party/xz-5.8.3/po4a/man/ro/xzless.1 | 60 + cpp/third_party/xz-5.8.3/po4a/man/ro/xzmore.1 | 62 + .../xz-5.8.3/po4a/man/sr/lzmainfo.1 | 42 + cpp/third_party/xz-5.8.3/po4a/man/sr/xz.1 | 1928 ++ cpp/third_party/xz-5.8.3/po4a/man/sr/xzdec.1 | 81 + cpp/third_party/xz-5.8.3/po4a/man/sr/xzdiff.1 | 54 + cpp/third_party/xz-5.8.3/po4a/man/sr/xzgrep.1 | 92 + cpp/third_party/xz-5.8.3/po4a/man/sr/xzless.1 | 47 + cpp/third_party/xz-5.8.3/po4a/man/sr/xzmore.1 | 49 + .../xz-5.8.3/po4a/man/sv/lzmainfo.1 | 42 + cpp/third_party/xz-5.8.3/po4a/man/sv/xz.1 | 1954 ++ cpp/third_party/xz-5.8.3/po4a/man/sv/xzdec.1 | 87 + cpp/third_party/xz-5.8.3/po4a/man/sv/xzdiff.1 | 54 + cpp/third_party/xz-5.8.3/po4a/man/sv/xzgrep.1 | 92 + cpp/third_party/xz-5.8.3/po4a/man/sv/xzless.1 | 47 + cpp/third_party/xz-5.8.3/po4a/man/sv/xzmore.1 | 48 + .../xz-5.8.3/po4a/man/uk/lzmainfo.1 | 45 + cpp/third_party/xz-5.8.3/po4a/man/uk/xz.1 | 2039 ++ cpp/third_party/xz-5.8.3/po4a/man/uk/xzdec.1 | 85 + cpp/third_party/xz-5.8.3/po4a/man/uk/xzdiff.1 | 56 + cpp/third_party/xz-5.8.3/po4a/man/uk/xzgrep.1 | 96 + cpp/third_party/xz-5.8.3/po4a/man/uk/xzless.1 | 49 + cpp/third_party/xz-5.8.3/po4a/man/uk/xzmore.1 | 51 + cpp/third_party/xz-5.8.3/po4a/po4a.conf | 16 + cpp/third_party/xz-5.8.3/po4a/pt_BR.po | 4003 +++ cpp/third_party/xz-5.8.3/po4a/ro.po | 3936 +++ cpp/third_party/xz-5.8.3/po4a/sr.po | 3908 +++ cpp/third_party/xz-5.8.3/po4a/sv.po | 3904 +++ cpp/third_party/xz-5.8.3/po4a/uk.po | 3908 +++ cpp/third_party/xz-5.8.3/po4a/update-po | 93 + cpp/third_party/xz-5.8.3/po4a/xz-man.pot | 3889 +++ cpp/third_party/xz-5.8.3/src/Makefile.am | 45 + cpp/third_party/xz-5.8.3/src/Makefile.in | 717 + .../xz-5.8.3/src/common/common_w32res.rc | 57 + .../xz-5.8.3/src/common/my_landlock.h | 184 + .../xz-5.8.3/src/common/mythread.h | 549 + cpp/third_party/xz-5.8.3/src/common/sysdefs.h | 229 + .../xz-5.8.3/src/common/tuklib_common.h | 95 + .../xz-5.8.3/src/common/tuklib_config.h | 12 + .../xz-5.8.3/src/common/tuklib_cpucores.c | 108 + .../xz-5.8.3/src/common/tuklib_cpucores.h | 22 + .../xz-5.8.3/src/common/tuklib_exit.c | 57 + .../xz-5.8.3/src/common/tuklib_exit.h | 24 + .../xz-5.8.3/src/common/tuklib_gettext.h | 54 + .../xz-5.8.3/src/common/tuklib_integer.h | 953 + .../xz-5.8.3/src/common/tuklib_mbstr.h | 78 + .../xz-5.8.3/src/common/tuklib_mbstr_fw.c | 30 + .../src/common/tuklib_mbstr_nonprint.c | 162 + .../src/common/tuklib_mbstr_nonprint.h | 71 + .../xz-5.8.3/src/common/tuklib_mbstr_width.c | 86 + .../xz-5.8.3/src/common/tuklib_mbstr_wrap.c | 294 + .../xz-5.8.3/src/common/tuklib_mbstr_wrap.h | 204 + .../xz-5.8.3/src/common/tuklib_open_stdxxx.c | 56 + .../xz-5.8.3/src/common/tuklib_open_stdxxx.h | 22 + .../xz-5.8.3/src/common/tuklib_physmem.c | 224 + .../xz-5.8.3/src/common/tuklib_physmem.h | 27 + .../xz-5.8.3/src/common/tuklib_progname.c | 49 + .../xz-5.8.3/src/common/tuklib_progname.h | 31 + .../src/common/w32_application.manifest | 28 + .../w32_application.manifest.comments.txt | 192 + .../xz-5.8.3/src/liblzma/Makefile.am | 128 + .../xz-5.8.3/src/liblzma/Makefile.in | 2237 ++ .../xz-5.8.3/src/liblzma/api/Makefile.am | 38 + .../xz-5.8.3/src/liblzma/api/Makefile.in | 665 + .../xz-5.8.3/src/liblzma/api/lzma.h | 327 + .../xz-5.8.3/src/liblzma/api/lzma/base.h | 749 + .../xz-5.8.3/src/liblzma/api/lzma/bcj.h | 195 + .../xz-5.8.3/src/liblzma/api/lzma/block.h | 694 + .../xz-5.8.3/src/liblzma/api/lzma/check.h | 163 + .../xz-5.8.3/src/liblzma/api/lzma/container.h | 993 + .../xz-5.8.3/src/liblzma/api/lzma/delta.h | 95 + .../xz-5.8.3/src/liblzma/api/lzma/filter.h | 769 + .../xz-5.8.3/src/liblzma/api/lzma/hardware.h | 62 + .../xz-5.8.3/src/liblzma/api/lzma/index.h | 882 + .../src/liblzma/api/lzma/index_hash.h | 123 + .../xz-5.8.3/src/liblzma/api/lzma/lzma12.h | 568 + .../src/liblzma/api/lzma/stream_flags.h | 265 + .../xz-5.8.3/src/liblzma/api/lzma/version.h | 134 + .../xz-5.8.3/src/liblzma/api/lzma/vli.h | 166 + .../xz-5.8.3/src/liblzma/check/Makefile.inc | 50 + .../xz-5.8.3/src/liblzma/check/check.c | 173 + .../xz-5.8.3/src/liblzma/check/check.h | 156 + .../xz-5.8.3/src/liblzma/check/crc32_arm64.h | 148 + .../xz-5.8.3/src/liblzma/check/crc32_fast.c | 196 + .../src/liblzma/check/crc32_loongarch.h | 65 + .../xz-5.8.3/src/liblzma/check/crc32_small.c | 70 + .../src/liblzma/check/crc32_table_be.h | 527 + .../src/liblzma/check/crc32_table_le.h | 527 + .../src/liblzma/check/crc32_tablegen.c | 120 + .../xz-5.8.3/src/liblzma/check/crc32_x86.S | 308 + .../xz-5.8.3/src/liblzma/check/crc64_fast.c | 161 + .../xz-5.8.3/src/liblzma/check/crc64_small.c | 57 + .../src/liblzma/check/crc64_table_be.h | 523 + .../src/liblzma/check/crc64_table_le.h | 523 + .../src/liblzma/check/crc64_tablegen.c | 89 + .../xz-5.8.3/src/liblzma/check/crc64_x86.S | 291 + .../src/liblzma/check/crc_clmul_consts_gen.c | 160 + .../xz-5.8.3/src/liblzma/check/crc_common.h | 181 + .../src/liblzma/check/crc_x86_clmul.h | 377 + .../xz-5.8.3/src/liblzma/check/sha256.c | 189 + .../xz-5.8.3/src/liblzma/common/Makefile.inc | 100 + .../src/liblzma/common/alone_decoder.c | 249 + .../src/liblzma/common/alone_decoder.h | 22 + .../src/liblzma/common/alone_encoder.c | 151 + .../src/liblzma/common/auto_decoder.c | 204 + .../src/liblzma/common/block_buffer_decoder.c | 79 + .../src/liblzma/common/block_buffer_encoder.c | 354 + .../src/liblzma/common/block_buffer_encoder.h | 23 + .../src/liblzma/common/block_decoder.c | 286 + .../src/liblzma/common/block_decoder.h | 21 + .../src/liblzma/common/block_encoder.c | 224 + .../src/liblzma/common/block_encoder.h | 46 + .../src/liblzma/common/block_header_decoder.c | 114 + .../src/liblzma/common/block_header_encoder.c | 131 + .../xz-5.8.3/src/liblzma/common/block_util.c | 89 + .../xz-5.8.3/src/liblzma/common/common.c | 486 + .../xz-5.8.3/src/liblzma/common/common.h | 412 + .../src/liblzma/common/easy_buffer_encoder.c | 26 + .../liblzma/common/easy_decoder_memusage.c | 23 + .../src/liblzma/common/easy_encoder.c | 23 + .../liblzma/common/easy_encoder_memusage.c | 23 + .../xz-5.8.3/src/liblzma/common/easy_preset.c | 26 + .../xz-5.8.3/src/liblzma/common/easy_preset.h | 36 + .../xz-5.8.3/src/liblzma/common/file_info.c | 850 + .../liblzma/common/filter_buffer_decoder.c | 87 + .../liblzma/common/filter_buffer_encoder.c | 54 + .../src/liblzma/common/filter_common.c | 393 + .../src/liblzma/common/filter_common.h | 50 + .../src/liblzma/common/filter_decoder.c | 214 + .../src/liblzma/common/filter_decoder.h | 22 + .../src/liblzma/common/filter_encoder.c | 330 + .../src/liblzma/common/filter_encoder.h | 22 + .../src/liblzma/common/filter_flags_decoder.c | 45 + .../src/liblzma/common/filter_flags_encoder.c | 55 + .../src/liblzma/common/hardware_cputhreads.c | 33 + .../src/liblzma/common/hardware_physmem.c | 24 + .../xz-5.8.3/src/liblzma/common/index.c | 1289 + .../xz-5.8.3/src/liblzma/common/index.h | 80 + .../src/liblzma/common/index_decoder.c | 369 + .../src/liblzma/common/index_decoder.h | 24 + .../src/liblzma/common/index_encoder.c | 260 + .../src/liblzma/common/index_encoder.h | 22 + .../xz-5.8.3/src/liblzma/common/index_hash.c | 341 + .../src/liblzma/common/lzip_decoder.c | 414 + .../src/liblzma/common/lzip_decoder.h | 21 + .../xz-5.8.3/src/liblzma/common/memcmplen.h | 192 + .../src/liblzma/common/microlzma_decoder.c | 220 + .../src/liblzma/common/microlzma_encoder.c | 140 + .../xz-5.8.3/src/liblzma/common/outqueue.c | 286 + .../xz-5.8.3/src/liblzma/common/outqueue.h | 259 + .../liblzma/common/stream_buffer_decoder.c | 90 + .../liblzma/common/stream_buffer_encoder.c | 141 + .../src/liblzma/common/stream_decoder.c | 469 + .../src/liblzma/common/stream_decoder.h | 21 + .../src/liblzma/common/stream_decoder_mt.c | 2004 ++ .../src/liblzma/common/stream_encoder.c | 354 + .../src/liblzma/common/stream_encoder_mt.c | 1278 + .../src/liblzma/common/stream_flags_common.c | 46 + .../src/liblzma/common/stream_flags_common.h | 35 + .../src/liblzma/common/stream_flags_decoder.c | 87 + .../src/liblzma/common/stream_flags_encoder.c | 85 + .../src/liblzma/common/string_conversion.c | 1363 + .../xz-5.8.3/src/liblzma/common/vli_decoder.c | 85 + .../xz-5.8.3/src/liblzma/common/vli_encoder.c | 68 + .../xz-5.8.3/src/liblzma/common/vli_size.c | 29 + .../xz-5.8.3/src/liblzma/delta/Makefile.inc | 19 + .../xz-5.8.3/src/liblzma/delta/delta_common.c | 72 + .../xz-5.8.3/src/liblzma/delta/delta_common.h | 19 + .../src/liblzma/delta/delta_decoder.c | 87 + .../src/liblzma/delta/delta_decoder.h | 25 + .../src/liblzma/delta/delta_encoder.c | 132 + .../src/liblzma/delta/delta_encoder.h | 23 + .../src/liblzma/delta/delta_private.h | 36 + .../xz-5.8.3/src/liblzma/liblzma.pc.in | 17 + .../xz-5.8.3/src/liblzma/liblzma_generic.map | 138 + .../xz-5.8.3/src/liblzma/liblzma_linux.map | 153 + .../xz-5.8.3/src/liblzma/liblzma_w32res.rc | 19 + .../xz-5.8.3/src/liblzma/lz/Makefile.inc | 18 + .../xz-5.8.3/src/liblzma/lz/lz_decoder.c | 333 + .../xz-5.8.3/src/liblzma/lz/lz_decoder.h | 325 + .../xz-5.8.3/src/liblzma/lz/lz_encoder.c | 632 + .../xz-5.8.3/src/liblzma/lz/lz_encoder.h | 352 + .../xz-5.8.3/src/liblzma/lz/lz_encoder_hash.h | 122 + .../src/liblzma/lz/lz_encoder_hash_table.h | 70 + .../xz-5.8.3/src/liblzma/lz/lz_encoder_mf.c | 744 + .../xz-5.8.3/src/liblzma/lzma/Makefile.inc | 40 + .../xz-5.8.3/src/liblzma/lzma/fastpos.h | 141 + .../xz-5.8.3/src/liblzma/lzma/fastpos_table.c | 521 + .../src/liblzma/lzma/fastpos_tablegen.c | 58 + .../xz-5.8.3/src/liblzma/lzma/lzma2_decoder.c | 310 + .../xz-5.8.3/src/liblzma/lzma/lzma2_decoder.h | 28 + .../xz-5.8.3/src/liblzma/lzma/lzma2_encoder.c | 413 + .../xz-5.8.3/src/liblzma/lzma/lzma2_encoder.h | 42 + .../xz-5.8.3/src/liblzma/lzma/lzma_common.h | 240 + .../xz-5.8.3/src/liblzma/lzma/lzma_decoder.c | 1263 + .../xz-5.8.3/src/liblzma/lzma/lzma_decoder.h | 53 + .../xz-5.8.3/src/liblzma/lzma/lzma_encoder.c | 786 + .../xz-5.8.3/src/liblzma/lzma/lzma_encoder.h | 58 + .../liblzma/lzma/lzma_encoder_optimum_fast.c | 169 + .../lzma/lzma_encoder_optimum_normal.c | 858 + .../src/liblzma/lzma/lzma_encoder_presets.c | 63 + .../src/liblzma/lzma/lzma_encoder_private.h | 161 + .../src/liblzma/rangecoder/Makefile.inc | 17 + .../xz-5.8.3/src/liblzma/rangecoder/price.h | 92 + .../src/liblzma/rangecoder/price_table.c | 24 + .../src/liblzma/rangecoder/price_tablegen.c | 93 + .../src/liblzma/rangecoder/range_common.h | 77 + .../src/liblzma/rangecoder/range_decoder.h | 967 + .../src/liblzma/rangecoder/range_encoder.h | 349 + .../xz-5.8.3/src/liblzma/simple/Makefile.inc | 51 + .../xz-5.8.3/src/liblzma/simple/arm.c | 76 + .../xz-5.8.3/src/liblzma/simple/arm64.c | 156 + .../xz-5.8.3/src/liblzma/simple/armthumb.c | 84 + .../xz-5.8.3/src/liblzma/simple/ia64.c | 117 + .../xz-5.8.3/src/liblzma/simple/powerpc.c | 81 + .../xz-5.8.3/src/liblzma/simple/riscv.c | 773 + .../src/liblzma/simple/simple_coder.c | 291 + .../src/liblzma/simple/simple_coder.h | 89 + .../src/liblzma/simple/simple_decoder.c | 39 + .../src/liblzma/simple/simple_decoder.h | 21 + .../src/liblzma/simple/simple_encoder.c | 37 + .../src/liblzma/simple/simple_encoder.h | 22 + .../src/liblzma/simple/simple_private.h | 73 + .../xz-5.8.3/src/liblzma/simple/sparc.c | 87 + .../xz-5.8.3/src/liblzma/simple/x86.c | 181 + .../xz-5.8.3/src/liblzma/validate_map.sh | 163 + .../xz-5.8.3/src/lzmainfo/Makefile.am | 66 + .../xz-5.8.3/src/lzmainfo/Makefile.in | 936 + .../xz-5.8.3/src/lzmainfo/lzmainfo.1 | 58 + .../xz-5.8.3/src/lzmainfo/lzmainfo.c | 243 + .../xz-5.8.3/src/lzmainfo/lzmainfo_w32res.rc | 11 + .../xz-5.8.3/src/scripts/Makefile.am | 85 + .../xz-5.8.3/src/scripts/Makefile.in | 713 + cpp/third_party/xz-5.8.3/src/scripts/xzdiff.1 | 99 + .../xz-5.8.3/src/scripts/xzdiff.in | 224 + cpp/third_party/xz-5.8.3/src/scripts/xzgrep.1 | 148 + .../xz-5.8.3/src/scripts/xzgrep.in | 302 + cpp/third_party/xz-5.8.3/src/scripts/xzless.1 | 69 + .../xz-5.8.3/src/scripts/xzless.in | 76 + cpp/third_party/xz-5.8.3/src/scripts/xzmore.1 | 69 + .../xz-5.8.3/src/scripts/xzmore.in | 82 + cpp/third_party/xz-5.8.3/src/xz/Makefile.am | 135 + cpp/third_party/xz-5.8.3/src/xz/Makefile.in | 1231 + cpp/third_party/xz-5.8.3/src/xz/args.c | 914 + cpp/third_party/xz-5.8.3/src/xz/args.h | 44 + cpp/third_party/xz-5.8.3/src/xz/coder.c | 1476 + cpp/third_party/xz-5.8.3/src/xz/coder.h | 107 + cpp/third_party/xz-5.8.3/src/xz/file_io.c | 1485 + cpp/third_party/xz-5.8.3/src/xz/file_io.h | 188 + cpp/third_party/xz-5.8.3/src/xz/hardware.c | 413 + cpp/third_party/xz-5.8.3/src/xz/hardware.h | 74 + cpp/third_party/xz-5.8.3/src/xz/list.c | 1357 + cpp/third_party/xz-5.8.3/src/xz/list.h | 17 + cpp/third_party/xz-5.8.3/src/xz/main.c | 381 + cpp/third_party/xz-5.8.3/src/xz/main.h | 29 + cpp/third_party/xz-5.8.3/src/xz/message.c | 1326 + cpp/third_party/xz-5.8.3/src/xz/message.h | 168 + cpp/third_party/xz-5.8.3/src/xz/mytime.c | 177 + cpp/third_party/xz-5.8.3/src/xz/mytime.h | 48 + cpp/third_party/xz-5.8.3/src/xz/options.c | 361 + cpp/third_party/xz-5.8.3/src/xz/options.h | 30 + cpp/third_party/xz-5.8.3/src/xz/private.h | 81 + cpp/third_party/xz-5.8.3/src/xz/sandbox.c | 317 + cpp/third_party/xz-5.8.3/src/xz/sandbox.h | 43 + cpp/third_party/xz-5.8.3/src/xz/signals.c | 237 + cpp/third_party/xz-5.8.3/src/xz/signals.h | 42 + cpp/third_party/xz-5.8.3/src/xz/suffix.c | 408 + cpp/third_party/xz-5.8.3/src/xz/suffix.h | 35 + cpp/third_party/xz-5.8.3/src/xz/util.c | 315 + cpp/third_party/xz-5.8.3/src/xz/util.h | 132 + cpp/third_party/xz-5.8.3/src/xz/xz.1 | 3264 ++ cpp/third_party/xz-5.8.3/src/xz/xz_w32res.rc | 11 + .../xz-5.8.3/src/xzdec/Makefile.am | 111 + .../xz-5.8.3/src/xzdec/Makefile.in | 1019 + .../xz-5.8.3/src/xzdec/lzmadec_w32res.rc | 11 + cpp/third_party/xz-5.8.3/src/xzdec/xzdec.1 | 144 + cpp/third_party/xz-5.8.3/src/xzdec/xzdec.c | 489 + .../xz-5.8.3/src/xzdec/xzdec_w32res.rc | 11 + cpp/third_party/xz-5.8.3/tests/Makefile.am | 83 + cpp/third_party/xz-5.8.3/tests/Makefile.in | 1414 + .../xz-5.8.3/tests/create_compress_files.c | 162 + cpp/third_party/xz-5.8.3/tests/files/README | 415 + .../tests/files/bad-0-backward_size.xz | Bin 0 -> 32 bytes .../tests/files/bad-0-empty-truncated.xz | Bin 0 -> 31 bytes .../tests/files/bad-0-footer_magic.xz | Bin 0 -> 32 bytes .../tests/files/bad-0-header_magic.xz | Bin 0 -> 32 bytes .../tests/files/bad-0-nonempty_index.xz | Bin 0 -> 32 bytes .../xz-5.8.3/tests/files/bad-0cat-alone.xz | Bin 0 -> 55 bytes .../tests/files/bad-0cat-header_magic.xz | Bin 0 -> 64 bytes .../xz-5.8.3/tests/files/bad-0catpad-empty.xz | Bin 0 -> 69 bytes .../xz-5.8.3/tests/files/bad-0pad-empty.xz | Bin 0 -> 37 bytes .../tests/files/bad-1-block_header-1.xz | Bin 0 -> 64 bytes .../tests/files/bad-1-block_header-2.xz | Bin 0 -> 64 bytes .../tests/files/bad-1-block_header-3.xz | Bin 0 -> 68 bytes .../tests/files/bad-1-block_header-4.xz | Bin 0 -> 76 bytes .../tests/files/bad-1-block_header-5.xz | Bin 0 -> 72 bytes .../tests/files/bad-1-block_header-6.xz | Bin 0 -> 72 bytes .../tests/files/bad-1-check-crc32-2.xz | Bin 0 -> 72 bytes .../xz-5.8.3/tests/files/bad-1-check-crc32.xz | Bin 0 -> 68 bytes .../xz-5.8.3/tests/files/bad-1-check-crc64.xz | Bin 0 -> 72 bytes .../tests/files/bad-1-check-sha256.xz | Bin 0 -> 96 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-1.xz | Bin 0 -> 64 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-10.xz | Bin 0 -> 60 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-11.xz | Bin 0 -> 64 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-2.xz | Bin 0 -> 424 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-3.xz | Bin 0 -> 424 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-4.xz | Bin 0 -> 408 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-5.xz | Bin 0 -> 408 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-6.xz | Bin 0 -> 68 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-7.xz | Bin 0 -> 408 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-8.xz | Bin 0 -> 464 bytes .../xz-5.8.3/tests/files/bad-1-lzma2-9.xz | Bin 0 -> 72 bytes .../tests/files/bad-1-stream_flags-1.xz | Bin 0 -> 68 bytes .../tests/files/bad-1-stream_flags-2.xz | Bin 0 -> 68 bytes .../tests/files/bad-1-stream_flags-3.xz | Bin 0 -> 68 bytes .../tests/files/bad-1-v0-uncomp-size.lz | Bin 0 -> 42 bytes .../xz-5.8.3/tests/files/bad-1-v1-crc32.lz | Bin 0 -> 50 bytes .../xz-5.8.3/tests/files/bad-1-v1-dict-1.lz | Bin 0 -> 50 bytes .../xz-5.8.3/tests/files/bad-1-v1-dict-2.lz | Bin 0 -> 50 bytes .../xz-5.8.3/tests/files/bad-1-v1-magic-1.lz | Bin 0 -> 50 bytes .../xz-5.8.3/tests/files/bad-1-v1-magic-2.lz | Bin 0 -> 50 bytes .../tests/files/bad-1-v1-member-size.lz | Bin 0 -> 50 bytes .../tests/files/bad-1-v1-trailing-magic.lz | Bin 0 -> 54 bytes .../tests/files/bad-1-v1-uncomp-size.lz | Bin 0 -> 50 bytes .../xz-5.8.3/tests/files/bad-1-vli-1.xz | Bin 0 -> 72 bytes .../xz-5.8.3/tests/files/bad-1-vli-2.xz | Bin 0 -> 76 bytes .../files/bad-2-compressed_data_padding.xz | Bin 0 -> 92 bytes .../xz-5.8.3/tests/files/bad-2-index-1.xz | Bin 0 -> 92 bytes .../xz-5.8.3/tests/files/bad-2-index-2.xz | Bin 0 -> 92 bytes .../xz-5.8.3/tests/files/bad-2-index-3.xz | Bin 0 -> 92 bytes .../xz-5.8.3/tests/files/bad-2-index-4.xz | Bin 0 -> 92 bytes .../xz-5.8.3/tests/files/bad-2-index-5.xz | Bin 0 -> 92 bytes .../files/bad-3-index-uncomp-overflow.xz | Bin 0 -> 132 bytes .../files/bad-too_big_size-with_eopm.lzma | Bin 0 -> 37 bytes .../bad-too_small_size-without_eopm-1.lzma | Bin 0 -> 31 bytes .../bad-too_small_size-without_eopm-2.lzma | Bin 0 -> 31 bytes .../bad-too_small_size-without_eopm-3.lzma | Bin 0 -> 36 bytes .../files/bad-unknown_size-without_eopm.lzma | Bin 0 -> 31 bytes .../xz-5.8.3/tests/files/good-0-empty.xz | Bin 0 -> 32 bytes .../xz-5.8.3/tests/files/good-0cat-empty.xz | Bin 0 -> 64 bytes .../tests/files/good-0catpad-empty.xz | Bin 0 -> 68 bytes .../xz-5.8.3/tests/files/good-0pad-empty.xz | Bin 0 -> 36 bytes .../tests/files/good-1-3delta-lzma2.xz | Bin 0 -> 528 bytes .../tests/files/good-1-arm64-lzma2-1.xz | Bin 0 -> 512 bytes .../tests/files/good-1-arm64-lzma2-2.xz | Bin 0 -> 488 bytes .../tests/files/good-1-block_header-1.xz | Bin 0 -> 72 bytes .../tests/files/good-1-block_header-2.xz | Bin 0 -> 68 bytes .../tests/files/good-1-block_header-3.xz | Bin 0 -> 68 bytes .../tests/files/good-1-check-crc32.xz | Bin 0 -> 68 bytes .../tests/files/good-1-check-crc64.xz | Bin 0 -> 72 bytes .../xz-5.8.3/tests/files/good-1-check-none.xz | Bin 0 -> 64 bytes .../tests/files/good-1-check-sha256.xz | Bin 0 -> 96 bytes .../tests/files/good-1-delta-lzma2.tiff.xz | Bin 0 -> 51316 bytes .../tests/files/good-1-empty-bcj-lzma2.xz | Bin 0 -> 52 bytes .../xz-5.8.3/tests/files/good-1-lzma2-1.xz | Bin 0 -> 424 bytes .../xz-5.8.3/tests/files/good-1-lzma2-2.xz | Bin 0 -> 424 bytes .../xz-5.8.3/tests/files/good-1-lzma2-3.xz | Bin 0 -> 408 bytes .../xz-5.8.3/tests/files/good-1-lzma2-4.xz | Bin 0 -> 464 bytes .../xz-5.8.3/tests/files/good-1-lzma2-5.xz | Bin 0 -> 52 bytes .../tests/files/good-1-v0-trailing-1.lz | Bin 0 -> 59 bytes .../xz-5.8.3/tests/files/good-1-v0.lz | Bin 0 -> 42 bytes .../tests/files/good-1-v1-trailing-1.lz | Bin 0 -> 67 bytes .../tests/files/good-1-v1-trailing-2.lz | Bin 0 -> 70 bytes .../xz-5.8.3/tests/files/good-1-v1.lz | Bin 0 -> 50 bytes .../xz-5.8.3/tests/files/good-2-lzma2.xz | Bin 0 -> 92 bytes .../xz-5.8.3/tests/files/good-2-v0-v1.lz | Bin 0 -> 78 bytes .../xz-5.8.3/tests/files/good-2-v1-v0.lz | Bin 0 -> 78 bytes .../xz-5.8.3/tests/files/good-2-v1-v1.lz | Bin 0 -> 86 bytes .../files/good-known_size-with_eopm.lzma | Bin 0 -> 37 bytes .../files/good-known_size-without_eopm.lzma | Bin 0 -> 31 bytes .../files/good-unknown_size-with_eopm.lzma | Bin 0 -> 37 bytes .../tests/files/unsupported-1-v234.lz | Bin 0 -> 50 bytes .../tests/files/unsupported-block_header.xz | Bin 0 -> 68 bytes .../xz-5.8.3/tests/files/unsupported-check.xz | Bin 0 -> 68 bytes .../tests/files/unsupported-filter_flags-1.xz | Bin 0 -> 68 bytes .../tests/files/unsupported-filter_flags-2.xz | Bin 0 -> 68 bytes .../tests/files/unsupported-filter_flags-3.xz | Bin 0 -> 68 bytes .../xz-5.8.3/tests/ossfuzz/Makefile | 17 + .../ossfuzz/config/fuzz_decode_alone.options | 5 + .../ossfuzz/config/fuzz_decode_stream.options | 4 + .../config/fuzz_decode_stream_mt.options | 4 + .../ossfuzz/config/fuzz_encode_stream.options | 4 + .../tests/ossfuzz/config/fuzz_lzma.dict | 22 + .../tests/ossfuzz/config/fuzz_xz.dict | 4 + .../xz-5.8.3/tests/ossfuzz/fuzz_common.h | 72 + .../tests/ossfuzz/fuzz_decode_alone.c | 41 + .../tests/ossfuzz/fuzz_decode_stream.c | 53 + .../tests/ossfuzz/fuzz_decode_stream_mt.c | 47 + .../tests/ossfuzz/fuzz_encode_stream.c | 86 + .../xz-5.8.3/tests/test_bcj_exact_size.c | 123 + .../xz-5.8.3/tests/test_block_header.c | 519 + cpp/third_party/xz-5.8.3/tests/test_check.c | 398 + .../xz-5.8.3/tests/test_compress.sh | 166 + .../tests/test_compress_generated_abc | 4 + .../tests/test_compress_generated_random | 4 + .../tests/test_compress_generated_text | 4 + cpp/third_party/xz-5.8.3/tests/test_files.sh | 208 + .../xz-5.8.3/tests/test_filter_flags.c | 535 + .../xz-5.8.3/tests/test_filter_str.c | 685 + .../xz-5.8.3/tests/test_hardware.c | 49 + cpp/third_party/xz-5.8.3/tests/test_index.c | 1826 ++ .../xz-5.8.3/tests/test_index_hash.c | 385 + .../xz-5.8.3/tests/test_lzip_decoder.c | 475 + .../xz-5.8.3/tests/test_memlimit.c | 172 + .../xz-5.8.3/tests/test_microlzma.c | 568 + .../xz-5.8.3/tests/test_scripts.sh | 82 + .../xz-5.8.3/tests/test_stream_flags.c | 478 + cpp/third_party/xz-5.8.3/tests/test_suffix.sh | 192 + cpp/third_party/xz-5.8.3/tests/test_vli.c | 323 + cpp/third_party/xz-5.8.3/tests/tests.cmake | 228 + cpp/third_party/xz-5.8.3/tests/tests.h | 74 + .../xz-5.8.3/tests/tests_w32res.rc | 18 + cpp/third_party/xz-5.8.3/tests/tuktest.h | 1053 + .../xz-5.8.3/tests/xzgrep_expected_output | 39 + .../xz-5.8.3/windows/INSTALL-MSVC.txt | 44 + .../INSTALL-MinGW-w64_with_Autotools.txt | 49 + .../windows/INSTALL-MinGW-w64_with_CMake.txt | 211 + .../xz-5.8.3/windows/README-Windows.txt | 100 + .../xz-5.8.3/windows/build-with-cmake.bat | 35 + cpp/third_party/xz-5.8.3/windows/build.bash | 245 + .../xz-5.8.3/windows/liblzma-crt-mixing.txt | 70 + cpp/third_party/zstd-1.5.7/.buckconfig | 9 + cpp/third_party/zstd-1.5.7/.buckversion | 1 + cpp/third_party/zstd-1.5.7/.cirrus.yml | 9 + cpp/third_party/zstd-1.5.7/.gitattributes | 21 + .../.github/ISSUE_TEMPLATE/bug_report.md | 35 + .../.github/ISSUE_TEMPLATE/feature_request.md | 20 + .../zstd-1.5.7/.github/dependabot.yml | 6 + .../.github/workflows/android-ndk-build.yml | 39 + .../zstd-1.5.7/.github/workflows/commit.yml | 104 + .../.github/workflows/dev-long-tests.yml | 313 + .../.github/workflows/dev-short-tests.yml | 725 + .../zstd-1.5.7/.github/workflows/nightly.yml | 38 + .../workflows/publish-release-artifacts.yml | 73 + .../.github/workflows/scorecards.yml | 64 + .../.github/workflows/windows-artifacts.yml | 58 + cpp/third_party/zstd-1.5.7/.gitignore | 63 + cpp/third_party/zstd-1.5.7/CHANGELOG | 863 + cpp/third_party/zstd-1.5.7/CODE_OF_CONDUCT.md | 5 + cpp/third_party/zstd-1.5.7/CONTRIBUTING.md | 489 + cpp/third_party/zstd-1.5.7/COPYING | 339 + cpp/third_party/zstd-1.5.7/LICENSE | 30 + cpp/third_party/zstd-1.5.7/Makefile | 471 + cpp/third_party/zstd-1.5.7/Package.swift | 36 + cpp/third_party/zstd-1.5.7/README.md | 237 + cpp/third_party/zstd-1.5.7/SECURITY.md | 15 + cpp/third_party/zstd-1.5.7/TESTING.md | 43 + .../zstd-1.5.7/contrib/VS2005/README.md | 3 + .../contrib/VS2005/fullbench/fullbench.vcproj | 440 + .../contrib/VS2005/fuzzer/fuzzer.vcproj | 488 + .../zstd-1.5.7/contrib/VS2005/zstd.sln | 55 + .../contrib/VS2005/zstd/zstd.vcproj | 552 + .../contrib/VS2005/zstdlib/zstdlib.vcproj | 546 + cpp/third_party/zstd-1.5.7/contrib/cleanTabs | 2 + .../contrib/diagnose_corruption/.gitignore | 1 + .../contrib/diagnose_corruption/Makefile | 35 + .../diagnose_corruption/check_flipped_bits.c | 400 + .../zstd-1.5.7/contrib/docker/Dockerfile | 20 + .../zstd-1.5.7/contrib/docker/README.md | 20 + .../externalSequenceProducer/.gitignore | 2 + .../contrib/externalSequenceProducer/Makefile | 40 + .../externalSequenceProducer/README.md | 14 + .../contrib/externalSequenceProducer/main.c | 107 + .../sequence_producer.c | 80 + .../sequence_producer.h | 26 + .../contrib/freestanding_lib/freestanding.py | 774 + .../zstd-1.5.7/contrib/gen_html/.gitignore | 3 + .../zstd-1.5.7/contrib/gen_html/Makefile | 51 + .../zstd-1.5.7/contrib/gen_html/README.md | 31 + .../contrib/gen_html/gen-zstd-manual.sh | 9 + .../zstd-1.5.7/contrib/gen_html/gen_html.cpp | 225 + .../contrib/largeNbDicts/.gitignore | 2 + .../zstd-1.5.7/contrib/largeNbDicts/Makefile | 58 + .../zstd-1.5.7/contrib/largeNbDicts/README.md | 33 + .../contrib/largeNbDicts/largeNbDicts.c | 1085 + .../contrib/linux-kernel/.gitignore | 4 + .../zstd-1.5.7/contrib/linux-kernel/Makefile | 108 + .../zstd-1.5.7/contrib/linux-kernel/README.md | 14 + .../contrib/linux-kernel/btrfs-benchmark.sh | 104 + .../linux-kernel/btrfs-extract-benchmark.sh | 99 + .../contrib/linux-kernel/decompress_sources.h | 34 + .../zstd-1.5.7/contrib/linux-kernel/linux.mk | 44 + .../contrib/linux-kernel/linux_zstd.h | 525 + .../zstd-1.5.7/contrib/linux-kernel/mem.h | 262 + .../linux-kernel/squashfs-benchmark.sh | 39 + .../contrib/linux-kernel/test/Makefile | 49 + .../test/include/linux/compiler.h | 23 + .../linux-kernel/test/include/linux/errno.h | 15 + .../linux-kernel/test/include/linux/kernel.h | 19 + .../linux-kernel/test/include/linux/limits.h | 15 + .../linux-kernel/test/include/linux/math64.h | 15 + .../linux-kernel/test/include/linux/module.h | 20 + .../linux-kernel/test/include/linux/printk.h | 15 + .../linux-kernel/test/include/linux/stddef.h | 15 + .../linux-kernel/test/include/linux/swab.h | 16 + .../linux-kernel/test/include/linux/types.h | 16 + .../test/include/linux/unaligned.h | 187 + .../linux-kernel/test/include/linux/xxhash.h | 745 + .../contrib/linux-kernel/test/macro-test.sh | 44 + .../contrib/linux-kernel/test/static_test.c | 52 + .../contrib/linux-kernel/test/test.c | 229 + .../contrib/linux-kernel/zstd_common_module.c | 29 + .../linux-kernel/zstd_compress_module.c | 237 + .../linux-kernel/zstd_decompress_module.c | 105 + .../contrib/linux-kernel/zstd_deps.h | 121 + .../contrib/match_finders/README.md | 42 + .../contrib/match_finders/zstd_edist.c | 558 + .../contrib/match_finders/zstd_edist.h | 70 + .../zstd-1.5.7/contrib/premake/premake4.lua | 6 + .../zstd-1.5.7/contrib/premake/zstd.lua | 80 + .../zstd-1.5.7/contrib/pzstd/.gitignore | 2 + cpp/third_party/zstd-1.5.7/contrib/pzstd/BUCK | 72 + .../zstd-1.5.7/contrib/pzstd/ErrorHolder.h | 54 + .../zstd-1.5.7/contrib/pzstd/Logging.h | 72 + .../zstd-1.5.7/contrib/pzstd/Makefile | 265 + .../zstd-1.5.7/contrib/pzstd/Options.cpp | 424 + .../zstd-1.5.7/contrib/pzstd/Options.h | 71 + .../zstd-1.5.7/contrib/pzstd/Pzstd.cpp | 626 + .../zstd-1.5.7/contrib/pzstd/Pzstd.h | 153 + .../zstd-1.5.7/contrib/pzstd/README.md | 56 + .../contrib/pzstd/SkippableFrame.cpp | 30 + .../zstd-1.5.7/contrib/pzstd/SkippableFrame.h | 64 + .../contrib/pzstd/images/Cspeed.png | Bin 0 -> 69804 bytes .../contrib/pzstd/images/Dspeed.png | Bin 0 -> 26335 bytes .../zstd-1.5.7/contrib/pzstd/main.cpp | 27 + .../zstd-1.5.7/contrib/pzstd/test/BUCK | 37 + .../contrib/pzstd/test/OptionsTest.cpp | 536 + .../contrib/pzstd/test/PzstdTest.cpp | 147 + .../zstd-1.5.7/contrib/pzstd/test/RoundTrip.h | 86 + .../contrib/pzstd/test/RoundTripTest.cpp | 84 + .../zstd-1.5.7/contrib/pzstd/utils/BUCK | 75 + .../zstd-1.5.7/contrib/pzstd/utils/Buffer.h | 99 + .../contrib/pzstd/utils/FileSystem.h | 96 + .../zstd-1.5.7/contrib/pzstd/utils/Likely.h | 28 + .../contrib/pzstd/utils/Portability.h | 16 + .../zstd-1.5.7/contrib/pzstd/utils/Range.h | 133 + .../contrib/pzstd/utils/ResourcePool.h | 96 + .../contrib/pzstd/utils/ScopeGuard.h | 50 + .../contrib/pzstd/utils/ThreadPool.h | 58 + .../contrib/pzstd/utils/WorkQueue.h | 182 + .../zstd-1.5.7/contrib/pzstd/utils/test/BUCK | 35 + .../contrib/pzstd/utils/test/BufferTest.cpp | 89 + .../contrib/pzstd/utils/test/RangeTest.cpp | 82 + .../pzstd/utils/test/ResourcePoolTest.cpp | 72 + .../pzstd/utils/test/ScopeGuardTest.cpp | 28 + .../pzstd/utils/test/ThreadPoolTest.cpp | 71 + .../pzstd/utils/test/WorkQueueTest.cpp | 282 + .../zstd-1.5.7/contrib/recovery/Makefile | 35 + .../contrib/recovery/recover_directory.c | 152 + .../contrib/seekable_format/README.md | 42 + .../seekable_format/examples/.gitignore | 5 + .../contrib/seekable_format/examples/Makefile | 53 + .../examples/parallel_compression.c | 214 + .../examples/parallel_processing.c | 194 + .../examples/seekable_compression.c | 136 + .../examples/seekable_decompression.c | 141 + .../examples/seekable_decompression_mem.c | 147 + .../contrib/seekable_format/tests/.gitignore | 1 + .../contrib/seekable_format/tests/Makefile | 38 + .../seekable_format/tests/seekable_tests.c | 363 + .../contrib/seekable_format/zstd_seekable.h | 226 + .../zstd_seekable_compression_format.md | 116 + .../seekable_format/zstdseek_compress.c | 365 + .../seekable_format/zstdseek_decompress.c | 600 + .../zstd-1.5.7/contrib/seqBench/Makefile | 58 + .../zstd-1.5.7/contrib/seqBench/seqBench.c | 53 + .../zstd-1.5.7/contrib/snap/snapcraft.yaml | 28 + cpp/third_party/zstd-1.5.7/doc/README.md | 26 + .../zstd-1.5.7/doc/decompressor_errata.md | 148 + .../zstd-1.5.7/doc/decompressor_permissive.md | 80 + .../doc/educational_decoder/.gitignore | 2 + .../doc/educational_decoder/Makefile | 62 + .../doc/educational_decoder/README.md | 36 + .../doc/educational_decoder/harness.c | 119 + .../doc/educational_decoder/zstd_decompress.c | 2323 ++ .../doc/educational_decoder/zstd_decompress.h | 61 + .../zstd-1.5.7/doc/images/CSpeed2.png | Bin 0 -> 73335 bytes .../zstd-1.5.7/doc/images/DCspeed5.png | Bin 0 -> 69278 bytes .../zstd-1.5.7/doc/images/DSpeed3.png | Bin 0 -> 27123 bytes .../zstd-1.5.7/doc/images/cdict_v136.png | Bin 0 -> 33330 bytes .../zstd-1.5.7/doc/images/dict-cr.png | Bin 0 -> 90412 bytes .../zstd-1.5.7/doc/images/dict-cs.png | Bin 0 -> 91518 bytes .../zstd-1.5.7/doc/images/dict-ds.png | Bin 0 -> 98316 bytes .../doc/images/zstd_cdict_v1_3_5.png | Bin 0 -> 93969 bytes .../zstd-1.5.7/doc/images/zstd_logo86.png | Bin 0 -> 13069 bytes .../zstd-1.5.7/doc/zstd_compression_format.md | 1771 + .../zstd-1.5.7/doc/zstd_manual.html | 2237 ++ .../zstd-1.5.7/examples/.gitignore | 15 + cpp/third_party/zstd-1.5.7/examples/Makefile | 93 + cpp/third_party/zstd-1.5.7/examples/README.md | 46 + cpp/third_party/zstd-1.5.7/examples/common.h | 246 + .../examples/dictionary_compression.c | 107 + .../examples/dictionary_decompression.c | 99 + .../examples/multiple_simple_compression.c | 116 + .../examples/multiple_streaming_compression.c | 133 + .../zstd-1.5.7/examples/simple_compression.c | 68 + .../examples/simple_decompression.c | 65 + .../examples/streaming_compression.c | 146 + .../streaming_compression_thread_pool.c | 180 + .../examples/streaming_decompression.c | 100 + .../examples/streaming_memory_usage.c | 137 + cpp/third_party/zstd-1.5.7/lib/.gitignore | 3 + cpp/third_party/zstd-1.5.7/lib/BUCK | 232 + cpp/third_party/zstd-1.5.7/lib/Makefile | 389 + cpp/third_party/zstd-1.5.7/lib/README.md | 248 + .../zstd-1.5.7/lib/common/allocations.h | 55 + cpp/third_party/zstd-1.5.7/lib/common/bits.h | 205 + .../zstd-1.5.7/lib/common/bitstream.h | 454 + .../zstd-1.5.7/lib/common/compiler.h | 464 + cpp/third_party/zstd-1.5.7/lib/common/cpu.h | 249 + cpp/third_party/zstd-1.5.7/lib/common/debug.c | 30 + cpp/third_party/zstd-1.5.7/lib/common/debug.h | 107 + .../zstd-1.5.7/lib/common/entropy_common.c | 340 + .../zstd-1.5.7/lib/common/error_private.c | 64 + .../zstd-1.5.7/lib/common/error_private.h | 158 + cpp/third_party/zstd-1.5.7/lib/common/fse.h | 625 + .../zstd-1.5.7/lib/common/fse_decompress.c | 315 + cpp/third_party/zstd-1.5.7/lib/common/huf.h | 277 + cpp/third_party/zstd-1.5.7/lib/common/mem.h | 422 + cpp/third_party/zstd-1.5.7/lib/common/pool.c | 371 + cpp/third_party/zstd-1.5.7/lib/common/pool.h | 81 + .../lib/common/portability_macros.h | 171 + .../zstd-1.5.7/lib/common/threading.c | 182 + .../zstd-1.5.7/lib/common/threading.h | 142 + .../zstd-1.5.7/lib/common/xxhash.c | 18 + .../zstd-1.5.7/lib/common/xxhash.h | 7094 ++++ .../zstd-1.5.7/lib/common/zstd_common.c | 48 + .../zstd-1.5.7/lib/common/zstd_deps.h | 123 + .../zstd-1.5.7/lib/common/zstd_internal.h | 324 + .../zstd-1.5.7/lib/common/zstd_trace.h | 156 + .../zstd-1.5.7/lib/compress/clevels.h | 134 + .../zstd-1.5.7/lib/compress/fse_compress.c | 625 + .../zstd-1.5.7/lib/compress/hist.c | 191 + .../zstd-1.5.7/lib/compress/hist.h | 82 + .../zstd-1.5.7/lib/compress/huf_compress.c | 1464 + .../zstd-1.5.7/lib/compress/zstd_compress.c | 7843 +++++ .../lib/compress/zstd_compress_internal.h | 1636 + .../lib/compress/zstd_compress_literals.c | 235 + .../lib/compress/zstd_compress_literals.h | 39 + .../lib/compress/zstd_compress_sequences.c | 442 + .../lib/compress/zstd_compress_sequences.h | 55 + .../lib/compress/zstd_compress_superblock.c | 688 + .../lib/compress/zstd_compress_superblock.h | 32 + .../zstd-1.5.7/lib/compress/zstd_cwksp.h | 765 + .../lib/compress/zstd_double_fast.c | 778 + .../lib/compress/zstd_double_fast.h | 42 + .../zstd-1.5.7/lib/compress/zstd_fast.c | 985 + .../zstd-1.5.7/lib/compress/zstd_fast.h | 30 + .../zstd-1.5.7/lib/compress/zstd_lazy.c | 2199 ++ .../zstd-1.5.7/lib/compress/zstd_lazy.h | 193 + .../zstd-1.5.7/lib/compress/zstd_ldm.c | 745 + .../zstd-1.5.7/lib/compress/zstd_ldm.h | 109 + .../lib/compress/zstd_ldm_geartab.h | 106 + .../zstd-1.5.7/lib/compress/zstd_opt.c | 1580 + .../zstd-1.5.7/lib/compress/zstd_opt.h | 72 + .../zstd-1.5.7/lib/compress/zstd_preSplit.c | 238 + .../zstd-1.5.7/lib/compress/zstd_preSplit.h | 33 + .../zstd-1.5.7/lib/compress/zstdmt_compress.c | 1923 ++ .../zstd-1.5.7/lib/compress/zstdmt_compress.h | 102 + .../lib/decompress/huf_decompress.c | 1944 ++ .../lib/decompress/huf_decompress_amd64.S | 602 + .../zstd-1.5.7/lib/decompress/zstd_ddict.c | 244 + .../zstd-1.5.7/lib/decompress/zstd_ddict.h | 44 + .../lib/decompress/zstd_decompress.c | 2410 ++ .../lib/decompress/zstd_decompress_block.c | 2209 ++ .../lib/decompress/zstd_decompress_block.h | 73 + .../lib/decompress/zstd_decompress_internal.h | 240 + .../zstd-1.5.7/lib/deprecated/zbuff.h | 214 + .../zstd-1.5.7/lib/deprecated/zbuff_common.c | 26 + .../lib/deprecated/zbuff_compress.c | 167 + .../lib/deprecated/zbuff_decompress.c | 77 + .../zstd-1.5.7/lib/dictBuilder/cover.c | 1302 + .../zstd-1.5.7/lib/dictBuilder/cover.h | 152 + .../zstd-1.5.7/lib/dictBuilder/divsufsort.c | 1913 ++ .../zstd-1.5.7/lib/dictBuilder/divsufsort.h | 57 + .../zstd-1.5.7/lib/dictBuilder/fastcover.c | 766 + .../zstd-1.5.7/lib/dictBuilder/zdict.c | 1133 + .../zstd-1.5.7/lib/dll/example/Makefile | 48 + .../zstd-1.5.7/lib/dll/example/README.md | 63 + .../lib/dll/example/build_package.bat | 20 + .../lib/dll/example/fullbench-dll.sln | 25 + .../lib/dll/example/fullbench-dll.vcxproj | 181 + .../zstd-1.5.7/lib/legacy/zstd_legacy.h | 452 + .../zstd-1.5.7/lib/legacy/zstd_v01.c | 2127 ++ .../zstd-1.5.7/lib/legacy/zstd_v01.h | 94 + .../zstd-1.5.7/lib/legacy/zstd_v02.c | 3465 ++ .../zstd-1.5.7/lib/legacy/zstd_v02.h | 93 + .../zstd-1.5.7/lib/legacy/zstd_v03.c | 3105 ++ .../zstd-1.5.7/lib/legacy/zstd_v03.h | 93 + .../zstd-1.5.7/lib/legacy/zstd_v04.c | 3598 ++ .../zstd-1.5.7/lib/legacy/zstd_v04.h | 142 + .../zstd-1.5.7/lib/legacy/zstd_v05.c | 4005 +++ .../zstd-1.5.7/lib/legacy/zstd_v05.h | 162 + .../zstd-1.5.7/lib/legacy/zstd_v06.c | 4110 +++ .../zstd-1.5.7/lib/legacy/zstd_v06.h | 172 + .../zstd-1.5.7/lib/legacy/zstd_v07.c | 4490 +++ .../zstd-1.5.7/lib/legacy/zstd_v07.h | 187 + cpp/third_party/zstd-1.5.7/lib/libzstd.mk | 235 + cpp/third_party/zstd-1.5.7/lib/libzstd.pc.in | 16 + .../zstd-1.5.7/lib/module.modulemap | 35 + cpp/third_party/zstd-1.5.7/lib/zdict.h | 481 + cpp/third_party/zstd-1.5.7/lib/zstd.h | 3198 ++ cpp/third_party/zstd-1.5.7/lib/zstd_errors.h | 107 + .../zstd-1.5.7/programs/.gitignore | 41 + cpp/third_party/zstd-1.5.7/programs/BUCK | 44 + cpp/third_party/zstd-1.5.7/programs/Makefile | 445 + cpp/third_party/zstd-1.5.7/programs/README.md | 344 + cpp/third_party/zstd-1.5.7/programs/benchfn.c | 256 + cpp/third_party/zstd-1.5.7/programs/benchfn.h | 173 + .../zstd-1.5.7/programs/benchzstd.c | 1281 + .../zstd-1.5.7/programs/benchzstd.h | 191 + cpp/third_party/zstd-1.5.7/programs/datagen.c | 186 + cpp/third_party/zstd-1.5.7/programs/datagen.h | 38 + cpp/third_party/zstd-1.5.7/programs/dibio.c | 440 + cpp/third_party/zstd-1.5.7/programs/dibio.h | 39 + cpp/third_party/zstd-1.5.7/programs/fileio.c | 3464 ++ cpp/third_party/zstd-1.5.7/programs/fileio.h | 171 + .../zstd-1.5.7/programs/fileio_asyncio.c | 663 + .../zstd-1.5.7/programs/fileio_asyncio.h | 195 + .../zstd-1.5.7/programs/fileio_common.h | 121 + .../zstd-1.5.7/programs/fileio_types.h | 86 + cpp/third_party/zstd-1.5.7/programs/lorem.c | 285 + cpp/third_party/zstd-1.5.7/programs/lorem.h | 32 + .../zstd-1.5.7/programs/platform.h | 217 + cpp/third_party/zstd-1.5.7/programs/timefn.c | 168 + cpp/third_party/zstd-1.5.7/programs/timefn.h | 59 + cpp/third_party/zstd-1.5.7/programs/util.c | 1643 + cpp/third_party/zstd-1.5.7/programs/util.h | 362 + .../zstd-1.5.7/programs/windres/verrsrc.h | 17 + .../zstd-1.5.7/programs/windres/zstd.rc | 51 + .../zstd-1.5.7/programs/windres/zstd32.res | Bin 0 -> 1044 bytes .../zstd-1.5.7/programs/windres/zstd64.res | Bin 0 -> 1044 bytes cpp/third_party/zstd-1.5.7/programs/zstd.1 | 392 + cpp/third_party/zstd-1.5.7/programs/zstd.1.md | 714 + cpp/third_party/zstd-1.5.7/programs/zstdcli.c | 1658 + .../zstd-1.5.7/programs/zstdcli_trace.c | 172 + .../zstd-1.5.7/programs/zstdcli_trace.h | 24 + cpp/third_party/zstd-1.5.7/programs/zstdgrep | 134 + .../zstd-1.5.7/programs/zstdgrep.1 | 26 + .../zstd-1.5.7/programs/zstdgrep.1.md | 30 + cpp/third_party/zstd-1.5.7/programs/zstdless | 8 + .../zstd-1.5.7/programs/zstdless.1 | 14 + .../zstd-1.5.7/programs/zstdless.1.md | 16 + cpp/third_party/zstd-1.5.7/tests/.gitignore | 72 + .../tests/DEPRECATED-test-zstd-speed.py | 378 + cpp/third_party/zstd-1.5.7/tests/Makefile | 481 + cpp/third_party/zstd-1.5.7/tests/README.md | 184 + .../tests/automated_benchmarking.py | 326 + cpp/third_party/zstd-1.5.7/tests/bigdict.c | 133 + cpp/third_party/zstd-1.5.7/tests/checkTag.c | 65 + .../zstd-1.5.7/tests/check_size.py | 31 + .../zstd-1.5.7/tests/cli-tests/.gitignore | 6 + .../zstd-1.5.7/tests/cli-tests/README.md | 258 + .../zstd-1.5.7/tests/cli-tests/basic/args.sh | 10 + .../tests/cli-tests/basic/args.sh.exit | 1 + .../tests/cli-tests/basic/args.sh.stderr.glob | 28 + .../zstd-1.5.7/tests/cli-tests/basic/help.sh | 10 + .../tests/cli-tests/basic/help.sh.stdout.glob | 34 + .../tests/cli-tests/basic/memlimit.sh | 40 + .../cli-tests/basic/memlimit.sh.stderr.exact | 13 + .../cli-tests/basic/memlimit.sh.stdout.exact | 13 + .../tests/cli-tests/basic/output_dir.sh | 7 + .../basic/output_dir.sh.stderr.exact | 2 + .../basic/output_dir.sh.stdout.exact | 2 + .../tests/cli-tests/basic/version.sh | 6 + .../cli-tests/basic/version.sh.stdout.glob | 2 + .../zstd-1.5.7/tests/cli-tests/bin/cmp_size | 44 + .../zstd-1.5.7/tests/cli-tests/bin/datagen | 3 + .../zstd-1.5.7/tests/cli-tests/bin/die | 4 + .../zstd-1.5.7/tests/cli-tests/bin/println | 2 + .../zstd-1.5.7/tests/cli-tests/bin/unzstd | 1 + .../zstd-1.5.7/tests/cli-tests/bin/zstd | 9 + .../zstd-1.5.7/tests/cli-tests/bin/zstdcat | 1 + .../zstd-1.5.7/tests/cli-tests/bin/zstdgrep | 2 + .../zstd-1.5.7/tests/cli-tests/bin/zstdless | 2 + .../zstd-1.5.7/tests/cli-tests/cltools/setup | 6 + .../tests/cli-tests/cltools/zstdgrep.sh | 8 + .../tests/cli-tests/cltools/zstdgrep.sh.exit | 1 + .../cltools/zstdgrep.sh.stderr.exact | 1 + .../cli-tests/cltools/zstdgrep.sh.stdout.glob | 4 + .../tests/cli-tests/cltools/zstdless.sh | 10 + .../cltools/zstdless.sh.stderr.exact | 2 + .../cli-tests/cltools/zstdless.sh.stdout.glob | 5 + .../tests/cli-tests/common/format.sh | 19 + .../tests/cli-tests/common/mtime.sh | 13 + .../tests/cli-tests/common/permissions.sh | 18 + .../tests/cli-tests/common/platform.sh | 36 + .../tests/cli-tests/compression/adapt.sh | 14 + .../tests/cli-tests/compression/basic.sh | 36 + .../compression/compress-literals.sh | 10 + .../tests/cli-tests/compression/format.sh | 16 + .../tests/cli-tests/compression/golden.sh | 16 + .../cli-tests/compression/gzip-compat.sh | 17 + .../tests/cli-tests/compression/levels.sh | 75 + .../compression/levels.sh.stderr.exact | 80 + .../compression/long-distance-matcher.sh | 7 + .../cli-tests/compression/multi-threaded.sh | 15 + .../multi-threaded.sh.stderr.exact | 11 + .../cli-tests/compression/multiple-files.sh | 21 + .../multiple-files.sh.stdout.exact | 12 + .../cli-tests/compression/row-match-finder.sh | 7 + .../tests/cli-tests/compression/setup | 7 + .../cli-tests/compression/stream-size.sh | 7 + .../cli-tests/compression/verbose-wlog.sh | 11 + .../compression/verbose-wlog.sh.stderr.glob | 5 + .../compression/verbose-wlog.sh.stdout.glob | 5 + .../cli-tests/compression/window-resize.sh | 9 + .../window-resize.sh.stderr.ignore | 0 .../compression/window-resize.sh.stdout.glob | 3 + .../cli-tests/decompression/detectErrors.sh | 11 + .../tests/cli-tests/decompression/golden.sh | 7 + .../cli-tests/decompression/pass-through.sh | 57 + .../pass-through.sh.stderr.exact | 11 + .../pass-through.sh.stdout.exact | 25 + .../cli-tests/dict-builder/empty-input.sh | 9 + .../dict-builder/empty-input.sh.stderr.exact | 1 + .../tests/cli-tests/dict-builder/no-inputs.sh | 3 + .../cli-tests/dict-builder/no-inputs.sh.exit | 1 + .../dict-builder/no-inputs.sh.stderr.exact | 5 + .../dictionaries/dictionary-mismatch.sh | 29 + .../dictionary-mismatch.sh.stderr.exact | 7 + .../tests/cli-tests/dictionaries/golden.sh | 9 + .../tests/cli-tests/dictionaries/setup | 6 + .../tests/cli-tests/dictionaries/setup_once | 24 + .../file-handling/directory-mirror.sh | 49 + .../directory-mirror.sh.stderr.exact | 0 .../directory-mirror.sh.stdout.exact | 0 ...compress-file-to-dir-without-write-perm.sh | 12 + ...-to-dir-without-write-perm.sh.stderr.exact | 26 + .../file-stat/compress-file-to-file.sh | 9 + .../compress-file-to-file.sh.stderr.exact | 42 + .../file-stat/compress-file-to-stdout.sh | 8 + .../compress-file-to-stdout.sh.stderr.exact | 24 + .../file-stat/compress-stdin-to-file.sh | 8 + .../compress-stdin-to-file.sh.stderr.exact | 24 + .../file-stat/compress-stdin-to-stdout.sh | 8 + .../compress-stdin-to-stdout.sh.stderr.exact | 18 + .../file-stat/decompress-file-to-file.sh | 8 + .../decompress-file-to-file.sh.stderr.exact | 38 + .../file-stat/decompress-file-to-stdout.sh | 7 + .../decompress-file-to-stdout.sh.stderr.exact | 18 + .../file-stat/decompress-stdin-to-file.sh | 7 + .../decompress-stdin-to-file.sh.stderr.exact | 20 + .../file-stat/decompress-stdin-to-stdout.sh | 7 + ...decompress-stdin-to-stdout.sh.stderr.exact | 14 + .../tests/cli-tests/progress/no-progress.sh | 46 + .../progress/no-progress.sh.stderr.glob | 96 + .../tests/cli-tests/progress/progress.sh | 41 + .../progress/progress.sh.stderr.glob | 62 + .../zstd-1.5.7/tests/cli-tests/run.py | 731 + .../tests/cli-tests/zstd-symlinks/setup | 6 + .../tests/cli-tests/zstd-symlinks/zstdcat.sh | 12 + .../zstd-symlinks/zstdcat.sh.stdout.exact | 8 + cpp/third_party/zstd-1.5.7/tests/datagencli.c | 149 + .../zstd-1.5.7/tests/decodecorpus.c | 1998 ++ .../tests/dict-files/zero-weight-dict | Bin 0 -> 153 bytes .../zstd-1.5.7/tests/external_matchfinder.c | 140 + .../zstd-1.5.7/tests/external_matchfinder.h | 39 + cpp/third_party/zstd-1.5.7/tests/fullbench.c | 1209 + .../zstd-1.5.7/tests/fuzz/.gitignore | 31 + .../zstd-1.5.7/tests/fuzz/Makefile | 278 + .../zstd-1.5.7/tests/fuzz/README.md | 161 + .../zstd-1.5.7/tests/fuzz/block_decompress.c | 53 + .../zstd-1.5.7/tests/fuzz/block_round_trip.c | 103 + .../tests/fuzz/decompress_cross_format.c | 130 + .../tests/fuzz/decompress_dstSize_tooSmall.c | 74 + .../tests/fuzz/dictionary_decompress.c | 77 + .../zstd-1.5.7/tests/fuzz/dictionary_loader.c | 106 + .../tests/fuzz/dictionary_round_trip.c | 155 + .../tests/fuzz/dictionary_stream_round_trip.c | 209 + .../zstd-1.5.7/tests/fuzz/fse_read_ncount.c | 100 + cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz.h | 57 + cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz.py | 910 + .../tests/fuzz/fuzz_data_producer.c | 95 + .../tests/fuzz/fuzz_data_producer.h | 66 + .../zstd-1.5.7/tests/fuzz/fuzz_helpers.c | 48 + .../zstd-1.5.7/tests/fuzz/fuzz_helpers.h | 81 + .../tests/fuzz/fuzz_third_party_seq_prod.h | 116 + .../tests/fuzz/generate_sequences.c | 88 + .../zstd-1.5.7/tests/fuzz/huf_decompress.c | 68 + .../zstd-1.5.7/tests/fuzz/huf_round_trip.c | 137 + .../tests/fuzz/raw_dictionary_round_trip.c | 119 + .../zstd-1.5.7/tests/fuzz/regression_driver.c | 90 + .../tests/fuzz/seekable_roundtrip.c | 88 + .../tests/fuzz/seq_prod_fuzz_example/Makefile | 16 + .../fuzz/seq_prod_fuzz_example/README.md | 12 + .../seq_prod_fuzz_example/example_seq_prod.c | 52 + .../tests/fuzz/sequence_compression_api.c | 452 + .../zstd-1.5.7/tests/fuzz/simple_compress.c | 60 + .../zstd-1.5.7/tests/fuzz/simple_decompress.c | 59 + .../zstd-1.5.7/tests/fuzz/simple_round_trip.c | 182 + .../zstd-1.5.7/tests/fuzz/stream_decompress.c | 119 + .../zstd-1.5.7/tests/fuzz/stream_round_trip.c | 218 + .../zstd-1.5.7/tests/fuzz/zstd_frame_info.c | 43 + .../zstd-1.5.7/tests/fuzz/zstd_helpers.c | 208 + .../zstd-1.5.7/tests/fuzz/zstd_helpers.h | 56 + cpp/third_party/zstd-1.5.7/tests/fuzzer.c | 5147 +++ .../PR-3517-block-splitter-corruption-test | 1 + .../zstd-1.5.7/tests/golden-compression/http | 1 + .../huffman-compressed-larger | Bin 0 -> 143 bytes .../large-literal-and-match-lengths | Bin 0 -> 199998 bytes .../golden-decompression-errors/.gitignore | 1 + .../golden-decompression-errors/off0.bin.zst | Bin 0 -> 17 bytes .../truncated_huff_state.zst | Bin 0 -> 19 bytes .../zeroSeq_extraneous.zst | Bin 0 -> 27 bytes .../tests/golden-decompression/block-128k.zst | Bin 0 -> 131081 bytes .../golden-decompression/empty-block.zst | Bin 0 -> 11 bytes .../golden-decompression/rle-first-block.zst | Bin 0 -> 45 bytes .../tests/golden-decompression/zeroSeq_2B.zst | Bin 0 -> 25 bytes .../http-dict-missing-symbols | Bin 0 -> 1000 bytes .../zstd-1.5.7/tests/gzip/Makefile | 45 + .../zstd-1.5.7/tests/gzip/gzip-env.sh | 46 + .../zstd-1.5.7/tests/gzip/helin-segv.sh | 31 + .../zstd-1.5.7/tests/gzip/help-version.sh | 270 + .../zstd-1.5.7/tests/gzip/hufts-segv.gz | Bin 0 -> 425 bytes .../zstd-1.5.7/tests/gzip/hufts.sh | 34 + .../zstd-1.5.7/tests/gzip/init.cfg | 5 + cpp/third_party/zstd-1.5.7/tests/gzip/init.sh | 616 + cpp/third_party/zstd-1.5.7/tests/gzip/keep.sh | 51 + cpp/third_party/zstd-1.5.7/tests/gzip/list.sh | 31 + .../zstd-1.5.7/tests/gzip/memcpy-abuse.sh | 34 + .../zstd-1.5.7/tests/gzip/mixed.sh | 68 + .../tests/gzip/null-suffix-clobber.sh | 35 + .../zstd-1.5.7/tests/gzip/stdin.sh | 31 + .../zstd-1.5.7/tests/gzip/test-driver.sh | 150 + .../zstd-1.5.7/tests/gzip/trailing-nul.sh | 37 + .../zstd-1.5.7/tests/gzip/unpack-invalid.sh | 36 + .../zstd-1.5.7/tests/gzip/z-suffix.sh | 30 + .../zstd-1.5.7/tests/gzip/zdiff.sh | 48 + .../zstd-1.5.7/tests/gzip/zgrep-context.sh | 47 + .../zstd-1.5.7/tests/gzip/zgrep-f.sh | 43 + .../zstd-1.5.7/tests/gzip/zgrep-signal.sh | 64 + .../zstd-1.5.7/tests/gzip/znew-k.sh | 40 + .../zstd-1.5.7/tests/invalidDictionaries.c | 61 + .../zstd-1.5.7/tests/largeDictionary.c | 128 + cpp/third_party/zstd-1.5.7/tests/legacy.c | 260 + .../zstd-1.5.7/tests/libzstd_builds.sh | 104 + cpp/third_party/zstd-1.5.7/tests/longmatch.c | 102 + cpp/third_party/zstd-1.5.7/tests/loremOut.c | 50 + cpp/third_party/zstd-1.5.7/tests/loremOut.h | 15 + cpp/third_party/zstd-1.5.7/tests/paramgrill.c | 2965 ++ cpp/third_party/zstd-1.5.7/tests/playTests.sh | 1925 ++ cpp/third_party/zstd-1.5.7/tests/poolTests.c | 271 + .../zstd-1.5.7/tests/rateLimiter.py | 41 + .../zstd-1.5.7/tests/regression/.gitignore | 4 + .../zstd-1.5.7/tests/regression/Makefile | 60 + .../zstd-1.5.7/tests/regression/README.md | 28 + .../zstd-1.5.7/tests/regression/config.c | 404 + .../zstd-1.5.7/tests/regression/config.h | 91 + .../zstd-1.5.7/tests/regression/data.c | 631 + .../zstd-1.5.7/tests/regression/data.h | 121 + .../zstd-1.5.7/tests/regression/levels.h | 59 + .../zstd-1.5.7/tests/regression/method.c | 701 + .../zstd-1.5.7/tests/regression/method.h | 65 + .../zstd-1.5.7/tests/regression/result.c | 30 + .../zstd-1.5.7/tests/regression/result.h | 103 + .../zstd-1.5.7/tests/regression/results.csv | 1480 + .../zstd-1.5.7/tests/regression/test.c | 362 + .../zstd-1.5.7/tests/roundTripCrash.c | 241 + cpp/third_party/zstd-1.5.7/tests/seqgen.c | 260 + cpp/third_party/zstd-1.5.7/tests/seqgen.h | 58 + .../zstd-1.5.7/tests/test-license.py | 156 + .../zstd-1.5.7/tests/test-variants.sh | 115 + .../zstd-1.5.7/tests/test-zstd-versions.py | 308 + .../zstd-1.5.7/tests/zstreamtest.c | 3467 ++ .../zstd-1.5.7/zlibWrapper/.gitignore | 28 + cpp/third_party/zstd-1.5.7/zlibWrapper/BUCK | 22 + .../zstd-1.5.7/zlibWrapper/Makefile | 120 + .../zstd-1.5.7/zlibWrapper/README.md | 163 + .../zstd-1.5.7/zlibWrapper/examples/example.c | 598 + .../zlibWrapper/examples/example_original.c | 599 + .../zstd-1.5.7/zlibWrapper/examples/fitblk.c | 254 + .../zlibWrapper/examples/fitblk_original.c | 233 + .../zlibWrapper/examples/minigzip.c | 605 + .../zlibWrapper/examples/zwrapbench.c | 1018 + .../zstd-1.5.7/zlibWrapper/gzclose.c | 26 + .../zstd-1.5.7/zlibWrapper/gzcompatibility.h | 68 + .../zstd-1.5.7/zlibWrapper/gzguts.h | 229 + .../zstd-1.5.7/zlibWrapper/gzlib.c | 587 + .../zstd-1.5.7/zlibWrapper/gzread.c | 637 + .../zstd-1.5.7/zlibWrapper/gzwrite.c | 632 + .../zstd-1.5.7/zlibWrapper/zstd_zlibwrapper.c | 1200 + .../zstd-1.5.7/zlibWrapper/zstd_zlibwrapper.h | 91 + cpp/tools/format/output_format.cc | 10 + python/tsfile/constants.py | 1 + python/tsfile/tsfile_cpp.pxd | 6 + python/tsfile/tsfile_py_cpp.pyx | 6 + 1248 files changed, 455242 insertions(+), 35 deletions(-) create mode 100644 cpp/src/compress/lzma2_compressor.cc create mode 100644 cpp/src/compress/lzma2_compressor.h create mode 100644 cpp/src/compress/zstd_compressor.cc create mode 100644 cpp/src/compress/zstd_compressor.h create mode 100644 cpp/src/encoding/bit_packing_utils.h create mode 100644 cpp/src/encoding/camel_decoder.h create mode 100644 cpp/src/encoding/camel_encoder.h create mode 100644 cpp/src/encoding/chimp_decoder.h create mode 100644 cpp/src/encoding/chimp_encoder.h create mode 100644 cpp/src/encoding/rlbe_decoder.h create mode 100644 cpp/src/encoding/rlbe_encoder.h create mode 100644 cpp/test/compress/lzma2_compressor_test.cc create mode 100644 cpp/test/compress/zstd_compressor_test.cc create mode 100644 cpp/test/encoding/camel_codec_test.cc create mode 100644 cpp/test/encoding/chimp_codec_test.cc create mode 100644 cpp/test/encoding/rlbe_codec_test.cc create mode 100644 cpp/third_party/xz-5.8.3/ABOUT-NLS create mode 100644 cpp/third_party/xz-5.8.3/AUTHORS create mode 100644 cpp/third_party/xz-5.8.3/CMakeLists.txt create mode 100644 cpp/third_party/xz-5.8.3/COPYING create mode 100644 cpp/third_party/xz-5.8.3/COPYING.0BSD create mode 100644 cpp/third_party/xz-5.8.3/COPYING.GPLv2 create mode 100644 cpp/third_party/xz-5.8.3/COPYING.GPLv3 create mode 100644 cpp/third_party/xz-5.8.3/COPYING.LGPLv2.1 create mode 100644 cpp/third_party/xz-5.8.3/ChangeLog create mode 100644 cpp/third_party/xz-5.8.3/INSTALL create mode 100644 cpp/third_party/xz-5.8.3/INSTALL.generic create mode 100644 cpp/third_party/xz-5.8.3/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/NEWS create mode 100644 cpp/third_party/xz-5.8.3/PACKAGERS create mode 100644 cpp/third_party/xz-5.8.3/README create mode 100644 cpp/third_party/xz-5.8.3/THANKS create mode 100644 cpp/third_party/xz-5.8.3/TODO create mode 100644 cpp/third_party/xz-5.8.3/aclocal.m4 create mode 100755 cpp/third_party/xz-5.8.3/autogen.sh create mode 100755 cpp/third_party/xz-5.8.3/build-aux/compile create mode 100755 cpp/third_party/xz-5.8.3/build-aux/config.guess create mode 100755 cpp/third_party/xz-5.8.3/build-aux/config.rpath create mode 100755 cpp/third_party/xz-5.8.3/build-aux/config.sub create mode 100755 cpp/third_party/xz-5.8.3/build-aux/depcomp create mode 100755 cpp/third_party/xz-5.8.3/build-aux/install-sh create mode 100644 cpp/third_party/xz-5.8.3/build-aux/license-check.sh create mode 100644 cpp/third_party/xz-5.8.3/build-aux/ltmain.sh create mode 100644 cpp/third_party/xz-5.8.3/build-aux/manconv.sh create mode 100755 cpp/third_party/xz-5.8.3/build-aux/missing create mode 100755 cpp/third_party/xz-5.8.3/build-aux/test-driver create mode 100644 cpp/third_party/xz-5.8.3/build-aux/version.sh create mode 100644 cpp/third_party/xz-5.8.3/cmake/remove-ordinals.cmake create mode 100644 cpp/third_party/xz-5.8.3/cmake/tuklib_common.cmake create mode 100644 cpp/third_party/xz-5.8.3/cmake/tuklib_cpucores.cmake create mode 100644 cpp/third_party/xz-5.8.3/cmake/tuklib_integer.cmake create mode 100644 cpp/third_party/xz-5.8.3/cmake/tuklib_large_file_support.cmake create mode 100644 cpp/third_party/xz-5.8.3/cmake/tuklib_mbstr.cmake create mode 100644 cpp/third_party/xz-5.8.3/cmake/tuklib_physmem.cmake create mode 100644 cpp/third_party/xz-5.8.3/cmake/tuklib_progname.cmake create mode 100644 cpp/third_party/xz-5.8.3/config.h.in create mode 100755 cpp/third_party/xz-5.8.3/configure create mode 100644 cpp/third_party/xz-5.8.3/configure.ac create mode 100644 cpp/third_party/xz-5.8.3/debug/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/debug/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/debug/README create mode 100644 cpp/third_party/xz-5.8.3/debug/crc32.c create mode 100644 cpp/third_party/xz-5.8.3/debug/full_flush.c create mode 100644 cpp/third_party/xz-5.8.3/debug/hex2bin.c create mode 100644 cpp/third_party/xz-5.8.3/debug/known_sizes.c create mode 100644 cpp/third_party/xz-5.8.3/debug/memusage.c create mode 100644 cpp/third_party/xz-5.8.3/debug/repeat.c create mode 100644 cpp/third_party/xz-5.8.3/debug/sync_flush.c create mode 100644 cpp/third_party/xz-5.8.3/debug/testfilegen-arm64.c create mode 100644 cpp/third_party/xz-5.8.3/debug/translation.bash create mode 100644 cpp/third_party/xz-5.8.3/doc/examples/00_README.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/examples/01_compress_easy.c create mode 100644 cpp/third_party/xz-5.8.3/doc/examples/02_decompress.c create mode 100644 cpp/third_party/xz-5.8.3/doc/examples/03_compress_custom.c create mode 100644 cpp/third_party/xz-5.8.3/doc/examples/04_compress_easy_mt.c create mode 100644 cpp/third_party/xz-5.8.3/doc/examples/11_file_info.c create mode 100644 cpp/third_party/xz-5.8.3/doc/examples/Makefile create mode 100644 cpp/third_party/xz-5.8.3/doc/faq.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/history.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/lzma-file-format.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/man/txt/lzmainfo.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/man/txt/xz.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/man/txt/xzdec.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/man/txt/xzdiff.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/man/txt/xzgrep.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/man/txt/xzless.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/man/txt/xzmore.txt create mode 100644 cpp/third_party/xz-5.8.3/doc/xz-file-format.txt create mode 100644 cpp/third_party/xz-5.8.3/dos/INSTALL.txt create mode 100644 cpp/third_party/xz-5.8.3/dos/Makefile create mode 100644 cpp/third_party/xz-5.8.3/dos/README.txt create mode 100644 cpp/third_party/xz-5.8.3/dos/config.h create mode 100644 cpp/third_party/xz-5.8.3/doxygen/Doxyfile create mode 100755 cpp/third_party/xz-5.8.3/doxygen/update-doxygen create mode 100755 cpp/third_party/xz-5.8.3/extra/7z2lzma/7z2lzma.bash create mode 100644 cpp/third_party/xz-5.8.3/extra/scanlzma/scanlzma.c create mode 100644 cpp/third_party/xz-5.8.3/lib/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/lib/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt-cdefs.h create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt-core.h create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt-ext.h create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt-pfx-core.h create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt-pfx-ext.h create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt.c create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt.in.h create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt1.c create mode 100644 cpp/third_party/xz-5.8.3/lib/getopt_int.h create mode 100644 cpp/third_party/xz-5.8.3/m4/ax_pthread.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/build-to-host.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/getopt.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/gettext.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/host-cpu-c-abi.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/iconv.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/intlmacosx.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/lib-ld.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/lib-link.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/lib-prefix.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/libtool.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/ltoptions.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/ltsugar.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/ltversion.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/lt~obsolete.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/nls.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/po.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/posix-shell.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/progtest.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/tuklib_common.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/tuklib_cpucores.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/tuklib_integer.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/tuklib_mbstr.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/tuklib_physmem.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/tuklib_progname.m4 create mode 100644 cpp/third_party/xz-5.8.3/m4/visibility.m4 create mode 100644 cpp/third_party/xz-5.8.3/po/LINGUAS create mode 100644 cpp/third_party/xz-5.8.3/po/Makefile.in.in create mode 100644 cpp/third_party/xz-5.8.3/po/Makevars create mode 100644 cpp/third_party/xz-5.8.3/po/POTFILES.in create mode 100644 cpp/third_party/xz-5.8.3/po/Rules-quot create mode 100644 cpp/third_party/xz-5.8.3/po/boldquot.sed create mode 100644 cpp/third_party/xz-5.8.3/po/ca.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/ca.po create mode 100644 cpp/third_party/xz-5.8.3/po/cs.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/cs.po create mode 100644 cpp/third_party/xz-5.8.3/po/da.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/da.po create mode 100644 cpp/third_party/xz-5.8.3/po/de.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/de.po create mode 100644 cpp/third_party/xz-5.8.3/po/en@boldquot.header create mode 100644 cpp/third_party/xz-5.8.3/po/en@quot.header create mode 100644 cpp/third_party/xz-5.8.3/po/eo.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/eo.po create mode 100644 cpp/third_party/xz-5.8.3/po/es.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/es.po create mode 100644 cpp/third_party/xz-5.8.3/po/fi.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/fi.po create mode 100644 cpp/third_party/xz-5.8.3/po/fr.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/fr.po create mode 100644 cpp/third_party/xz-5.8.3/po/hr.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/hr.po create mode 100644 cpp/third_party/xz-5.8.3/po/hu.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/hu.po create mode 100644 cpp/third_party/xz-5.8.3/po/insert-header.sed create mode 100644 cpp/third_party/xz-5.8.3/po/it.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/it.po create mode 100644 cpp/third_party/xz-5.8.3/po/ka.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/ka.po create mode 100644 cpp/third_party/xz-5.8.3/po/ko.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/ko.po create mode 100644 cpp/third_party/xz-5.8.3/po/nl.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/nl.po create mode 100644 cpp/third_party/xz-5.8.3/po/pl.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/pl.po create mode 100644 cpp/third_party/xz-5.8.3/po/pt.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/pt.po create mode 100644 cpp/third_party/xz-5.8.3/po/pt_BR.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/pt_BR.po create mode 100644 cpp/third_party/xz-5.8.3/po/quot.sed create mode 100644 cpp/third_party/xz-5.8.3/po/remove-potcdate.sed create mode 100644 cpp/third_party/xz-5.8.3/po/ro.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/ro.po create mode 100644 cpp/third_party/xz-5.8.3/po/sr.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/sr.po create mode 100644 cpp/third_party/xz-5.8.3/po/stamp-po create mode 100644 cpp/third_party/xz-5.8.3/po/sv.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/sv.po create mode 100644 cpp/third_party/xz-5.8.3/po/tr.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/tr.po create mode 100644 cpp/third_party/xz-5.8.3/po/uk.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/uk.po create mode 100644 cpp/third_party/xz-5.8.3/po/vi.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/vi.po create mode 100644 cpp/third_party/xz-5.8.3/po/xz.pot create mode 100644 cpp/third_party/xz-5.8.3/po/xz.pot-header create mode 100644 cpp/third_party/xz-5.8.3/po/zh_CN.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/zh_CN.po create mode 100644 cpp/third_party/xz-5.8.3/po/zh_TW.gmo create mode 100644 cpp/third_party/xz-5.8.3/po/zh_TW.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/ar.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/de.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/fr.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/it.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/ko.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ar/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ar/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ar/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ar/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ar/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ar/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ar/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/de/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/de/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/de/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/de/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/de/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/de/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/de/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/fr/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/fr/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/fr/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/fr/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/it/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/it/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/it/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/it/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/it/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/it/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/it/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ko/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ko/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ko/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ko/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ko/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ko/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ko/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/pt_BR/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ro/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ro/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ro/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ro/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ro/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ro/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/ro/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sr/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sr/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sr/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sr/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sr/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sr/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sr/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sv/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sv/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sv/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sv/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sv/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sv/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/sv/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/uk/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/uk/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/uk/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/uk/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/uk/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/uk/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/man/uk/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/po4a/po4a.conf create mode 100644 cpp/third_party/xz-5.8.3/po4a/pt_BR.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/ro.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/sr.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/sv.po create mode 100644 cpp/third_party/xz-5.8.3/po4a/uk.po create mode 100755 cpp/third_party/xz-5.8.3/po4a/update-po create mode 100644 cpp/third_party/xz-5.8.3/po4a/xz-man.pot create mode 100644 cpp/third_party/xz-5.8.3/src/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/src/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/src/common/common_w32res.rc create mode 100644 cpp/third_party/xz-5.8.3/src/common/my_landlock.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/mythread.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/sysdefs.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_common.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_config.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_cpucores.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_cpucores.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_exit.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_exit.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_gettext.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_integer.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_mbstr.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_mbstr_fw.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_mbstr_nonprint.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_mbstr_nonprint.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_mbstr_width.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_mbstr_wrap.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_mbstr_wrap.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_open_stdxxx.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_open_stdxxx.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_physmem.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_physmem.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_progname.c create mode 100644 cpp/third_party/xz-5.8.3/src/common/tuklib_progname.h create mode 100644 cpp/third_party/xz-5.8.3/src/common/w32_application.manifest create mode 100644 cpp/third_party/xz-5.8.3/src/common/w32_application.manifest.comments.txt create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/base.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/bcj.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/block.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/check.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/container.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/delta.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/filter.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/hardware.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/index.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/index_hash.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/lzma12.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/stream_flags.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/version.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/api/lzma/vli.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/Makefile.inc create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/check.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/check.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc32_arm64.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc32_fast.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc32_loongarch.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc32_small.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc32_table_be.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc32_table_le.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc32_tablegen.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc32_x86.S create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc64_fast.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc64_small.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc64_table_be.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc64_table_le.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc64_tablegen.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc64_x86.S create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc_clmul_consts_gen.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc_common.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/crc_x86_clmul.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/check/sha256.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/Makefile.inc create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/alone_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/alone_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/alone_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/auto_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_buffer_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_buffer_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_buffer_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_header_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_header_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/block_util.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/common.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/common.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/easy_buffer_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/easy_decoder_memusage.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/easy_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/easy_encoder_memusage.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/easy_preset.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/easy_preset.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/file_info.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_buffer_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_buffer_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_common.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_common.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_flags_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/filter_flags_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/hardware_cputhreads.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/hardware_physmem.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/index.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/index.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/index_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/index_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/index_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/index_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/index_hash.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/lzip_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/lzip_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/memcmplen.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/microlzma_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/microlzma_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/outqueue.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/outqueue.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_buffer_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_buffer_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_decoder_mt.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_encoder_mt.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_flags_common.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_flags_common.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_flags_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/stream_flags_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/string_conversion.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/vli_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/vli_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/common/vli_size.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/delta/Makefile.inc create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/delta/delta_common.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/delta/delta_common.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/delta/delta_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/delta/delta_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/delta/delta_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/delta/delta_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/delta/delta_private.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/liblzma.pc.in create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/liblzma_generic.map create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/liblzma_linux.map create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/liblzma_w32res.rc create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lz/Makefile.inc create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lz/lz_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lz/lz_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lz/lz_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lz/lz_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lz/lz_encoder_hash.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lz/lz_encoder_hash_table.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lz/lz_encoder_mf.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/Makefile.inc create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/fastpos.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/fastpos_table.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/fastpos_tablegen.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma2_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma2_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma2_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma2_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_common.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_encoder_optimum_fast.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_encoder_optimum_normal.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_encoder_presets.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/lzma/lzma_encoder_private.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/rangecoder/Makefile.inc create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/rangecoder/price.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/rangecoder/price_table.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/rangecoder/price_tablegen.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/rangecoder/range_common.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/rangecoder/range_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/rangecoder/range_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/Makefile.inc create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/arm.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/arm64.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/armthumb.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/ia64.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/powerpc.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/riscv.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/simple_coder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/simple_coder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/simple_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/simple_decoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/simple_encoder.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/simple_encoder.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/simple_private.h create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/sparc.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/simple/x86.c create mode 100644 cpp/third_party/xz-5.8.3/src/liblzma/validate_map.sh create mode 100644 cpp/third_party/xz-5.8.3/src/lzmainfo/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/src/lzmainfo/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/src/lzmainfo/lzmainfo.1 create mode 100644 cpp/third_party/xz-5.8.3/src/lzmainfo/lzmainfo.c create mode 100644 cpp/third_party/xz-5.8.3/src/lzmainfo/lzmainfo_w32res.rc create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/xzdiff.1 create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/xzdiff.in create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/xzgrep.1 create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/xzgrep.in create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/xzless.1 create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/xzless.in create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/xzmore.1 create mode 100644 cpp/third_party/xz-5.8.3/src/scripts/xzmore.in create mode 100644 cpp/third_party/xz-5.8.3/src/xz/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/src/xz/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/src/xz/args.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/args.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/coder.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/coder.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/file_io.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/file_io.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/hardware.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/hardware.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/list.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/list.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/main.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/main.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/message.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/message.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/mytime.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/mytime.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/options.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/options.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/private.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/sandbox.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/sandbox.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/signals.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/signals.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/suffix.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/suffix.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/util.c create mode 100644 cpp/third_party/xz-5.8.3/src/xz/util.h create mode 100644 cpp/third_party/xz-5.8.3/src/xz/xz.1 create mode 100644 cpp/third_party/xz-5.8.3/src/xz/xz_w32res.rc create mode 100644 cpp/third_party/xz-5.8.3/src/xzdec/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/src/xzdec/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/src/xzdec/lzmadec_w32res.rc create mode 100644 cpp/third_party/xz-5.8.3/src/xzdec/xzdec.1 create mode 100644 cpp/third_party/xz-5.8.3/src/xzdec/xzdec.c create mode 100644 cpp/third_party/xz-5.8.3/src/xzdec/xzdec_w32res.rc create mode 100644 cpp/third_party/xz-5.8.3/tests/Makefile.am create mode 100644 cpp/third_party/xz-5.8.3/tests/Makefile.in create mode 100644 cpp/third_party/xz-5.8.3/tests/create_compress_files.c create mode 100644 cpp/third_party/xz-5.8.3/tests/files/README create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0-backward_size.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0-empty-truncated.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0-footer_magic.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0-header_magic.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0-nonempty_index.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0cat-alone.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0cat-header_magic.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0catpad-empty.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-0pad-empty.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-3.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-4.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-5.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-6.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-check-crc32-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-check-crc32.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-check-crc64.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-check-sha256.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-10.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-11.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-3.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-4.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-5.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-6.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-7.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-8.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-9.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-stream_flags-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-stream_flags-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-stream_flags-3.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v0-uncomp-size.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-crc32.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-dict-1.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-dict-2.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-magic-1.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-magic-2.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-member-size.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-trailing-magic.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-uncomp-size.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-vli-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-1-vli-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-2-compressed_data_padding.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-2-index-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-2-index-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-2-index-3.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-2-index-4.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-2-index-5.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-3-index-uncomp-overflow.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-too_big_size-with_eopm.lzma create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-too_small_size-without_eopm-1.lzma create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-too_small_size-without_eopm-2.lzma create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-too_small_size-without_eopm-3.lzma create mode 100644 cpp/third_party/xz-5.8.3/tests/files/bad-unknown_size-without_eopm.lzma create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-0-empty.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-0cat-empty.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-0catpad-empty.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-0pad-empty.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-3delta-lzma2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-arm64-lzma2-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-arm64-lzma2-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-3.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-check-crc32.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-check-crc64.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-check-none.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-check-sha256.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-delta-lzma2.tiff.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-empty-bcj-lzma2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-3.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-4.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-5.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-v0-trailing-1.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-v0.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-v1-trailing-1.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-v1-trailing-2.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-1-v1.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-2-lzma2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-2-v0-v1.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-2-v1-v0.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-2-v1-v1.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-known_size-with_eopm.lzma create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-known_size-without_eopm.lzma create mode 100644 cpp/third_party/xz-5.8.3/tests/files/good-unknown_size-with_eopm.lzma create mode 100644 cpp/third_party/xz-5.8.3/tests/files/unsupported-1-v234.lz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/unsupported-block_header.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/unsupported-check.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-1.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-2.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-3.xz create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/Makefile create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_alone.options create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_stream.options create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_stream_mt.options create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_encode_stream.options create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_lzma.dict create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_xz.dict create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_common.h create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_alone.c create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_stream.c create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_stream_mt.c create mode 100644 cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_encode_stream.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_bcj_exact_size.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_block_header.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_check.c create mode 100755 cpp/third_party/xz-5.8.3/tests/test_compress.sh create mode 100755 cpp/third_party/xz-5.8.3/tests/test_compress_generated_abc create mode 100755 cpp/third_party/xz-5.8.3/tests/test_compress_generated_random create mode 100755 cpp/third_party/xz-5.8.3/tests/test_compress_generated_text create mode 100755 cpp/third_party/xz-5.8.3/tests/test_files.sh create mode 100644 cpp/third_party/xz-5.8.3/tests/test_filter_flags.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_filter_str.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_hardware.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_index.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_index_hash.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_lzip_decoder.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_memlimit.c create mode 100644 cpp/third_party/xz-5.8.3/tests/test_microlzma.c create mode 100755 cpp/third_party/xz-5.8.3/tests/test_scripts.sh create mode 100644 cpp/third_party/xz-5.8.3/tests/test_stream_flags.c create mode 100755 cpp/third_party/xz-5.8.3/tests/test_suffix.sh create mode 100644 cpp/third_party/xz-5.8.3/tests/test_vli.c create mode 100644 cpp/third_party/xz-5.8.3/tests/tests.cmake create mode 100644 cpp/third_party/xz-5.8.3/tests/tests.h create mode 100644 cpp/third_party/xz-5.8.3/tests/tests_w32res.rc create mode 100644 cpp/third_party/xz-5.8.3/tests/tuktest.h create mode 100644 cpp/third_party/xz-5.8.3/tests/xzgrep_expected_output create mode 100644 cpp/third_party/xz-5.8.3/windows/INSTALL-MSVC.txt create mode 100644 cpp/third_party/xz-5.8.3/windows/INSTALL-MinGW-w64_with_Autotools.txt create mode 100644 cpp/third_party/xz-5.8.3/windows/INSTALL-MinGW-w64_with_CMake.txt create mode 100644 cpp/third_party/xz-5.8.3/windows/README-Windows.txt create mode 100644 cpp/third_party/xz-5.8.3/windows/build-with-cmake.bat create mode 100644 cpp/third_party/xz-5.8.3/windows/build.bash create mode 100644 cpp/third_party/xz-5.8.3/windows/liblzma-crt-mixing.txt create mode 100644 cpp/third_party/zstd-1.5.7/.buckconfig create mode 100644 cpp/third_party/zstd-1.5.7/.buckversion create mode 100644 cpp/third_party/zstd-1.5.7/.cirrus.yml create mode 100644 cpp/third_party/zstd-1.5.7/.gitattributes create mode 100644 cpp/third_party/zstd-1.5.7/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 cpp/third_party/zstd-1.5.7/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 cpp/third_party/zstd-1.5.7/.github/dependabot.yml create mode 100644 cpp/third_party/zstd-1.5.7/.github/workflows/android-ndk-build.yml create mode 100644 cpp/third_party/zstd-1.5.7/.github/workflows/commit.yml create mode 100644 cpp/third_party/zstd-1.5.7/.github/workflows/dev-long-tests.yml create mode 100644 cpp/third_party/zstd-1.5.7/.github/workflows/dev-short-tests.yml create mode 100644 cpp/third_party/zstd-1.5.7/.github/workflows/nightly.yml create mode 100644 cpp/third_party/zstd-1.5.7/.github/workflows/publish-release-artifacts.yml create mode 100644 cpp/third_party/zstd-1.5.7/.github/workflows/scorecards.yml create mode 100644 cpp/third_party/zstd-1.5.7/.github/workflows/windows-artifacts.yml create mode 100644 cpp/third_party/zstd-1.5.7/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/CHANGELOG create mode 100644 cpp/third_party/zstd-1.5.7/CODE_OF_CONDUCT.md create mode 100644 cpp/third_party/zstd-1.5.7/CONTRIBUTING.md create mode 100644 cpp/third_party/zstd-1.5.7/COPYING create mode 100644 cpp/third_party/zstd-1.5.7/LICENSE create mode 100644 cpp/third_party/zstd-1.5.7/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/Package.swift create mode 100644 cpp/third_party/zstd-1.5.7/README.md create mode 100644 cpp/third_party/zstd-1.5.7/SECURITY.md create mode 100644 cpp/third_party/zstd-1.5.7/TESTING.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/VS2005/README.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/VS2005/fullbench/fullbench.vcproj create mode 100644 cpp/third_party/zstd-1.5.7/contrib/VS2005/fuzzer/fuzzer.vcproj create mode 100644 cpp/third_party/zstd-1.5.7/contrib/VS2005/zstd.sln create mode 100644 cpp/third_party/zstd-1.5.7/contrib/VS2005/zstd/zstd.vcproj create mode 100644 cpp/third_party/zstd-1.5.7/contrib/VS2005/zstdlib/zstdlib.vcproj create mode 100755 cpp/third_party/zstd-1.5.7/contrib/cleanTabs create mode 100644 cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/check_flipped_bits.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/docker/Dockerfile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/docker/README.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/README.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/main.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/sequence_producer.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/sequence_producer.h create mode 100755 cpp/third_party/zstd-1.5.7/contrib/freestanding_lib/freestanding.py create mode 100644 cpp/third_party/zstd-1.5.7/contrib/gen_html/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/contrib/gen_html/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/gen_html/README.md create mode 100755 cpp/third_party/zstd-1.5.7/contrib/gen_html/gen-zstd-manual.sh create mode 100644 cpp/third_party/zstd-1.5.7/contrib/gen_html/gen_html.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/README.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/largeNbDicts.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/README.md create mode 100755 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/btrfs-benchmark.sh create mode 100755 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/btrfs-extract-benchmark.sh create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/decompress_sources.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/linux.mk create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/linux_zstd.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/mem.h create mode 100755 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/squashfs-benchmark.sh create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/compiler.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/errno.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/kernel.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/limits.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/math64.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/module.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/printk.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/stddef.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/swab.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/types.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/unaligned.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/xxhash.h create mode 100755 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/macro-test.sh create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/static_test.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/test.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_common_module.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_compress_module.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_decompress_module.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_deps.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/match_finders/README.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/match_finders/zstd_edist.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/match_finders/zstd_edist.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/premake/premake4.lua create mode 100644 cpp/third_party/zstd-1.5.7/contrib/premake/zstd.lua create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/BUCK create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/ErrorHolder.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/Logging.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/Options.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/Options.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/Pzstd.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/Pzstd.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/README.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/SkippableFrame.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/SkippableFrame.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/images/Cspeed.png create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/images/Dspeed.png create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/main.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/test/BUCK create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/test/OptionsTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/test/PzstdTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/test/RoundTrip.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/test/RoundTripTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/BUCK create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Buffer.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/FileSystem.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Likely.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Portability.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Range.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ResourcePool.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ScopeGuard.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ThreadPool.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/WorkQueue.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/BUCK create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/BufferTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/RangeTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ResourcePoolTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ScopeGuardTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ThreadPoolTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/WorkQueueTest.cpp create mode 100644 cpp/third_party/zstd-1.5.7/contrib/recovery/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/recovery/recover_directory.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/README.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/parallel_compression.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/parallel_processing.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_compression.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_decompression.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_decompression_mem.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/seekable_tests.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstd_seekable.h create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstd_seekable_compression_format.md create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstdseek_compress.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstdseek_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seqBench/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/contrib/seqBench/seqBench.c create mode 100644 cpp/third_party/zstd-1.5.7/contrib/snap/snapcraft.yaml create mode 100644 cpp/third_party/zstd-1.5.7/doc/README.md create mode 100644 cpp/third_party/zstd-1.5.7/doc/decompressor_errata.md create mode 100644 cpp/third_party/zstd-1.5.7/doc/decompressor_permissive.md create mode 100644 cpp/third_party/zstd-1.5.7/doc/educational_decoder/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/doc/educational_decoder/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/doc/educational_decoder/README.md create mode 100644 cpp/third_party/zstd-1.5.7/doc/educational_decoder/harness.c create mode 100644 cpp/third_party/zstd-1.5.7/doc/educational_decoder/zstd_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/doc/educational_decoder/zstd_decompress.h create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/CSpeed2.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/DCspeed5.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/DSpeed3.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/cdict_v136.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/dict-cr.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/dict-cs.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/dict-ds.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/zstd_cdict_v1_3_5.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/images/zstd_logo86.png create mode 100644 cpp/third_party/zstd-1.5.7/doc/zstd_compression_format.md create mode 100644 cpp/third_party/zstd-1.5.7/doc/zstd_manual.html create mode 100644 cpp/third_party/zstd-1.5.7/examples/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/examples/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/examples/README.md create mode 100644 cpp/third_party/zstd-1.5.7/examples/common.h create mode 100644 cpp/third_party/zstd-1.5.7/examples/dictionary_compression.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/dictionary_decompression.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/multiple_simple_compression.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/multiple_streaming_compression.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/simple_compression.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/simple_decompression.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/streaming_compression.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/streaming_compression_thread_pool.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/streaming_decompression.c create mode 100644 cpp/third_party/zstd-1.5.7/examples/streaming_memory_usage.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/lib/BUCK create mode 100644 cpp/third_party/zstd-1.5.7/lib/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/lib/README.md create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/allocations.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/bits.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/bitstream.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/compiler.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/cpu.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/debug.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/debug.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/entropy_common.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/error_private.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/error_private.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/fse.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/fse_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/huf.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/mem.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/pool.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/pool.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/portability_macros.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/threading.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/threading.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/xxhash.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/xxhash.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/zstd_common.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/zstd_deps.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/zstd_internal.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/common/zstd_trace.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/clevels.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/fse_compress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/hist.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/hist.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/huf_compress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_internal.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_literals.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_literals.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_sequences.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_sequences.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_superblock.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_superblock.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_cwksp.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_double_fast.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_double_fast.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_fast.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_fast.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_lazy.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_lazy.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm_geartab.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_opt.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_opt.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_preSplit.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstd_preSplit.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstdmt_compress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/compress/zstdmt_compress.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/decompress/huf_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/decompress/huf_decompress_amd64.S create mode 100644 cpp/third_party/zstd-1.5.7/lib/decompress/zstd_ddict.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/decompress/zstd_ddict.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_block.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_block.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_internal.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_common.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_compress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/dictBuilder/cover.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/dictBuilder/cover.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/dictBuilder/divsufsort.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/dictBuilder/divsufsort.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/dictBuilder/fastcover.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/dictBuilder/zdict.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/dll/example/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/lib/dll/example/README.md create mode 100644 cpp/third_party/zstd-1.5.7/lib/dll/example/build_package.bat create mode 100644 cpp/third_party/zstd-1.5.7/lib/dll/example/fullbench-dll.sln create mode 100644 cpp/third_party/zstd-1.5.7/lib/dll/example/fullbench-dll.vcxproj create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_legacy.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v01.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v01.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v02.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v02.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v03.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v03.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v04.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v04.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v05.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v05.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v06.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v06.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v07.c create mode 100644 cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v07.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/libzstd.mk create mode 100644 cpp/third_party/zstd-1.5.7/lib/libzstd.pc.in create mode 100644 cpp/third_party/zstd-1.5.7/lib/module.modulemap create mode 100644 cpp/third_party/zstd-1.5.7/lib/zdict.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/zstd.h create mode 100644 cpp/third_party/zstd-1.5.7/lib/zstd_errors.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/programs/BUCK create mode 100644 cpp/third_party/zstd-1.5.7/programs/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/programs/README.md create mode 100644 cpp/third_party/zstd-1.5.7/programs/benchfn.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/benchfn.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/benchzstd.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/benchzstd.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/datagen.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/datagen.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/dibio.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/dibio.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/fileio.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/fileio.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/fileio_asyncio.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/fileio_asyncio.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/fileio_common.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/fileio_types.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/lorem.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/lorem.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/platform.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/timefn.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/timefn.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/util.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/util.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/windres/verrsrc.h create mode 100644 cpp/third_party/zstd-1.5.7/programs/windres/zstd.rc create mode 100644 cpp/third_party/zstd-1.5.7/programs/windres/zstd32.res create mode 100644 cpp/third_party/zstd-1.5.7/programs/windres/zstd64.res create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstd.1 create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstd.1.md create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstdcli.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstdcli_trace.c create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstdcli_trace.h create mode 100755 cpp/third_party/zstd-1.5.7/programs/zstdgrep create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstdgrep.1 create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstdgrep.1.md create mode 100755 cpp/third_party/zstd-1.5.7/programs/zstdless create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstdless.1 create mode 100644 cpp/third_party/zstd-1.5.7/programs/zstdless.1.md create mode 100644 cpp/third_party/zstd-1.5.7/tests/.gitignore create mode 100755 cpp/third_party/zstd-1.5.7/tests/DEPRECATED-test-zstd-speed.py create mode 100644 cpp/third_party/zstd-1.5.7/tests/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/tests/README.md create mode 100644 cpp/third_party/zstd-1.5.7/tests/automated_benchmarking.py create mode 100644 cpp/third_party/zstd-1.5.7/tests/bigdict.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/checkTag.c create mode 100755 cpp/third_party/zstd-1.5.7/tests/check_size.py create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/README.md create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/args.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/args.sh.exit create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/args.sh.stderr.glob create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/help.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/help.sh.stdout.glob create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/memlimit.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/memlimit.sh.stderr.exact create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/memlimit.sh.stdout.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/output_dir.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/output_dir.sh.stderr.exact create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/output_dir.sh.stdout.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/version.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/basic/version.sh.stdout.glob create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/cmp_size create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/datagen create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/die create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/println create mode 120000 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/unzstd create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/zstd create mode 120000 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/zstdcat create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/zstdgrep create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/bin/zstdless create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/cltools/setup create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/cltools/zstdgrep.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/cltools/zstdgrep.sh.exit create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/cltools/zstdgrep.sh.stderr.exact create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/cltools/zstdgrep.sh.stdout.glob create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/cltools/zstdless.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/cltools/zstdless.sh.stderr.exact create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/cltools/zstdless.sh.stdout.glob create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/common/format.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/common/mtime.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/common/permissions.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/common/platform.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/adapt.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/basic.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/compress-literals.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/format.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/golden.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/gzip-compat.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/levels.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/levels.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/long-distance-matcher.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/multi-threaded.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/multi-threaded.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/multiple-files.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/multiple-files.sh.stdout.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/row-match-finder.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/setup create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/stream-size.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/verbose-wlog.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/verbose-wlog.sh.stderr.glob create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/verbose-wlog.sh.stdout.glob create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/window-resize.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/window-resize.sh.stderr.ignore create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/compression/window-resize.sh.stdout.glob create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/decompression/detectErrors.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/decompression/golden.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/decompression/pass-through.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/decompression/pass-through.sh.stderr.exact create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/decompression/pass-through.sh.stdout.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/dict-builder/empty-input.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/dict-builder/empty-input.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/dict-builder/no-inputs.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/dict-builder/no-inputs.sh.exit create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/dict-builder/no-inputs.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/dictionaries/dictionary-mismatch.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/dictionaries/dictionary-mismatch.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/dictionaries/golden.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/dictionaries/setup create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/dictionaries/setup_once create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-handling/directory-mirror.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-handling/directory-mirror.sh.stderr.exact create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-handling/directory-mirror.sh.stdout.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-file-to-file.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-file-to-stdout.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-file-to-stdout.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-stdin-to-file.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-stdin-to-file.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/decompress-file-to-file.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/decompress-file-to-stdout.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/decompress-file-to-stdout.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/decompress-stdin-to-file.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/decompress-stdin-to-file.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh.stderr.exact create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/progress/no-progress.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/progress/no-progress.sh.stderr.glob create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/progress/progress.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/progress/progress.sh.stderr.glob create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/run.py create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/zstd-symlinks/setup create mode 100755 cpp/third_party/zstd-1.5.7/tests/cli-tests/zstd-symlinks/zstdcat.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/cli-tests/zstd-symlinks/zstdcat.sh.stdout.exact create mode 100644 cpp/third_party/zstd-1.5.7/tests/datagencli.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/decodecorpus.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/dict-files/zero-weight-dict create mode 100644 cpp/third_party/zstd-1.5.7/tests/external_matchfinder.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/external_matchfinder.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/fullbench.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/README.md create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/block_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/block_round_trip.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/decompress_cross_format.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/decompress_dstSize_tooSmall.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/dictionary_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/dictionary_loader.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/dictionary_round_trip.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/dictionary_stream_round_trip.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/fse_read_ncount.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz.h create mode 100755 cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz.py create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz_data_producer.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz_data_producer.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz_helpers.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz_helpers.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/fuzz_third_party_seq_prod.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/generate_sequences.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/huf_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/huf_round_trip.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/raw_dictionary_round_trip.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/regression_driver.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/seekable_roundtrip.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/seq_prod_fuzz_example/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/seq_prod_fuzz_example/README.md create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/seq_prod_fuzz_example/example_seq_prod.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/sequence_compression_api.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/simple_compress.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/simple_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/simple_round_trip.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/stream_decompress.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/stream_round_trip.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/zstd_frame_info.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/zstd_helpers.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzz/zstd_helpers.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/fuzzer.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-compression/PR-3517-block-splitter-corruption-test create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-compression/http create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-compression/huffman-compressed-larger create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-compression/large-literal-and-match-lengths create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-decompression-errors/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-decompression-errors/off0.bin.zst create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-decompression-errors/truncated_huff_state.zst create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-decompression-errors/zeroSeq_extraneous.zst create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-decompression/block-128k.zst create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-decompression/empty-block.zst create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-decompression/rle-first-block.zst create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-decompression/zeroSeq_2B.zst create mode 100644 cpp/third_party/zstd-1.5.7/tests/golden-dictionaries/http-dict-missing-symbols create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/Makefile create mode 100755 cpp/third_party/zstd-1.5.7/tests/gzip/gzip-env.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/helin-segv.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/help-version.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/hufts-segv.gz create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/hufts.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/init.cfg create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/init.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/keep.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/list.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/memcpy-abuse.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/mixed.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/null-suffix-clobber.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/stdin.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/test-driver.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/trailing-nul.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/unpack-invalid.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/z-suffix.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/zdiff.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/zgrep-context.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/zgrep-f.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/zgrep-signal.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/gzip/znew-k.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/invalidDictionaries.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/largeDictionary.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/legacy.c create mode 100755 cpp/third_party/zstd-1.5.7/tests/libzstd_builds.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/longmatch.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/loremOut.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/loremOut.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/paramgrill.c create mode 100755 cpp/third_party/zstd-1.5.7/tests/playTests.sh create mode 100644 cpp/third_party/zstd-1.5.7/tests/poolTests.c create mode 100755 cpp/third_party/zstd-1.5.7/tests/rateLimiter.py create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/README.md create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/config.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/config.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/data.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/data.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/levels.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/method.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/method.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/result.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/result.h create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/results.csv create mode 100644 cpp/third_party/zstd-1.5.7/tests/regression/test.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/roundTripCrash.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/seqgen.c create mode 100644 cpp/third_party/zstd-1.5.7/tests/seqgen.h create mode 100755 cpp/third_party/zstd-1.5.7/tests/test-license.py create mode 100755 cpp/third_party/zstd-1.5.7/tests/test-variants.sh create mode 100755 cpp/third_party/zstd-1.5.7/tests/test-zstd-versions.py create mode 100644 cpp/third_party/zstd-1.5.7/tests/zstreamtest.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/.gitignore create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/BUCK create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/Makefile create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/README.md create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/examples/example.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/examples/example_original.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/examples/fitblk.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/examples/fitblk_original.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/examples/minigzip.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/examples/zwrapbench.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/gzclose.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/gzcompatibility.h create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/gzguts.h create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/gzlib.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/gzread.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/gzwrite.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/zstd_zlibwrapper.c create mode 100644 cpp/third_party/zstd-1.5.7/zlibWrapper/zstd_zlibwrapper.h diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 75cc55a4f..91ea672da 100755 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -247,6 +247,23 @@ if (ENABLE_ZLIB) add_definitions(-DENABLE_GZIP) endif() +option(ENABLE_ZSTD "Enable Zstandard compression" ON) +message("cmake using: ENABLE_ZSTD=${ENABLE_ZSTD}") + +if (ENABLE_ZSTD) + add_definitions(-DENABLE_ZSTD) +endif() + +option(ENABLE_LZMA2 "Enable LZMA2 compression through bundled XZ Utils" ON) +message("cmake using: ENABLE_LZMA2=${ENABLE_LZMA2}") + +if (ENABLE_LZMA2) + if (CMAKE_VERSION VERSION_LESS 3.20) + message(FATAL_ERROR "ENABLE_LZMA2 requires CMake 3.20 or newer because bundled XZ Utils 5.8.3 requires it") + endif() + add_definitions(-DENABLE_LZMA2) +endif() + option(ENABLE_THREADS "Enable multi-threaded read/write (requires pthreads)" ON) message("cmake using: ENABLE_THREADS=${ENABLE_THREADS}") diff --git a/cpp/build.sh b/cpp/build.sh index f51c4eded..d78595929 100644 --- a/cpp/build.sh +++ b/cpp/build.sh @@ -32,6 +32,8 @@ enable_snappy=ON enable_lz4=ON enable_lzokay=ON enable_zlib=ON +enable_zstd=ON +enable_lzma2=ON shell_dir=$(cd "$(dirname "$0")";pwd) @@ -62,6 +64,10 @@ Options: --disable-lzokay --enable-zlib= --disable-zlib + --enable-zstd= + --disable-zstd + --enable-lzma2= + --disable-lzma2 -h, --help Show this help message. EOF } @@ -79,6 +85,8 @@ function print_config() echo "enable_lz4=$enable_lz4" echo "enable_lzokay=$enable_lzokay" echo "enable_zlib=$enable_zlib" + echo "enable_zstd=$enable_zstd" + echo "enable_lzma2=$enable_lzma2" } function run_test_for_cov() @@ -123,6 +131,10 @@ parse_options() enable_lzokay=$(get_key_value "$1");; --enable-zlib=*) enable_zlib=$(get_key_value "$1");; + --enable-zstd=*) + enable_zstd=$(get_key_value "$1");; + --enable-lzma2=*) + enable_lzma2=$(get_key_value "$1");; --disable-antlr4) enable_antlr4=OFF;; --disable-snappy) @@ -133,6 +145,10 @@ parse_options() enable_lzokay=OFF;; --disable-zlib) enable_zlib=OFF;; + --disable-zstd) + enable_zstd=OFF;; + --disable-lzma2) + enable_lzma2=OFF;; -h | --help) usage exit 0;; @@ -199,7 +215,9 @@ cmake ../../ \ -DENABLE_SNAPPY=$enable_snappy \ -DENABLE_LZ4=$enable_lz4 \ -DENABLE_LZOKAY=$enable_lzokay \ - -DENABLE_ZLIB=$enable_zlib + -DENABLE_ZLIB=$enable_zlib \ + -DENABLE_ZSTD=$enable_zstd \ + -DENABLE_LZMA2=$enable_lzma2 VERBOSE=1 make if [ ${do_install} -eq 1 ] diff --git a/cpp/pom.xml b/cpp/pom.xml index 153e75dc2..e82888645 100644 --- a/cpp/pom.xml +++ b/cpp/pom.xml @@ -39,6 +39,8 @@ ON ON ON + ON + ON ON OFF @@ -87,6 +89,8 @@ + + "): + + +=====+ + | Foo | + +=====+ + + +=====+ + ---> | Bar | + +=====+ + + The above is equivalent to this: + + +=====+=====+ + | Foo | Bar | + +=====+=====+ + + +1.2. Multibyte Integers + + Multibyte integers of static length, such as CRC values, + are stored in little endian byte order (least significant + byte first). + + When smaller values are more likely than bigger values (for + example file sizes), multibyte integers are encoded in a + variable-length representation: + - Numbers in the range [0, 127] are copied as is, and take + one byte of space. + - Bigger numbers will occupy two or more bytes. All but the + last byte of the multibyte representation have the highest + (eighth) bit set. + + For now, the value of the variable-length integers is limited + to 63 bits, which limits the encoded size of the integer to + nine bytes. These limits may be increased in the future if + needed. + + The following C code illustrates encoding and decoding of + variable-length integers. The functions return the number of + bytes occupied by the integer (1-9), or zero on error. + + #include + #include + + size_t + encode(uint8_t buf[static 9], uint64_t num) + { + if (num > UINT64_MAX / 2) + return 0; + + size_t i = 0; + + while (num >= 0x80) { + buf[i++] = (uint8_t)(num) | 0x80; + num >>= 7; + } + + buf[i++] = (uint8_t)(num); + + return i; + } + + size_t + decode(const uint8_t buf[], size_t size_max, uint64_t *num) + { + if (size_max == 0) + return 0; + + if (size_max > 9) + size_max = 9; + + *num = buf[0] & 0x7F; + size_t i = 0; + + while (buf[i++] & 0x80) { + if (i >= size_max || buf[i] == 0x00) + return 0; + + *num |= (uint64_t)(buf[i] & 0x7F) << (i * 7); + } + + return i; + } + + +2. Overall Structure of .xz File + + A standalone .xz files consist of one or more Streams which may + have Stream Padding between or after them: + + +========+================+========+================+ + | Stream | Stream Padding | Stream | Stream Padding | ... + +========+================+========+================+ + + The sizes of Stream and Stream Padding are always multiples + of four bytes, thus the size of every valid .xz file MUST be + a multiple of four bytes. + + While a typical file contains only one Stream and no Stream + Padding, a decoder handling standalone .xz files SHOULD support + files that have more than one Stream or Stream Padding. + + In contrast to standalone .xz files, when the .xz file format + is used as an internal part of some other file format or + communication protocol, it usually is expected that the decoder + stops after the first Stream, and doesn't look for Stream + Padding or possibly other Streams. + + +2.1. Stream + + +-+-+-+-+-+-+-+-+-+-+-+-+=======+=======+ +=======+ + | Stream Header | Block | Block | ... | Block | + +-+-+-+-+-+-+-+-+-+-+-+-+=======+=======+ +=======+ + + +=======+-+-+-+-+-+-+-+-+-+-+-+-+ + ---> | Index | Stream Footer | + +=======+-+-+-+-+-+-+-+-+-+-+-+-+ + + All the above fields have a size that is a multiple of four. If + Stream is used as an internal part of another file format, it + is RECOMMENDED to make the Stream start at an offset that is + a multiple of four bytes. + + Stream Header, Index, and Stream Footer are always present in + a Stream. The maximum size of the Index field is 16 GiB (2^34). + + There are zero or more Blocks. The maximum number of Blocks is + limited only by the maximum size of the Index field. + + Total size of a Stream MUST be less than 8 EiB (2^63 bytes). + The same limit applies to the total amount of uncompressed + data stored in a Stream. + + If an implementation supports handling .xz files with multiple + concatenated Streams, it MAY apply the above limits to the file + as a whole instead of limiting per Stream basis. + + +2.1.1. Stream Header + + +---+---+---+---+---+---+-------+------+--+--+--+--+ + | Header Magic Bytes | Stream Flags | CRC32 | + +---+---+---+---+---+---+-------+------+--+--+--+--+ + + +2.1.1.1. Header Magic Bytes + + The first six (6) bytes of the Stream are so called Header + Magic Bytes. They can be used to identify the file type. + + Using a C array and ASCII: + const uint8_t HEADER_MAGIC[6] + = { 0xFD, '7', 'z', 'X', 'Z', 0x00 }; + + In plain hexadecimal: + FD 37 7A 58 5A 00 + + Notes: + - The first byte (0xFD) was chosen so that the files cannot + be erroneously detected as being in .lzma format, in which + the first byte is in the range [0x00, 0xE0]. + - The sixth byte (0x00) was chosen to prevent applications + from misdetecting the file as a text file. + + If the Header Magic Bytes don't match, the decoder MUST + indicate an error. + + +2.1.1.2. Stream Flags + + The first byte of Stream Flags is always a null byte. In the + future, this byte may be used to indicate a new Stream version + or other Stream properties. + + The second byte of Stream Flags is a bit field: + + Bit(s) Mask Description + 0-3 0x0F Type of Check (see Section 3.4): + ID Size Check name + 0x00 0 bytes None + 0x01 4 bytes CRC32 + 0x02 4 bytes (Reserved) + 0x03 4 bytes (Reserved) + 0x04 8 bytes CRC64 + 0x05 8 bytes (Reserved) + 0x06 8 bytes (Reserved) + 0x07 16 bytes (Reserved) + 0x08 16 bytes (Reserved) + 0x09 16 bytes (Reserved) + 0x0A 32 bytes SHA-256 + 0x0B 32 bytes (Reserved) + 0x0C 32 bytes (Reserved) + 0x0D 64 bytes (Reserved) + 0x0E 64 bytes (Reserved) + 0x0F 64 bytes (Reserved) + 4-7 0xF0 Reserved for future use; MUST be zero for now. + + Implementations SHOULD support at least the Check IDs 0x00 + (None) and 0x01 (CRC32). Supporting other Check IDs is + OPTIONAL. If an unsupported Check is used, the decoder SHOULD + indicate a warning or error. + + If any reserved bit is set, the decoder MUST indicate an error. + It is possible that there is a new field present which the + decoder is not aware of, and can thus parse the Stream Header + incorrectly. + + +2.1.1.3. CRC32 + + The CRC32 is calculated from the Stream Flags field. It is + stored as an unsigned 32-bit little endian integer. If the + calculated value does not match the stored one, the decoder + MUST indicate an error. + + The idea is that Stream Flags would always be two bytes, even + if new features are needed. This way old decoders will be able + to verify the CRC32 calculated from Stream Flags, and thus + distinguish between corrupt files (CRC32 doesn't match) and + files that the decoder doesn't support (CRC32 matches but + Stream Flags has reserved bits set). + + +2.1.2. Stream Footer + + +-+-+-+-+---+---+---+---+-------+------+----------+---------+ + | CRC32 | Backward Size | Stream Flags | Footer Magic Bytes | + +-+-+-+-+---+---+---+---+-------+------+----------+---------+ + + +2.1.2.1. CRC32 + + The CRC32 is calculated from the Backward Size and Stream Flags + fields. It is stored as an unsigned 32-bit little endian + integer. If the calculated value does not match the stored one, + the decoder MUST indicate an error. + + The reason to have the CRC32 field before the Backward Size and + Stream Flags fields is to keep the four-byte fields aligned to + a multiple of four bytes. + + +2.1.2.2. Backward Size + + Backward Size is stored as a 32-bit little endian integer, + which indicates the size of the Index field as multiple of + four bytes, minimum value being four bytes: + + real_backward_size = (stored_backward_size + 1) * 4; + + If the stored value does not match the real size of the Index + field, the decoder MUST indicate an error. + + Using a fixed-size integer to store Backward Size makes + it slightly simpler to parse the Stream Footer when the + application needs to parse the Stream backwards. + + +2.1.2.3. Stream Flags + + This is a copy of the Stream Flags field from the Stream + Header. The information stored to Stream Flags is needed + when parsing the Stream backwards. The decoder MUST compare + the Stream Flags fields in both Stream Header and Stream + Footer, and indicate an error if they are not identical. + + +2.1.2.4. Footer Magic Bytes + + As the last step of the decoding process, the decoder MUST + verify the existence of Footer Magic Bytes. If they don't + match, an error MUST be indicated. + + Using a C array and ASCII: + const uint8_t FOOTER_MAGIC[2] = { 'Y', 'Z' }; + + In hexadecimal: + 59 5A + + The primary reason to have Footer Magic Bytes is to make + it easier to detect incomplete files quickly, without + uncompressing. If the file does not end with Footer Magic Bytes + (excluding Stream Padding described in Section 2.2), it cannot + be undamaged, unless someone has intentionally appended garbage + after the end of the Stream. + + +2.2. Stream Padding + + Only the decoders that support decoding of concatenated Streams + MUST support Stream Padding. + + Stream Padding MUST contain only null bytes. To preserve the + four-byte alignment of consecutive Streams, the size of Stream + Padding MUST be a multiple of four bytes. Empty Stream Padding + is allowed. If these requirements are not met, the decoder MUST + indicate an error. + + Note that non-empty Stream Padding is allowed at the end of the + file; there doesn't need to be a new Stream after non-empty + Stream Padding. This can be convenient in certain situations + [GNU-tar]. + + The possibility of Stream Padding MUST be taken into account + when designing an application that parses Streams backwards, + and the application supports concatenated Streams. + + +3. Block + + +==============+=================+===============+=======+ + | Block Header | Compressed Data | Block Padding | Check | + +==============+=================+===============+=======+ + + +3.1. Block Header + + +-------------------+-------------+=================+ + | Block Header Size | Block Flags | Compressed Size | + +-------------------+-------------+=================+ + + +===================+======================+ + ---> | Uncompressed Size | List of Filter Flags | + +===================+======================+ + + +================+--+--+--+--+ + ---> | Header Padding | CRC32 | + +================+--+--+--+--+ + + +3.1.1. Block Header Size + + This field overlaps with the Index Indicator field (see + Section 4.1). + + This field contains the size of the Block Header field, + including the Block Header Size field itself. Valid values are + in the range [0x01, 0xFF], which indicate the size of the Block + Header as multiples of four bytes, minimum size being eight + bytes: + + real_header_size = (encoded_header_size + 1) * 4; + + If a Block Header bigger than 1024 bytes is needed in the + future, a new field can be added between the Block Header and + Compressed Data fields. The presence of this new field would + be indicated in the Block Header field. + + +3.1.2. Block Flags + + The Block Flags field is a bit field: + + Bit(s) Mask Description + 0-1 0x03 Number of filters (1-4) + 2-5 0x3C Reserved for future use; MUST be zero for now. + 6 0x40 The Compressed Size field is present. + 7 0x80 The Uncompressed Size field is present. + + If any reserved bit is set, the decoder MUST indicate an error. + It is possible that there is a new field present which the + decoder is not aware of, and can thus parse the Block Header + incorrectly. + + +3.1.3. Compressed Size + + This field is present only if the appropriate bit is set in + the Block Flags field (see Section 3.1.2). + + The Compressed Size field contains the size of the Compressed + Data field, which MUST be non-zero. Compressed Size is stored + using the encoding described in Section 1.2. If the Compressed + Size doesn't match the size of the Compressed Data field, the + decoder MUST indicate an error. + + +3.1.4. Uncompressed Size + + This field is present only if the appropriate bit is set in + the Block Flags field (see Section 3.1.2). + + The Uncompressed Size field contains the size of the Block + after uncompressing. Uncompressed Size is stored using the + encoding described in Section 1.2. If the Uncompressed Size + does not match the real uncompressed size, the decoder MUST + indicate an error. + + Storing the Compressed Size and Uncompressed Size fields serves + several purposes: + - The decoder knows how much memory it needs to allocate + for a temporary buffer in multithreaded mode. + - Simple error detection: wrong size indicates a broken file. + - Seeking forwards to a specific location in streamed mode. + + It should be noted that the only reliable way to determine + the real uncompressed size is to uncompress the Block, + because the Block Header and Index fields may contain + (intentionally or unintentionally) invalid information. + + +3.1.5. List of Filter Flags + + +================+================+ +================+ + | Filter 0 Flags | Filter 1 Flags | ... | Filter n Flags | + +================+================+ +================+ + + The number of Filter Flags fields is stored in the Block Flags + field (see Section 3.1.2). + + The format of each Filter Flags field is as follows: + + +===========+====================+===================+ + | Filter ID | Size of Properties | Filter Properties | + +===========+====================+===================+ + + Both Filter ID and Size of Properties are stored using the + encoding described in Section 1.2. Size of Properties indicates + the size of the Filter Properties field as bytes. The list of + officially defined Filter IDs and the formats of their Filter + Properties are described in Section 5.3. + + Filter IDs greater than or equal to 0x4000_0000_0000_0000 + (2^62) are reserved for implementation-specific internal use. + These Filter IDs MUST never be used in List of Filter Flags. + + +3.1.6. Header Padding + + This field contains as many null byte as it is needed to make + the Block Header have the size specified in Block Header Size. + If any of the bytes are not null bytes, the decoder MUST + indicate an error. It is possible that there is a new field + present which the decoder is not aware of, and can thus parse + the Block Header incorrectly. + + +3.1.7. CRC32 + + The CRC32 is calculated over everything in the Block Header + field except the CRC32 field itself. It is stored as an + unsigned 32-bit little endian integer. If the calculated + value does not match the stored one, the decoder MUST indicate + an error. + + By verifying the CRC32 of the Block Header before parsing the + actual contents allows the decoder to distinguish between + corrupt and unsupported files. + + +3.2. Compressed Data + + The format of Compressed Data depends on Block Flags and List + of Filter Flags. Excluding the descriptions of the simplest + filters in Section 5.3, the format of the filter-specific + encoded data is out of scope of this document. + + +3.3. Block Padding + + Block Padding MUST contain 0-3 null bytes to make the size of + the Block a multiple of four bytes. This can be needed when + the size of Compressed Data is not a multiple of four. If any + of the bytes in Block Padding are not null bytes, the decoder + MUST indicate an error. + + +3.4. Check + + The type and size of the Check field depends on which bits + are set in the Stream Flags field (see Section 2.1.1.2). + + The Check, when used, is calculated from the original + uncompressed data. If the calculated Check does not match the + stored one, the decoder MUST indicate an error. If the selected + type of Check is not supported by the decoder, it SHOULD + indicate a warning or error. + + +4. Index + + +-----------------+===================+ + | Index Indicator | Number of Records | + +-----------------+===================+ + + +=================+===============+-+-+-+-+ + ---> | List of Records | Index Padding | CRC32 | + +=================+===============+-+-+-+-+ + + Index serves several purposes. Using it, one can + - verify that all Blocks in a Stream have been processed; + - find out the uncompressed size of a Stream; and + - quickly access the beginning of any Block (random access). + + +4.1. Index Indicator + + This field overlaps with the Block Header Size field (see + Section 3.1.1). The value of Index Indicator is always 0x00. + + +4.2. Number of Records + + This field indicates how many Records there are in the List + of Records field, and thus how many Blocks there are in the + Stream. The value is stored using the encoding described in + Section 1.2. If the decoder has decoded all the Blocks of the + Stream, and then notices that the Number of Records doesn't + match the real number of Blocks, the decoder MUST indicate an + error. + + +4.3. List of Records + + List of Records consists of as many Records as indicated by the + Number of Records field: + + +========+========+ + | Record | Record | ... + +========+========+ + + Each Record contains information about one Block: + + +===============+===================+ + | Unpadded Size | Uncompressed Size | + +===============+===================+ + + If the decoder has decoded all the Blocks of the Stream, it + MUST verify that the contents of the Records match the real + Unpadded Size and Uncompressed Size of the respective Blocks. + + Implementation hint: It is possible to verify the Index with + constant memory usage by calculating for example SHA-256 of + both the real size values and the List of Records, then + comparing the hash values. Implementing this using + non-cryptographic hash like CRC32 SHOULD be avoided unless + small code size is important. + + If the decoder supports random-access reading, it MUST verify + that Unpadded Size and Uncompressed Size of every completely + decoded Block match the sizes stored in the Index. If only + partial Block is decoded, the decoder MUST verify that the + processed sizes don't exceed the sizes stored in the Index. + + +4.3.1. Unpadded Size + + This field indicates the size of the Block excluding the Block + Padding field. That is, Unpadded Size is the size of the Block + Header, Compressed Data, and Check fields. Unpadded Size is + stored using the encoding described in Section 1.2. The value + MUST never be zero; with the current structure of Blocks, the + actual minimum value for Unpadded Size is five. + + Implementation note: Because the size of the Block Padding + field is not included in Unpadded Size, calculating the total + size of a Stream or doing random-access reading requires + calculating the actual size of the Blocks by rounding Unpadded + Sizes up to the next multiple of four. + + The reason to exclude Block Padding from Unpadded Size is to + ease making a raw copy of Compressed Data without Block + Padding. This can be useful, for example, if someone wants + to convert Streams to some other file format quickly. + + +4.3.2. Uncompressed Size + + This field indicates the Uncompressed Size of the respective + Block as bytes. The value is stored using the encoding + described in Section 1.2. + + +4.4. Index Padding + + This field MUST contain 0-3 null bytes to pad the Index to + a multiple of four bytes. If any of the bytes are not null + bytes, the decoder MUST indicate an error. + + +4.5. CRC32 + + The CRC32 is calculated over everything in the Index field + except the CRC32 field itself. The CRC32 is stored as an + unsigned 32-bit little endian integer. If the calculated + value does not match the stored one, the decoder MUST indicate + an error. + + +5. Filter Chains + + The Block Flags field defines how many filters are used. When + more than one filter is used, the filters are chained; that is, + the output of one filter is the input of another filter. The + following figure illustrates the direction of data flow. + + v Uncompressed Data ^ + | Filter 0 | + Encoder | Filter 1 | Decoder + | Filter n | + v Compressed Data ^ + + +5.1. Alignment + + Alignment of uncompressed input data is usually the job of + the application producing the data. For example, to get the + best results, an archiver tool should make sure that all + PowerPC executable files in the archive stream start at + offsets that are multiples of four bytes. + + Some filters, for example LZMA2, can be configured to take + advantage of specified alignment of input data. Note that + taking advantage of aligned input can be beneficial also when + a filter is not the first filter in the chain. For example, + if you compress PowerPC executables, you may want to use the + PowerPC filter and chain that with the LZMA2 filter. Because + not only the input but also the output alignment of the PowerPC + filter is four bytes, it is now beneficial to set LZMA2 + settings so that the LZMA2 encoder can take advantage of its + four-byte-aligned input data. + + The output of the last filter in the chain is stored to the + Compressed Data field, which is is guaranteed to be aligned + to a multiple of four bytes relative to the beginning of the + Stream. This can increase + - speed, if the filtered data is handled multiple bytes at + a time by the filter-specific encoder and decoder, + because accessing aligned data in computer memory is + usually faster; and + - compression ratio, if the output data is later compressed + with an external compression tool. + + +5.2. Security + + If filters would be allowed to be chained freely, it would be + possible to create malicious files, that would be very slow to + decode. Such files could be used to create denial of service + attacks. + + Slow files could occur when multiple filters are chained: + + v Compressed input data + | Filter 1 decoder (last filter) + | Filter 0 decoder (non-last filter) + v Uncompressed output data + + The decoder of the last filter in the chain produces a lot of + output from little input. Another filter in the chain takes the + output of the last filter, and produces very little output + while consuming a lot of input. As a result, a lot of data is + moved inside the filter chain, but the filter chain as a whole + gets very little work done. + + To prevent this kind of slow files, there are restrictions on + how the filters can be chained. These restrictions MUST be + taken into account when designing new filters. + + The maximum number of filters in the chain has been limited to + four, thus there can be at maximum of three non-last filters. + Of these three non-last filters, only two are allowed to change + the size of the data. + + The non-last filters, that change the size of the data, MUST + have a limit how much the decoder can compress the data: the + decoder SHOULD produce at least n bytes of output when the + filter is given 2n bytes of input. This limit is not + absolute, but significant deviations MUST be avoided. + + The above limitations guarantee that if the last filter in the + chain produces 4n bytes of output, the chain as a whole will + produce at least n bytes of output. + + +5.3. Filters + +5.3.1. LZMA2 + + LZMA (Lempel-Ziv-Markov chain-Algorithm) is a general-purpose + compression algorithm with high compression ratio and fast + decompression. LZMA is based on LZ77 and range coding + algorithms. + + LZMA2 is an extension on top of the original LZMA. LZMA2 uses + LZMA internally, but adds support for flushing the encoder, + uncompressed chunks, eases stateful decoder implementations, + and improves support for multithreading. Thus, the plain LZMA + will not be supported in this file format. + + Filter ID: 0x21 + Size of Filter Properties: 1 byte + Changes size of data: Yes + Allow as a non-last filter: No + Allow as the last filter: Yes + + Preferred alignment: + Input data: Adjustable to 1/2/4/8/16 byte(s) + Output data: 1 byte + + The format of the one-byte Filter Properties field is as + follows: + + Bits Mask Description + 0-5 0x3F Dictionary Size + 6-7 0xC0 Reserved for future use; MUST be zero for now. + + Dictionary Size is encoded with one-bit mantissa and five-bit + exponent. The smallest dictionary size is 4 KiB and the biggest + is 4 GiB. + + Raw value Mantissa Exponent Dictionary size + 0 2 11 4 KiB + 1 3 11 6 KiB + 2 2 12 8 KiB + 3 3 12 12 KiB + 4 2 13 16 KiB + 5 3 13 24 KiB + 6 2 14 32 KiB + ... ... ... ... + 35 3 27 768 MiB + 36 2 28 1024 MiB + 37 3 29 1536 MiB + 38 2 30 2048 MiB + 39 3 30 3072 MiB + 40 2 31 4096 MiB - 1 B + + Instead of having a table in the decoder, the dictionary size + can be decoded using the following C code: + + const uint8_t bits = get_dictionary_flags() & 0x3F; + if (bits > 40) + return DICTIONARY_TOO_BIG; // Bigger than 4 GiB + + uint32_t dictionary_size; + if (bits == 40) { + dictionary_size = UINT32_MAX; + } else { + dictionary_size = 2 | (bits & 1); + dictionary_size <<= bits / 2 + 11; + } + + +5.3.2. Branch/Call/Jump Filters for Executables + + These filters convert relative branch, call, and jump + instructions to their absolute counterparts in executable + files. This conversion increases redundancy and thus + compression ratio. + + Size of Filter Properties: 0 or 4 bytes + Changes size of data: No + Allow as a non-last filter: Yes + Allow as the last filter: No + + Below is the list of filters in this category. The alignment + is the same for both input and output data. + + Filter ID Alignment Description + 0x04 1 byte x86 filter (BCJ) + 0x05 4 bytes PowerPC (big endian) filter + 0x06 16 bytes IA64 filter + 0x07 4 bytes ARM filter [1] + 0x08 2 bytes ARM Thumb filter [1] + 0x09 4 bytes SPARC filter + 0x0A 4 bytes ARM64 filter [2] + 0x0B 2 bytes RISC-V filter + + [1] These are for little endian instruction encoding. + This must not be confused with data endianness. + A processor configured for big endian data access + may still use little endian instruction encoding. + The filters don't care about the data endianness. + + [2] 4096-byte alignment gives the best results + because the address in the ADRP instruction + is a multiple of 4096 bytes. + + If the size of Filter Properties is four bytes, the Filter + Properties field contains the start offset used for address + conversions. It is stored as an unsigned 32-bit little endian + integer. The start offset MUST be a multiple of the alignment + of the filter as listed in the table above; if it isn't, the + decoder MUST indicate an error. If the size of Filter + Properties is zero, the start offset is zero. + + Setting the start offset may be useful if an executable has + multiple sections, and there are many cross-section calls. + Taking advantage of this feature usually requires usage of + the Subblock filter, whose design is not complete yet. + + +5.3.3. Delta + + The Delta filter may increase compression ratio when the value + of the next byte correlates with the value of an earlier byte + at specified distance. + + Filter ID: 0x03 + Size of Filter Properties: 1 byte + Changes size of data: No + Allow as a non-last filter: Yes + Allow as the last filter: No + + Preferred alignment: + Input data: 1 byte + Output data: Same as the original input data + + The Properties byte indicates the delta distance, which can be + 1-256 bytes backwards from the current byte: 0x00 indicates + distance of 1 byte and 0xFF distance of 256 bytes. + + +5.3.3.1. Format of the Encoded Output + + The code below illustrates both encoding and decoding with + the Delta filter. + + // Distance is in the range [1, 256]. + const unsigned int distance = get_properties_byte() + 1; + uint8_t pos = 0; + uint8_t delta[256]; + + memset(delta, 0, sizeof(delta)); + + while (1) { + const int byte = read_byte(); + if (byte == EOF) + break; + + uint8_t tmp = delta[(uint8_t)(distance + pos)]; + if (is_encoder) { + tmp = (uint8_t)(byte) - tmp; + delta[pos] = (uint8_t)(byte); + } else { + tmp = (uint8_t)(byte) + tmp; + delta[pos] = tmp; + } + + write_byte(tmp); + --pos; + } + + +5.4. Custom Filter IDs + + If a developer wants to use custom Filter IDs, there are two + choices. The first choice is to contact Lasse Collin and ask + him to allocate a range of IDs for the developer. + + The second choice is to generate a 40-bit random integer + which the developer can use as a personal Developer ID. + To minimize the risk of collisions, Developer ID has to be + a randomly generated integer, not manually selected "hex word". + The following command, which works on many free operating + systems, can be used to generate Developer ID: + + dd if=/dev/urandom bs=5 count=1 | hexdump + + The developer can then use the Developer ID to create unique + (well, hopefully unique) Filter IDs. + + Bits Mask Description + 0-15 0x0000_0000_0000_FFFF Filter ID + 16-55 0x00FF_FFFF_FFFF_0000 Developer ID + 56-62 0x3F00_0000_0000_0000 Static prefix: 0x3F + + The resulting 63-bit integer will use 9 bytes of space when + stored using the encoding described in Section 1.2. To get + a shorter ID, see the beginning of this Section how to + request a custom ID range. + + +5.4.1. Reserved Custom Filter ID Ranges + + Range Description + 0x0000_0300 - 0x0000_04FF Reserved to ease .7z compatibility + 0x0002_0000 - 0x0007_FFFF Reserved to ease .7z compatibility + 0x0200_0000 - 0x07FF_FFFF Reserved to ease .7z compatibility + + +6. Cyclic Redundancy Checks + + There are several incompatible variations to calculate CRC32 + and CRC64. For simplicity and clarity, complete examples are + provided to calculate the checks as they are used in this file + format. Implementations MAY use different code as long as it + gives identical results. + + The program below reads data from standard input, calculates + the CRC32 and CRC64 values, and prints the calculated values + as big endian hexadecimal strings to standard output. + + #include + #include + #include + + uint32_t crc32_table[256]; + uint64_t crc64_table[256]; + + void + init(void) + { + static const uint32_t poly32 = UINT32_C(0xEDB88320); + static const uint64_t poly64 + = UINT64_C(0xC96C5795D7870F42); + + for (size_t i = 0; i < 256; ++i) { + uint32_t crc32 = i; + uint64_t crc64 = i; + + for (size_t j = 0; j < 8; ++j) { + if (crc32 & 1) + crc32 = (crc32 >> 1) ^ poly32; + else + crc32 >>= 1; + + if (crc64 & 1) + crc64 = (crc64 >> 1) ^ poly64; + else + crc64 >>= 1; + } + + crc32_table[i] = crc32; + crc64_table[i] = crc64; + } + } + + uint32_t + crc32(const uint8_t *buf, size_t size, uint32_t crc) + { + crc = ~crc; + for (size_t i = 0; i < size; ++i) + crc = crc32_table[buf[i] ^ (crc & 0xFF)] + ^ (crc >> 8); + return ~crc; + } + + uint64_t + crc64(const uint8_t *buf, size_t size, uint64_t crc) + { + crc = ~crc; + for (size_t i = 0; i < size; ++i) + crc = crc64_table[buf[i] ^ (crc & 0xFF)] + ^ (crc >> 8); + return ~crc; + } + + int + main() + { + init(); + + uint32_t value32 = 0; + uint64_t value64 = 0; + uint64_t total_size = 0; + uint8_t buf[8192]; + + while (1) { + const size_t buf_size + = fread(buf, 1, sizeof(buf), stdin); + if (buf_size == 0) + break; + + total_size += buf_size; + value32 = crc32(buf, buf_size, value32); + value64 = crc64(buf, buf_size, value64); + } + + printf("Bytes: %" PRIu64 "\n", total_size); + printf("CRC-32: 0x%08" PRIX32 "\n", value32); + printf("CRC-64: 0x%016" PRIX64 "\n", value64); + + return 0; + } + + +7. References + + LZMA SDK - The original LZMA implementation + https://7-zip.org/sdk.html + + LZMA Utils - LZMA adapted to POSIX-like systems + https://tukaani.org/lzma/ + + XZ Utils - The next generation of LZMA Utils + https://tukaani.org/xz/ + + [RFC-1952] + GZIP file format specification version 4.3 + https://www.ietf.org/rfc/rfc1952.txt + - Notation of byte boxes in section "2.1. Overall conventions" + + [RFC-2119] + Key words for use in RFCs to Indicate Requirement Levels + https://www.ietf.org/rfc/rfc2119.txt + + [GNU-tar] + GNU tar 1.35 manual + https://www.gnu.org/software/tar/manual/html_node/Blocking-Factor.html + - Node 9.4.2 "Blocking Factor", paragraph that begins + "gzip will complain about trailing garbage" + - Note that this URL points to the latest version of the + manual, and may some day not contain the note which is in + 1.35. For the exact version of the manual, download GNU + tar 1.35: ftp://ftp.gnu.org/pub/gnu/tar/tar-1.35.tar.gz + diff --git a/cpp/third_party/xz-5.8.3/dos/INSTALL.txt b/cpp/third_party/xz-5.8.3/dos/INSTALL.txt new file mode 100644 index 000000000..e5ba85bdb --- /dev/null +++ b/cpp/third_party/xz-5.8.3/dos/INSTALL.txt @@ -0,0 +1,78 @@ + +Building XZ Utils for DOS +========================= + +Introduction + + This document explains how to build XZ Utils for DOS using DJGPP. + The resulting binaries should run at least on various DOS versions + and under Windows 95/98/98SE/ME. + + This is somewhat experimental and has got very little testing. + + Note: Makefile and config.h are updated only now and then. This + means that if you checked out a development version, building for + DOS might not work without updating Makefile and config.h first. + + +Getting and Installing DJGPP + + You may use to help + deciding what to download. If you are only interested in building + XZ Utils, the zip-picker may list files that you don't strictly + need. However, using the zip-picker can still be worth it to get a + nice short summary of installation instructions (they can be found + from readme.1st too). + + For a more manual method, first select a mirror from + and go the + subdirectory named "current". You need the following files: + + unzip32.exe (if you don't already have a LFN-capable unzipper) + v2/djdev205.zip + v2gnu/bnu234b.zip + v2gnu/gcc920b.zip + v2gnu/mak43b.zip + v2misc/csdpmi7b.zip + + If newer versions are available, probably you should try them first. + Note that versions older than djdev205.zip aren't supported. Also + note that you want csdpmi7b.zip even if you run under Windows or + DOSEMU because the XZ Utils Makefile will embed cwsdstub.exe to + the resulting xz.exe. + + See the instructions in readme.1st found from djdev205.zip. Here's + a short summary, but you should still read readme.1st. + + C:\> mkdir DJGPP + C:\> cd DJGPP + C:\DJGPP> c:\download\unzip32 c:\download\djdev205.zip + C:\DJGPP> c:\download\unzip32 c:\download\bnu234b.zip + C:\DJGPP> c:\download\unzip32 c:\download\gcc920b.zip + C:\DJGPP> c:\download\unzip32 c:\download\mak43b.zip + C:\DJGPP> c:\download\unzip32 c:\download\csdpmi7b.zip + + C:\DJGPP> set PATH=C:\DJGPP\BIN;%PATH% + C:\DJGPP> set DJGPP=C:\DJGPP\DJGPP.ENV + + You may want to add the last two lines into AUTOEXEC.BAT or have, + for example, DJGPP.BAT which you can run before using DJGPP. + + Make sure you use completely upper case path in the DJGPP environment + variable. This is not required by DJGPP, but the XZ Utils Makefile is + a bit stupid and expects that everything in DJGPP environment variable + is uppercase. + + +Building + + You need to have an environment that supports long filenames (LFN). + Once you have built XZ Utils, the resulting binaries can be run + without long filename support. + + Run "make" in this directory (the directory containing this + INSTALL.txt). You should get xz.exe (and a bunch of temporary files). + Other tools are not built. Having e.g. xzdec.exe doesn't save much + space compared to xz.exe because the DJGPP runtime makes the .exe + quite big anyway. + diff --git a/cpp/third_party/xz-5.8.3/dos/Makefile b/cpp/third_party/xz-5.8.3/dos/Makefile new file mode 100644 index 000000000..a3d4ab4ba --- /dev/null +++ b/cpp/third_party/xz-5.8.3/dos/Makefile @@ -0,0 +1,150 @@ +# SPDX-License-Identifier: 0BSD + +############################################################################### +# +# Makefile to build XZ Utils using DJGPP +# +# Author: Lasse Collin +# +############################################################################### + +# For debugging, set comment "#define NDEBUG 1" from config.h to enable +# the assert() macro, set STRIP=rem to disable stripping, and finally +# e.g. CFLAGS="-g -O0". +CC = gcc +STRIP = strip +CPPFLAGS = +CFLAGS = -g -Wall -Wextra -Wfatal-errors -march=i386 -mtune=i686 -O2 +LDFLAGS = -lemu + +ALL_CFLAGS = -std=gnu99 + +ALL_CPPFLAGS = \ + -I. \ + -I../lib \ + -I../src/common \ + -I../src/liblzma/api \ + -I../src/liblzma/common \ + -I../src/liblzma/check \ + -I../src/liblzma/rangecoder \ + -I../src/liblzma/lz \ + -I../src/liblzma/lzma \ + -I../src/liblzma/delta \ + -I../src/liblzma/simple \ + -DHAVE_CONFIG_H + +ALL_CPPFLAGS += $(CPPFLAGS) +ALL_CFLAGS += $(CFLAGS) + +.PHONY: all +all: xz.exe + +SRCS_C = \ + ../lib/getopt.c \ + ../lib/getopt1.c \ + ../src/common/tuklib_cpucores.c \ + ../src/common/tuklib_exit.c \ + ../src/common/tuklib_mbstr_fw.c \ + ../src/common/tuklib_mbstr_nonprint.c \ + ../src/common/tuklib_mbstr_width.c \ + ../src/common/tuklib_mbstr_wrap.c \ + ../src/common/tuklib_open_stdxxx.c \ + ../src/common/tuklib_physmem.c \ + ../src/common/tuklib_progname.c \ + ../src/liblzma/check/check.c \ + ../src/liblzma/check/crc32_fast.c \ + ../src/liblzma/check/crc64_fast.c \ + ../src/liblzma/check/sha256.c \ + ../src/liblzma/common/alone_decoder.c \ + ../src/liblzma/common/alone_encoder.c \ + ../src/liblzma/common/block_decoder.c \ + ../src/liblzma/common/block_encoder.c \ + ../src/liblzma/common/block_header_decoder.c \ + ../src/liblzma/common/block_header_encoder.c \ + ../src/liblzma/common/block_util.c \ + ../src/liblzma/common/common.c \ + ../src/liblzma/common/file_info.c \ + ../src/liblzma/common/filter_common.c \ + ../src/liblzma/common/filter_decoder.c \ + ../src/liblzma/common/filter_encoder.c \ + ../src/liblzma/common/filter_flags_decoder.c \ + ../src/liblzma/common/filter_flags_encoder.c \ + ../src/liblzma/common/hardware_physmem.c \ + ../src/liblzma/common/index.c \ + ../src/liblzma/common/index_decoder.c \ + ../src/liblzma/common/index_encoder.c \ + ../src/liblzma/common/index_hash.c \ + ../src/liblzma/common/lzip_decoder.c \ + ../src/liblzma/common/stream_decoder.c \ + ../src/liblzma/common/stream_encoder.c \ + ../src/liblzma/common/stream_flags_common.c \ + ../src/liblzma/common/stream_flags_decoder.c \ + ../src/liblzma/common/stream_flags_encoder.c \ + ../src/liblzma/common/string_conversion.c \ + ../src/liblzma/common/vli_decoder.c \ + ../src/liblzma/common/vli_encoder.c \ + ../src/liblzma/common/vli_size.c \ + ../src/liblzma/delta/delta_common.c \ + ../src/liblzma/delta/delta_decoder.c \ + ../src/liblzma/delta/delta_encoder.c \ + ../src/liblzma/lz/lz_decoder.c \ + ../src/liblzma/lz/lz_encoder.c \ + ../src/liblzma/lz/lz_encoder_mf.c \ + ../src/liblzma/lzma/fastpos_table.c \ + ../src/liblzma/lzma/lzma2_decoder.c \ + ../src/liblzma/lzma/lzma2_encoder.c \ + ../src/liblzma/lzma/lzma_decoder.c \ + ../src/liblzma/lzma/lzma_encoder.c \ + ../src/liblzma/lzma/lzma_encoder_optimum_fast.c \ + ../src/liblzma/lzma/lzma_encoder_optimum_normal.c \ + ../src/liblzma/lzma/lzma_encoder_presets.c \ + ../src/liblzma/rangecoder/price_table.c \ + ../src/liblzma/simple/arm.c \ + ../src/liblzma/simple/arm64.c \ + ../src/liblzma/simple/armthumb.c \ + ../src/liblzma/simple/ia64.c \ + ../src/liblzma/simple/powerpc.c \ + ../src/liblzma/simple/simple_coder.c \ + ../src/liblzma/simple/simple_decoder.c \ + ../src/liblzma/simple/simple_encoder.c \ + ../src/liblzma/simple/sparc.c \ + ../src/liblzma/simple/x86.c \ + ../src/xz/args.c \ + ../src/xz/coder.c \ + ../src/xz/file_io.c \ + ../src/xz/hardware.c \ + ../src/xz/list.c \ + ../src/xz/main.c \ + ../src/xz/message.c \ + ../src/xz/mytime.c \ + ../src/xz/options.c \ + ../src/xz/signals.c \ + ../src/xz/suffix.c \ + ../src/xz/util.c +SRCS_ASM = \ + ../src/liblzma/check/crc32_x86.S \ + ../src/liblzma/check/crc64_x86.S + +OBJS_C = $(SRCS_C:.c=.o) +OBJS_ASM = $(SRCS_ASM:.S=.o) +OBJS = $(OBJS_C) $(OBJS_ASM) + +getopt.h: + update ../lib/getopt.in.h getopt.h + +$(OBJS): getopt.h + +$(OBJS_C): %.o: %.c + $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c -o $@ $< + +$(OBJS_ASM): %.o: %.S + $(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c -o $@ $< + +# Make xz.exe not depend on an external DPMI server. +xz.exe: $(OBJS) + $(CC) $(ALL_CFLAGS) $(OBJS) $(LDFLAGS) -o $@ + $(STRIP) --strip-all $@ + exe2coff $@ + del $@ + copy /b $(DJGPP:DJGPP.ENV=BIN\CWSDSTUB.EXE) + $(@:.exe=) $@ + del $(@:.exe=) diff --git a/cpp/third_party/xz-5.8.3/dos/README.txt b/cpp/third_party/xz-5.8.3/dos/README.txt new file mode 100644 index 000000000..0e8f6c086 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/dos/README.txt @@ -0,0 +1,123 @@ + +XZ Utils on DOS +=============== + +DOS-specific filename handling + + xz detects at runtime if long filename (LFN) support is + available and will use it by default. It can be disabled by + setting an environment variable: + + set lfn=n + + When xz is in LFN mode, it behaves pretty much the same as it + does on other operating systems. Examples: + + xz foo.tar -> foo.tar.xz + xz -d foo.tar.xz -> foo.tar + + xz -F lzma foo.tar -> foo.tar.lzma + xz -d foo.tar.lzma -> foo.tar + + When LFN support isn't available or it is disabled with LFN=n + environment setting, xz works in short filename (SFN) mode. This + affects filename suffix handling when compressing. + + When compressing to the .xz format in SFN mode: + + - Files without an extension get .xz just like on LFN systems. + + - *.tar files become *.txz (shorthand for *.tar.xz). *.txz + is recognized by xz on all supported operating systems. + (Try to avoid confusing this with gzipped .txt files.) + + - Files with 1-3 character extension have their extension modified + so that the last character is a dash ("-"). If the extension + is already three characters, the last character is lost. The + resulting *.?- or *.??- filename is recognized in LFN mode, but + it isn't recognized by xz on other operating systems. + + Examples: + + xz foo -> foo.xz | xz -d foo.xz -> foo + xz foo.tar -> foo.txz | xz -d foo.txz -> foo.tar + xz foo.c -> foo.c- | xz -d foo.c- -> foo.c + xz read.me -> read.me- | xz -d read.me- -> read.me + xz foo.txt -> foo.tx- | xz -d foo.tx- -> foo.tx ! + + Note that in the last example above, the third character of the + filename extension is lost. + + When compressing to the legacy .lzma format in SFN mode: + + - *.tar files become *.tlz (shorthand for *.tar.lzma). *.tlz + is recognized by xz on all supported operating systems. + + - Other files become *.lzm. The original filename extension + is lost. *.lzm is recognized also in LFN mode, but it is not + recognized by xz on other operating systems. + + Examples: + + xz -F lzma foo -> foo.lzm | xz -d foo.lzm -> foo + xz -F lzma foo.tar -> foo.tlz | xz -d foo.tlz -> foo.tar + xz -F lzma foo.c -> foo.lzm | xz -d foo.lzm -> foo ! + xz -F lzma read.me -> read.lzm | xz -d read.lzm -> read ! + xz -F lzma foo.txt -> foo.lzm | xz -d foo.lzm -> foo ! + + When compressing with a custom suffix (-S .SUF, --suffix=.SUF) to + any file format: + + - If the suffix begins with a dot, the filename extension is + replaced with the new suffix. The original extension is lost. + + - If the suffix doesn't begin with a dot and the filename has no + extension and the filename given on the command line doesn't + have a dot at the end, the custom suffix is appended just like + on LFN systems. + + - If the suffix doesn't begin with a dot and the filename has + an extension (or an extension-less filename is given with a dot + at the end), the last 1-3 characters of the filename extension + may get overwritten to fit the given custom suffix. + + Examples: + + xz -S x foo -> foox | xz -dS x foox -> foo + xz -S x foo. -> foo.x | xz -dS x foo.x -> foo + xz -S .x foo -> foo.x | xz -dS .x foo.x -> foo + xz -S .x foo. -> foo.x | xz -dS .x foo.x -> foo + xz -S x.y foo -> foox.y | xz -dS x.y foox.y -> foo + xz -S .a foo.c -> foo.a | xz -dS .a foo.a -> foo ! + xz -S a foo.c -> foo.ca | xz -dS a foo.ca -> foo.c + xz -S ab foo.c -> foo.cab | xz -dS ab foo.cab -> foo.c + xz -S ab read.me -> read.mab | xz -dS ab read.mab -> read.m ! + xz -S ab foo.txt -> foo.tab | xz -dS ab foo.tab -> foo.t ! + xz -S abc foo.txt -> foo.abc | xz -dS abc foo.abc -> foo ! + + When decompressing, the suffix handling in SFN mode is the same as + in LFN mode. The DOS-specific filenames *.lzm, *.?-, and *.??- are + recognized also in LFN mode. + + xz handles certain uncommon situations safely: + + - If the generated output filename refers to the same file as + the input file, xz detects this and refuses to compress or + decompress the input file even if --force is used. This can + happen when giving an overlong filename in SFN mode. E.g. + "xz -S x foo.texinfo" would try to write to foo.tex which on + SFN system is the same file as foo.texinfo. + + - If the generated output filename is a special file like "con" + or "prn", xz detects this and refuses to compress or decompress + the input file even if --force is used. + + +Bugs + + xz doesn't necessarily work in Dosbox. It should work in DOSEMU. + + Pressing Ctrl-c or Ctrl-Break won't remove the incomplete target file + when running under Windows XP Command Prompt (something goes wrong + with SIGINT handling). It works correctly under Windows 95/98/98SE/ME. + diff --git a/cpp/third_party/xz-5.8.3/dos/config.h b/cpp/third_party/xz-5.8.3/dos/config.h new file mode 100644 index 000000000..4bab00e13 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/dos/config.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: 0BSD */ + +/* How many MiB of RAM to assume if the real amount cannot be determined. */ +#define ASSUME_RAM 32 + +/* Define to 1 if crc32 integrity check is enabled. */ +#define HAVE_CHECK_CRC32 1 + +/* Define to 1 if crc64 integrity check is enabled. */ +#define HAVE_CHECK_CRC64 1 + +/* Define to 1 if sha256 integrity check is enabled. */ +#define HAVE_CHECK_SHA256 1 + +/* Define to 1 if the 32-bit x86 CRC assembly files are used. */ +#define HAVE_CRC_X86_ASM 1 + +/* Define to 1 if any of HAVE_DECODER_foo have been defined. */ +#define HAVE_DECODERS 1 + +/* Define to 1 if arm decoder is enabled. */ +#define HAVE_DECODER_ARM 1 + +/* Define to 1 if arm64 decoder is enabled. */ +#define HAVE_DECODER_ARM64 1 + +/* Define to 1 if armthumb decoder is enabled. */ +#define HAVE_DECODER_ARMTHUMB 1 + +/* Define to 1 if delta decoder is enabled. */ +#define HAVE_DECODER_DELTA 1 + +/* Define to 1 if ia64 decoder is enabled. */ +#define HAVE_DECODER_IA64 1 + +/* Define to 1 if lzma1 decoder is enabled. */ +#define HAVE_DECODER_LZMA1 1 + +/* Define to 1 if lzma2 decoder is enabled. */ +#define HAVE_DECODER_LZMA2 1 + +/* Define to 1 if powerpc decoder is enabled. */ +#define HAVE_DECODER_POWERPC 1 + +/* Define to 1 if sparc decoder is enabled. */ +#define HAVE_DECODER_SPARC 1 + +/* Define to 1 if x86 decoder is enabled. */ +#define HAVE_DECODER_X86 1 + +/* Define to 1 if any of HAVE_ENCODER_foo have been defined. */ +#define HAVE_ENCODERS 1 + +/* Define to 1 if arm encoder is enabled. */ +#define HAVE_ENCODER_ARM 1 + +/* Define to 1 if arm64 encoder is enabled. */ +#define HAVE_ENCODER_ARM64 1 + +/* Define to 1 if armthumb encoder is enabled. */ +#define HAVE_ENCODER_ARMTHUMB 1 + +/* Define to 1 if delta encoder is enabled. */ +#define HAVE_ENCODER_DELTA 1 + +/* Define to 1 if ia64 encoder is enabled. */ +#define HAVE_ENCODER_IA64 1 + +/* Define to 1 if lzma1 encoder is enabled. */ +#define HAVE_ENCODER_LZMA1 1 + +/* Define to 1 if lzma2 encoder is enabled. */ +#define HAVE_ENCODER_LZMA2 1 + +/* Define to 1 if powerpc encoder is enabled. */ +#define HAVE_ENCODER_POWERPC 1 + +/* Define to 1 if sparc encoder is enabled. */ +#define HAVE_ENCODER_SPARC 1 + +/* Define to 1 if x86 encoder is enabled. */ +#define HAVE_ENCODER_X86 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if .lz (lzip) decompression support is enabled. */ +#define HAVE_LZIP_DECODER 1 + +/* Define to 1 to enable bt2 match finder. */ +#define HAVE_MF_BT2 1 + +/* Define to 1 to enable bt3 match finder. */ +#define HAVE_MF_BT3 1 + +/* Define to 1 to enable bt4 match finder. */ +#define HAVE_MF_BT4 1 + +/* Define to 1 to enable hc3 match finder. */ +#define HAVE_MF_HC3 1 + +/* Define to 1 to enable hc4 match finder. */ +#define HAVE_MF_HC4 1 + +/* Define to 1 if stdbool.h conforms to C99. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the 'utimes' function. */ +#define HAVE_UTIMES 1 + +/* Define to 1 or 0, depending whether the compiler supports simple visibility + declarations. */ +#define HAVE_VISIBILITY 0 + +/* Define to 1 if the system has the type '_Bool'. */ +#define HAVE__BOOL 1 + +/* Define to 1 if the GNU C extension __builtin_assume_aligned is supported. + */ +#define HAVE___BUILTIN_ASSUME_ALIGNED 1 + +/* Define to 1 if the GNU C extensions __builtin_bswap16/32/64 are supported. + */ +#define HAVE___BUILTIN_BSWAPXX 1 + +/* Define to 1 to disable debugging code. */ +#define NDEBUG 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "xz@tukaani.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "XZ Utils" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "https://tukaani.org/xz/" + +/* The size of 'size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 4 + +/* Define to 1 if the system supports fast unaligned access to 16-bit and + 32-bit integers. */ +#define TUKLIB_FAST_UNALIGNED_ACCESS 1 diff --git a/cpp/third_party/xz-5.8.3/doxygen/Doxyfile b/cpp/third_party/xz-5.8.3/doxygen/Doxyfile new file mode 100644 index 000000000..e13724e78 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/doxygen/Doxyfile @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: 0BSD + +# Run "doxygen" in this directory to generate the liblzma API documentation +# into ../doc/api. +# +# Use the "update-doxygen" script for more choices: +# - Include the liblzma version number in the generated documentation. +# - Instead of API docs, docs of XZ Utils internals may be built. +# - Change the output directory for out-of-tree builds. +# +# These options were tested with Doxygen 1.9.8 and 1.13.2. + +PROJECT_NAME = "liblzma (XZ Utils)" +OUTPUT_DIRECTORY = ../doc +STRIP_FROM_PATH = ../src/liblzma/api +INPUT = ../src/liblzma/api +FILE_PATTERNS = *.c *.h +RECURSIVE = YES +OPTIMIZE_OUTPUT_FOR_C = YES +EXTRACT_STATIC = YES +SORT_MEMBER_DOCS = NO +WARN_IF_UNDOCUMENTED = NO +WARN_AS_ERROR = FAIL_ON_WARNINGS +SOURCE_TOOLTIPS = NO +VERBATIM_HEADERS = NO +ALPHABETICAL_INDEX = NO +HTML_OUTPUT = api +HTML_COLORSTYLE_HUE = 210 +HTML_COLORSTYLE_SAT = 180 +HTML_COLORSTYLE_GAMMA = 110 +HTML_DYNAMIC_MENUS = NO +SEARCHENGINE = NO +GENERATE_LATEX = NO +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +PREDEFINED = LZMA_API(type)=type \ + LZMA_API_IMPORT= \ + LZMA_API_CALL= \ + tuklib_attr_noreturn= \ + lzma_attribute(attr)= \ + lzma_attr_alloc_size(size)= + +# Debian and Ubuntu patch Doxygen so that HAVE_DOT = YES is the default. +# Set HAVE_DOT explicitly to get consistent behavior across distributions. +HAVE_DOT = NO diff --git a/cpp/third_party/xz-5.8.3/doxygen/update-doxygen b/cpp/third_party/xz-5.8.3/doxygen/update-doxygen new file mode 100755 index 000000000..c5d6ad39f --- /dev/null +++ b/cpp/third_party/xz-5.8.3/doxygen/update-doxygen @@ -0,0 +1,114 @@ +#!/bin/sh +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# While it's possible to use the Doxyfile as is to generate liblzma API +# documentation, it is recommended to use this script because this adds +# the XZ Utils version number to the generated HTML. +# +# Other features: +# - Generate documentation of the XZ Utils internals. +# - Set input and output paths for out-of-tree builds. +# +############################################################################# +# +# Authors: Jia Tan +# Lasse Collin +# +############################################################################# + +set -e + +show_usage() +{ + echo "Usage: $0 [ABS_TOP_SRCDIR ABS_OUTDIR]" + echo + echo "Supported modes:" + echo " - 'api' (default): liblzma API docs into doc/api" + echo " - 'internal': internal docs into doc/internal" + echo + echo "Absolute source and output dirs may be set" \ + "to do an out-of-tree build." + echo "The output directory must already exist." + exit 1 +} + +case $1 in + api|internal) + ;; + *) + show_usage + ;; +esac + +if type doxygen > /dev/null 2>&1; then + : +else + echo "$0: 'doxygen' command not found" >&2 + exit 1 +fi + +case $# in + 1) + # One argument: Building inside the source tree + ABS_TOP_SRCDIR=`dirname "$0"`/.. + ABS_OUTDIR=$ABS_TOP_SRCDIR/doc + ;; + 3) + # Three arguments: Possibly an out of tree build + ABS_TOP_SRCDIR=$2 + ABS_OUTDIR=$3 + ;; + *) + show_usage + ;; +esac + +if test ! -f "$ABS_TOP_SRCDIR/doxygen/Doxyfile"; then + echo "$0: Source dir '$ABS_TOP_SRCDIR/doxygen/Doxyfile' not found" >&2 + exit 1 +fi +if test ! -d "$ABS_OUTDIR"; then + echo "$0: Output dir '$ABS_OUTDIR' not found" >&2 + exit 1 +fi + +# Get the package version so that it can be included in the generated docs. +PACKAGE_VERSION=`cd "$ABS_TOP_SRCDIR" && sh build-aux/version.sh` + +case $1 in + api) + # Remove old documentation before re-generating the new. + rm -rf "$ABS_OUTDIR/api" + + # Generate the HTML documentation by preparing the Doxyfile + # in stdin and piping the result to the doxygen command. + # With Doxygen, the last assignment of a value to a tag will + # override any earlier assignment. So, we can use this + # feature to override the tags that need to change between + # "api" and "internal" modes. + ABS_SRCDIR=$ABS_TOP_SRCDIR/src/liblzma/api + ( + cat "$ABS_TOP_SRCDIR/doxygen/Doxyfile" + echo "PROJECT_NUMBER = $PACKAGE_VERSION" + echo "OUTPUT_DIRECTORY = $ABS_OUTDIR" + echo "STRIP_FROM_PATH = $ABS_SRCDIR" + echo "INPUT = $ABS_SRCDIR" + ) | doxygen -q - + ;; + + internal) + rm -rf "$ABS_OUTDIR/internal" + ( + cat "$ABS_TOP_SRCDIR/doxygen/Doxyfile" + echo 'PROJECT_NAME = "XZ Utils"' + echo "PROJECT_NUMBER = $PACKAGE_VERSION" + echo "OUTPUT_DIRECTORY = $ABS_OUTDIR" + echo "STRIP_FROM_PATH = $ABS_TOP_SRCDIR" + echo "INPUT = $ABS_TOP_SRCDIR/src" + echo 'HTML_OUTPUT = internal' + echo 'SEARCHENGINE = YES' + ) | doxygen -q - + ;; +esac diff --git a/cpp/third_party/xz-5.8.3/extra/7z2lzma/7z2lzma.bash b/cpp/third_party/xz-5.8.3/extra/7z2lzma/7z2lzma.bash new file mode 100755 index 000000000..351108c87 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/extra/7z2lzma/7z2lzma.bash @@ -0,0 +1,113 @@ +#!/bin/bash +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# 7z2lzma.bash is very primitive .7z to .lzma converter. The input file must +# have exactly one LZMA compressed stream, which has been created with the +# default lc, lp, and pb values. The CRC32 in the .7z archive is not checked, +# and the script may seem to succeed while it actually created a corrupt .lzma +# file. You should always try uncompressing both the original .7z and the +# created .lzma and compare that the output is identical. +# +# This script requires basic GNU tools and 7z or 7za tool from p7zip. +# +# Last modified: 2009-01-15 14:25+0200 +# +############################################################################# +# +# Author: Lasse Collin +# +############################################################################# + +# You can use 7z or 7za, both will work. +SEVENZIP=7za + +if [ $# != 2 -o -z "$1" -o -z "$2" ]; then + echo "Usage: $0 input.7z output.lzma" + exit 1 +fi + +# Converts an integer variable to little endian binary integer. +int2bin() +{ + local LEN=$1 + local NUM=$2 + local HEX=(0 1 2 3 4 5 6 7 8 9 A B C D E F) + local I + for ((I=0; I < "$LEN"; ++I)); do + printf "\\x${HEX[(NUM >> 4) & 0x0F]}${HEX[NUM & 0x0F]}" + NUM=$((NUM >> 8)) + done +} + +# Make sure we get possible errors from pipes. +set -o pipefail + +# Get information about the input file. At least older 7z and 7za versions +# may return with zero exit status even when an error occurred, so check +# if the output has any lines beginning with "Error". +INFO=$("$SEVENZIP" l -slt "$1") +if [ $? != 0 ] || printf '%s\n' "$INFO" | grep -q ^Error; then + printf '%s\n' "$INFO" + exit 1 +fi + +# Check if the input file has more than one compressed block. +if printf '%s\n' "$INFO" | grep -q '^Block = 1'; then + echo "Cannot convert, because the input file has more than" + echo "one compressed block." + exit 1 +fi + +# Get compressed, uncompressed, and dictionary size. +CSIZE=$(printf '%s\n' "$INFO" | sed -rn 's|^Packed Size = ([0-9]+$)|\1|p') +USIZE=$(printf '%s\n' "$INFO" | sed -rn 's|^Size = ([0-9]+$)|\1|p') +DICT=$(printf '%s\n' "$INFO" | sed -rn 's|^Method = LZMA:([0-9]+[bkm]?)$|\1|p') + +if [ -z "$CSIZE" -o -z "$USIZE" -o -z "$DICT" ]; then + echo "Parsing output of $SEVENZIP failed. Maybe the file uses some" + echo "other compression method than plain LZMA." + exit 1 +fi + +# The following assumes that the default lc, lp, and pb settings were used. +# Otherwise the output will be corrupt. +printf '\x5D' > "$2" + +# Dictionary size can be either was power of two, bytes, kibibytes, or +# mebibytes. We need to convert it to bytes. +case $DICT in + *b) + DICT=${DICT%b} + ;; + *k) + DICT=${DICT%k} + DICT=$((DICT << 10)) + ;; + *m) + DICT=${DICT%m} + DICT=$((DICT << 20)) + ;; + *) + DICT=$((1 << DICT)) + ;; +esac +int2bin 4 "$DICT" >> "$2" + +# Uncompressed size +int2bin 8 "$USIZE" >> "$2" + +# Copy the actual compressed data. Using multiple dd commands to avoid +# copying large amount of data with one-byte block size, which would be +# annoyingly slow. +BS=8192 +BIGSIZE=$((CSIZE / BS)) +CSIZE=$((CSIZE % BS)) +{ + dd of=/dev/null bs=32 count=1 \ + && dd bs="$BS" count="$BIGSIZE" \ + && dd bs=1 count="$CSIZE" +} < "$1" >> "$2" + +exit $? diff --git a/cpp/third_party/xz-5.8.3/extra/scanlzma/scanlzma.c b/cpp/third_party/xz-5.8.3/extra/scanlzma/scanlzma.c new file mode 100644 index 000000000..1c8fcd8f4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/extra/scanlzma/scanlzma.c @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + scanlzma, scan for lzma compressed data in stdin and echo it to stdout. + Copyright (C) 2006 Timo Lindfors + + 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. +*/ + +/* Usage example: + + $ wget http://www.wifi-shop.cz/Files/produkty/wa2204/wa2204av1.4.1.zip + $ unzip wa2204av1.4.1.zip + $ gcc scanlzma.c -o scanlzma -Wall + $ ./scanlzma 0 < WA2204-FW1.4.1/linux-1.4.bin | lzma -c -d | strings | grep -i "copyright" + UpdateDD version 2.5, Copyright (C) 2005 Philipp Benner. + Copyright (C) 2005 Philipp Benner. + Copyright (C) 2005 Philipp Benner. + mawk 1.3%s%s %s, Copyright (C) Michael D. Brennan + # Copyright (C) 1998, 1999, 2001 Henry Spencer. + ... + +*/ + + +/* LZMA compressed file format */ +/* --------------------------- */ +/* Offset Size Description */ +/* 0 1 Special LZMA properties for compressed data */ +/* 1 4 Dictionary size (little endian) */ +/* 5 8 Uncompressed size (little endian). -1 means unknown size */ +/* 13 Compressed data */ + +#include +#include +#include + +#define BUFSIZE 4096 + +int find_lzma_header(unsigned char *buf) { + return (buf[0] < 0xE1 + && buf[0] == 0x5d + && buf[4] < 0x20 + && (memcmp (buf + 10 , "\x00\x00\x00", 3) == 0 + || (memcmp (buf + 5, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8) == 0))); +} + +int main(int argc, char *argv[]) { + unsigned char buf[BUFSIZE]; + int ret, i, numlzma, blocks=0; + + if (argc != 2) { + printf("usage: %s numlzma < infile | lzma -c -d > outfile\n" + "where numlzma is index of lzma file to extract, starting from zero.\n", + argv[0]); + exit(1); + } + numlzma = atoi(argv[1]); + + for (;;) { + /* Read data. */ + ret = fread(buf, BUFSIZE, 1, stdin); + if (ret != 1) + break; + + /* Scan for signature. */ + for (i = 0; i $@-t + mv -f $@-t $@ diff --git a/cpp/third_party/xz-5.8.3/lib/Makefile.in b/cpp/third_party/xz-5.8.3/lib/Makefile.in new file mode 100644 index 000000000..f097e0405 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/Makefile.in @@ -0,0 +1,625 @@ +# Makefile.in generated by automake 1.18.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2025 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)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) +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@ +subdir = lib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/build-to-host.m4 $(top_srcdir)/m4/getopt.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/host-cpu-c-abi.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/posix-shell.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/tuklib_common.m4 \ + $(top_srcdir)/m4/tuklib_cpucores.m4 \ + $(top_srcdir)/m4/tuklib_integer.m4 \ + $(top_srcdir)/m4/tuklib_mbstr.m4 \ + $(top_srcdir)/m4/tuklib_physmem.m4 \ + $(top_srcdir)/m4/tuklib_progname.m4 \ + $(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cr +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libgnu_a_AR = $(AR) $(ARFLAGS) +libgnu_a_RANLIB = $(RANLIB) +am_libgnu_a_OBJECTS = +libgnu_a_OBJECTS = $(am_libgnu_a_OBJECTS) +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@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = $(DEPDIR)/getopt.Po $(DEPDIR)/getopt1.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +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 = +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 = $(libgnu_a_SOURCES) +DIST_SOURCES = $(libgnu_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp getopt.c getopt1.c +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ +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@ +FILECMD = @FILECMD@ +GETOPT_H = @GETOPT_H@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LINKER_FLAG_UNDEFINED_VERSION = @LINKER_FLAG_UNDEFINED_VERSION@ +LIPO = @LIPO@ +LN_EXEEXT = @LN_EXEEXT@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +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@ +POSIX_SHELL = @POSIX_SHELL@ +POSUB = @POSUB@ +PREFERABLY_POSIX_SHELL = @PREFERABLY_POSIX_SHELL@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +RC = @RC@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +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__rm_f_notfound = @am__rm_f_notfound@ +am__tar = @am__tar@ +am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ +ax_pthread_config = @ax_pthread_config@ +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@ +enable_path_for_scripts = @enable_path_for_scripts@ +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@ +localedir_c = @localedir_c@ +localedir_c_make = @localedir_c_make@ +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@ +xz = @xz@ +noinst_LIBRARIES = libgnu.a +libgnu_a_SOURCES = +libgnu_a_DEPENDENCIES = $(LIBOBJS) +libgnu_a_LIBADD = $(LIBOBJS) +EXTRA_DIST = \ + getopt.in.h \ + getopt.c \ + getopt1.c \ + getopt_int.h \ + getopt-cdefs.h \ + getopt-core.h \ + getopt-ext.h \ + getopt-pfx-core.h \ + getopt-pfx-ext.h + +BUILT_SOURCES = $(GETOPT_H) +MOSTLYCLEANFILES = getopt.h getopt.h-t +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign lib/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -$(am__rm_f) $(noinst_LIBRARIES) + +libgnu.a: $(libgnu_a_OBJECTS) $(libgnu_a_DEPENDENCIES) $(EXTRA_libgnu_a_DEPENDENCIES) + $(AM_V_at)-rm -f libgnu.a + $(AM_V_AR)$(libgnu_a_AR) libgnu.a $(libgnu_a_OBJECTS) $(libgnu_a_LIBADD) + $(AM_V_at)$(libgnu_a_RANLIB) libgnu.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getopt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getopt1.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @: >>$@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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 $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @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 +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) +installdirs: +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: + -$(am__rm_f) $(MOSTLYCLEANFILES) + +clean-generic: + +distclean-generic: + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -$(am__rm_f) $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f $(DEPDIR)/getopt.Po + -rm -f $(DEPDIR)/getopt1.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +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 $(DEPDIR)/getopt.Po + -rm -f $(DEPDIR)/getopt1.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: + +.MAKE: all check install install-am install-exec install-strip + +.PHONY: all all-am am--depfiles check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES cscopelist-am ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am 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 tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +getopt.h: getopt.in.h + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/getopt.in.h; \ + } > $@-t + mv -f $@-t $@ + +# 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: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/cpp/third_party/xz-5.8.3/lib/getopt-cdefs.h b/cpp/third_party/xz-5.8.3/lib/getopt-cdefs.h new file mode 100644 index 000000000..576428c1c --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt-cdefs.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* getopt-on-non-glibc compatibility macros. + Copyright (C) 1989-2023 Free Software Foundation, Inc. + This file is part of gnulib. + Unlike most of the getopt implementation, it is NOT shared + with the GNU C Library. + + This file 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. + + This file 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 this program. If not, see . */ + +#ifndef _GETOPT_CDEFS_H +#define _GETOPT_CDEFS_H 1 + +/* This header should not be used directly; include getopt.h or + unistd.h instead. It does not have a protective #error, because + the guard macro for getopt.h in gnulib is not fixed. */ + +/* getopt-core.h and getopt-ext.h are shared with GNU libc, and expect + a number of the internal macros supplied to GNU libc's headers by + sys/cdefs.h. Provide fallback definitions for all of them. */ +#ifdef HAVE_SYS_CDEFS_H +# include +#endif + +#ifndef __BEGIN_DECLS +# ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# else +# define __BEGIN_DECLS /* nothing */ +# endif +#endif +#ifndef __END_DECLS +# ifdef __cplusplus +# define __END_DECLS } +# else +# define __END_DECLS /* nothing */ +# endif +#endif + +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_VERSION__ +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + +#ifndef __THROW +# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major__ >= 4) +# if __cplusplus >= 201103L +# define __THROW noexcept (true) +# else +# define __THROW throw () +# endif +# else +# define __THROW +# endif +#endif + +#endif /* _GETOPT_CDEFS_H */ diff --git a/cpp/third_party/xz-5.8.3/lib/getopt-core.h b/cpp/third_party/xz-5.8.3/lib/getopt-core.h new file mode 100644 index 000000000..126ce8089 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt-core.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* Declarations for getopt (basic, portable features only). + Copyright (C) 1989-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + The GNU C Library 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. + + The GNU C Library 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 the GNU C Library; if not, see + . */ + +#ifndef _GETOPT_CORE_H +#define _GETOPT_CORE_H 1 + +/* This header should not be used directly; include getopt.h or + unistd.h instead. Unlike most bits headers, it does not have + a protective #error, because the guard macro for getopt.h in + gnulib is not fixed. */ + +__BEGIN_DECLS + +/* For communication from 'getopt' to the caller. + When 'getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when 'ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to 'getopt'. + + On entry to 'getopt', zero means this is the first call; initialize. + + When 'getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, 'optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message 'getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, 'optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in 'optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU 'getopt'. + + The argument '--' causes premature termination of argument + scanning, explicitly telling 'getopt' that there are no more + options. + + If OPTS begins with '-', then non-option arguments are treated as + arguments to the option '\1'. This behavior is specific to the GNU + 'getopt'. If OPTS begins with '+', or POSIXLY_CORRECT is set in + the environment, then do not permute arguments. + + For standards compliance, the 'argv' argument has the type + char *const *, but this is inaccurate; if argument permutation is + enabled, the argv array (not the strings it points to) must be + writable. */ + +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) + __THROW _GL_ARG_NONNULL ((2, 3)); + +__END_DECLS + +#endif /* _GETOPT_CORE_H */ diff --git a/cpp/third_party/xz-5.8.3/lib/getopt-ext.h b/cpp/third_party/xz-5.8.3/lib/getopt-ext.h new file mode 100644 index 000000000..006037ba8 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt-ext.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* Declarations for getopt (GNU extensions). + Copyright (C) 1989-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + The GNU C Library 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. + + The GNU C Library 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 the GNU C Library; if not, see + . */ + +#ifndef _GETOPT_EXT_H +#define _GETOPT_EXT_H 1 + +/* This header should not be used directly; include getopt.h instead. + Unlike most bits headers, it does not have a protective #error, + because the guard macro for getopt.h in gnulib is not fixed. */ + +__BEGIN_DECLS + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of 'struct option' terminated by an element containing a name which is + zero. + + The field 'has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field 'flag' is not NULL, it points to a variable that is set + to the value given in the field 'val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an 'int' to + a compiled-in constant, such as set a value from 'optarg', set the + option's 'flag' field to zero and its 'val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero 'flag' field, 'getopt' + returns the contents of the 'val' field. */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the 'has_arg' field of 'struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW _GL_ARG_NONNULL ((2, 3)); +extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW _GL_ARG_NONNULL ((2, 3)); + +__END_DECLS + +#endif /* _GETOPT_EXT_H */ diff --git a/cpp/third_party/xz-5.8.3/lib/getopt-pfx-core.h b/cpp/third_party/xz-5.8.3/lib/getopt-pfx-core.h new file mode 100644 index 000000000..ee22d3f77 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt-pfx-core.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* getopt (basic, portable features) gnulib wrapper header. + Copyright (C) 1989-2023 Free Software Foundation, Inc. + This file is part of gnulib. + Unlike most of the getopt implementation, it is NOT shared + with the GNU C Library. + + This file 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. + + This file 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 this program. If not, see . */ + +#ifndef _GETOPT_PFX_CORE_H +#define _GETOPT_PFX_CORE_H 1 + +/* This header should not be used directly; include getopt.h or + unistd.h instead. It does not have a protective #error, because + the guard macro for getopt.h in gnulib is not fixed. */ + +/* Standalone applications should #define __GETOPT_PREFIX to an + identifier that prefixes the external functions and variables + defined in getopt-core.h and getopt-ext.h. Systematically + rename identifiers so that they do not collide with the system + functions and variables. Renaming avoids problems with some + compilers and linkers. */ +#ifdef __GETOPT_PREFIX +# ifndef __GETOPT_ID +# define __GETOPT_CONCAT(x, y) x ## y +# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) +# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) +# endif +# undef getopt +# undef optarg +# undef opterr +# undef optind +# undef optopt +# define getopt __GETOPT_ID (getopt) +# define optarg __GETOPT_ID (optarg) +# define opterr __GETOPT_ID (opterr) +# define optind __GETOPT_ID (optind) +# define optopt __GETOPT_ID (optopt) + +/* Work around a problem on macOS, which declares getopt with a + trailing __DARWIN_ALIAS(getopt) that would expand to something like + __asm("_" "rpl_getopt" "$UNIX2003") were it not for the following + hack to suppress the macOS declaration . */ +# ifdef __APPLE__ +# define _GETOPT +# endif + +/* The system's getopt.h may have already included getopt-core.h to + declare the unprefixed identifiers. Undef _GETOPT_CORE_H so that + getopt-core.h declares them with prefixes. */ +# undef _GETOPT_CORE_H +#endif + +#include + +#endif /* _GETOPT_PFX_CORE_H */ diff --git a/cpp/third_party/xz-5.8.3/lib/getopt-pfx-ext.h b/cpp/third_party/xz-5.8.3/lib/getopt-pfx-ext.h new file mode 100644 index 000000000..00d2a0952 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt-pfx-ext.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* getopt (GNU extensions) gnulib wrapper header. + Copyright (C) 1989-2023 Free Software Foundation, Inc. + This file is part of gnulib. + Unlike most of the getopt implementation, it is NOT shared + with the GNU C Library. + + This file 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. + + This file 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 this program. If not, see . */ + +#ifndef _GETOPT_PFX_EXT_H +#define _GETOPT_PFX_EXT_H 1 + +/* This header should not be used directly; include getopt.h instead. + It does not have a protective #error, because the guard macro for + getopt.h in gnulib is not fixed. */ + +/* Standalone applications should #define __GETOPT_PREFIX to an + identifier that prefixes the external functions and variables + defined in getopt-core.h and getopt-ext.h. Systematically + rename identifiers so that they do not collide with the system + functions and variables. Renaming avoids problems with some + compilers and linkers. */ +#ifdef __GETOPT_PREFIX +# ifndef __GETOPT_ID +# define __GETOPT_CONCAT(x, y) x ## y +# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) +# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) +# endif +# undef getopt_long +# undef getopt_long_only +# undef option +# undef _getopt_internal +# define getopt_long __GETOPT_ID (getopt_long) +# define getopt_long_only __GETOPT_ID (getopt_long_only) +# define option __GETOPT_ID (option) +# define _getopt_internal __GETOPT_ID (getopt_internal) + +/* The system's getopt.h may have already included getopt-ext.h to + declare the unprefixed identifiers. Undef _GETOPT_EXT_H so that + getopt-ext.h declares them with prefixes. */ +# undef _GETOPT_EXT_H +#endif + +/* Standalone applications get correct prototypes for getopt_long and + getopt_long_only; they declare "char **argv". For backward + compatibility with old applications, if __GETOPT_PREFIX is not + defined, we supply GNU-libc-compatible, but incorrect, prototypes + using "char *const *argv". (GNU libc is stuck with the incorrect + prototypes, as they are baked into older versions of LSB.) */ +#ifndef __getopt_argv_const +# if defined __GETOPT_PREFIX +# define __getopt_argv_const /* empty */ +# else +# define __getopt_argv_const const +# endif +#endif + +#include + +#endif /* _GETOPT_PFX_EXT_H */ diff --git a/cpp/third_party/xz-5.8.3/lib/getopt.c b/cpp/third_party/xz-5.8.3/lib/getopt.c new file mode 100644 index 000000000..ab3ff879c --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt.c @@ -0,0 +1,823 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* Getopt for GNU. + Copyright (C) 1987-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + The GNU C Library 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. + + The GNU C Library 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 the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# ifdef HAVE_CONFIG_H +# include +# endif +#endif + +#include "getopt.h" + +#include +#include +#include +#ifndef _MSC_VER +# include +#endif + +#ifdef _LIBC +/* When used as part of glibc, error printing must be done differently + for standards compliance. getopt is not a cancellation point, so + it must not call functions that are, and it is specified by an + older standard than stdio locking, so it must not refer to + functions in the "user namespace" related to stdio locking. + Finally, it must use glibc's internal message translation so that + the messages are looked up in the proper text domain. */ +# include +# define fprintf __fxprintf_nocancel +# define flockfile(fp) _IO_flockfile (fp) +# define funlockfile(fp) _IO_funlockfile (fp) +#else +/* Completely disable NLS for getopt. We won't include translations for it + anyway. If the system lacks getopt_long, missing translations probably + aren't a problem. */ +//# include "gettext.h" +//# define _(msgid) gettext (msgid) +#define _(msgid) (msgid) +/* When used standalone, flockfile and funlockfile might not be + available. */ +# if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \ + || (defined _WIN32 && ! defined __CYGWIN__)) +# define flockfile(fp) /* nop */ +# define funlockfile(fp) /* nop */ +# endif +/* When used standalone, do not attempt to use alloca. */ +# define __libc_use_alloca(size) 0 +# undef alloca +# define alloca(size) (abort (), (void *)0) +#endif + +/* This implementation of 'getopt' has three modes for handling + options interspersed with non-option arguments. It can stop + scanning for options at the first non-option argument encountered, + as POSIX specifies. It can continue scanning for options after the + first non-option argument, but permute 'argv' as it goes so that, + after 'getopt' is done, all the options precede all the non-option + arguments and 'optind' points to the first non-option argument. + Or, it can report non-option arguments as if they were arguments to + the option character '\x01'. + + The default behavior of 'getopt_long' is to permute the argument list. + When this implementation is used standalone, the default behavior of + 'getopt' is to stop at the first non-option argument, but when it is + used as part of GNU libc it also permutes the argument list. In both + cases, setting the environment variable POSIXLY_CORRECT to any value + disables permutation. + + If the first character of the OPTSTRING argument to 'getopt' or + 'getopt_long' is '+', both functions will stop at the first + non-option argument. If it is '-', both functions will report + non-option arguments as arguments to the option character '\x01'. */ + +#include "getopt_int.h" + +/* For communication from 'getopt' to the caller. + When 'getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when 'ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to 'getopt'. + + On entry to 'getopt', zero means this is the first call; initialize. + + When 'getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, 'optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Keep a global copy of all internal members of getopt_data. */ + +static struct _getopt_data getopt_data; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + 'first_nonopt' and 'last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange (char **argv, struct _getopt_data *d) +{ + int bottom = d->__first_nonopt; + int middle = d->__last_nonopt; + int top = d->optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + d->__first_nonopt += (d->optind - d->__last_nonopt); + d->__last_nonopt = d->optind; +} + +/* Process the argument starting with d->__nextchar as a long option. + d->optind should *not* have been advanced over this argument. + + If the value returned is -1, it was not actually a long option, the + state is unchanged, and the argument should be processed as a set + of short options (this can only happen when long_only is true). + Otherwise, the option (and its argument, if any) have been consumed + and the return value is the value to return from _getopt_internal_r. */ +static int +process_long_option (int argc, char **argv, const char *optstring, + const struct option *longopts, int *longind, + int long_only, struct _getopt_data *d, + int print_errors, const char *prefix) +{ + char *nameend; + size_t namelen; + const struct option *p; + const struct option *pfound = NULL; + int n_options; + int option_index; + + for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + namelen = (size_t)(nameend - d->__nextchar); + + /* First look for an exact match, counting the options as a side + effect. */ + for (p = longopts, n_options = 0; p->name; p++, n_options++) + if (!strncmp (p->name, d->__nextchar, namelen) + && namelen == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + option_index = n_options; + break; + } + + if (pfound == NULL) + { + /* Didn't find an exact match, so look for abbreviations. */ + unsigned char *ambig_set = NULL; + int ambig_malloced = 0; + int ambig_fallback = 0; + int indfound = -1; + + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, namelen)) + { + if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + { + /* Second or later nonexact match found. */ + if (!ambig_fallback) + { + if (!print_errors) + /* Don't waste effort tracking the ambig set if + we're not going to print it anyway. */ + ambig_fallback = 1; + else if (!ambig_set) + { + if (__libc_use_alloca (n_options)) + ambig_set = alloca (n_options); + else if ((ambig_set = malloc ((size_t)n_options)) == NULL) + /* Fall back to simpler error message. */ + ambig_fallback = 1; + else + ambig_malloced = 1; + + if (ambig_set) + { + memset (ambig_set, 0, (size_t)n_options); + ambig_set[indfound] = 1; + } + } + if (ambig_set) + ambig_set[option_index] = 1; + } + } + } + + if (ambig_set || ambig_fallback) + { + if (print_errors) + { + if (ambig_fallback) + fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"), + argv[0], prefix, d->__nextchar); + else + { + flockfile (stderr); + fprintf (stderr, + _("%s: option '%s%s' is ambiguous; possibilities:"), + argv[0], prefix, d->__nextchar); + + for (option_index = 0; option_index < n_options; option_index++) + if (ambig_set[option_index]) + fprintf (stderr, " '%s%s'", + prefix, longopts[option_index].name); + + /* This must use 'fprintf' even though it's only + printing a single character, so that it goes through + __fxprintf_nocancel when compiled as part of glibc. */ + fprintf (stderr, "\n"); + funlockfile (stderr); + } + } + if (ambig_malloced) + free (ambig_set); + d->__nextchar += strlen (d->__nextchar); + d->optind++; + d->optopt = 0; + return '?'; + } + + option_index = indfound; + } + + if (pfound == NULL) + { + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short option, + then it's an error. */ + if (!long_only || argv[d->optind][1] == '-' + || strchr (optstring, *d->__nextchar) == NULL) + { + if (print_errors) + fprintf (stderr, _("%s: unrecognized option '%s%s'\n"), + argv[0], prefix, d->__nextchar); + + d->__nextchar = NULL; + d->optind++; + d->optopt = 0; + return '?'; + } + + /* Otherwise interpret it as a short option. */ + return -1; + } + + /* We have found a matching long option. Consume it. */ + d->optind++; + d->__nextchar = NULL; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option '%s%s' doesn't allow an argument\n"), + argv[0], prefix, pfound->name); + + d->optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option '%s%s' requires an argument\n"), + argv[0], prefix, pfound->name); + + d->optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; +} + +/* Initialize internal data upon the first call to getopt. */ + +static const char * +_getopt_initialize (int argc, + char **argv, const char *optstring, + struct _getopt_data *d, int posixly_correct) +{ + (void)argc; + (void)argv; + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + if (d->optind == 0) + d->optind = 1; + + d->__first_nonopt = d->__last_nonopt = d->optind; + d->__nextchar = NULL; + + /* Determine how to handle the ordering of options and nonoptions. */ + if (optstring[0] == '-') + { + d->__ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + d->__ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct || !!getenv ("POSIXLY_CORRECT")) + d->__ordering = REQUIRE_ORDER; + else + d->__ordering = PERMUTE; + + d->__initialized = 1; + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If 'getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If 'getopt' finds another option character, it returns that character, + updating 'optind' and 'nextchar' so that the next call to 'getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, 'getopt' returns -1. + Then 'optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set 'opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in 'optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in 'optarg', otherwise 'optarg' is set to zero. + + If OPTSTRING starts with '-' or '+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with '--' instead of '-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a '=', or else the in next ARGV-element. + When 'getopt' finds a long-named option, it returns 0 if that option's + 'flag' field is nonzero, the value of the option's 'val' field + if the 'flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of 'struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal_r (int argc, char **argv, const char *optstring, + const struct option *longopts, int *longind, + int long_only, struct _getopt_data *d, int posixly_correct) +{ + int print_errors = d->opterr; + + if (argc < 1) + return -1; + + d->optarg = NULL; + + if (d->optind == 0 || !d->__initialized) + optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct); + else if (optstring[0] == '-' || optstring[0] == '+') + optstring++; + + if (optstring[0] == ':') + print_errors = 0; + + /* Test whether ARGV[optind] points to a non-option argument. */ +#define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') + + if (d->__nextchar == NULL || *d->__nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (d->__last_nonopt > d->optind) + d->__last_nonopt = d->optind; + if (d->__first_nonopt > d->optind) + d->__first_nonopt = d->optind; + + if (d->__ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange (argv, d); + else if (d->__last_nonopt != d->optind) + d->__first_nonopt = d->optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (d->optind < argc && NONOPTION_P) + d->optind++; + d->__last_nonopt = d->optind; + } + + /* The special ARGV-element '--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (d->optind != argc && !strcmp (argv[d->optind], "--")) + { + d->optind++; + + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange (argv, d); + else if (d->__first_nonopt == d->__last_nonopt) + d->__first_nonopt = d->optind; + d->__last_nonopt = argc; + + d->optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (d->optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (d->__first_nonopt != d->__last_nonopt) + d->optind = d->__first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (d->__ordering == REQUIRE_ORDER) + return -1; + d->optarg = argv[d->optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Check whether it might be a long option. */ + if (longopts) + { + if (argv[d->optind][1] == '-') + { + /* "--foo" is always a long option. The special option + "--" was handled above. */ + d->__nextchar = argv[d->optind] + 2; + return process_long_option (argc, argv, optstring, longopts, + longind, long_only, d, + print_errors, "--"); + } + + /* If long_only and the ARGV-element has the form "-f", + where f is a valid short option, don't consider it an + abbreviated form of a long option that starts with f. + Otherwise there would be no way to give the -f short + option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an + abbreviation of the long option, just like "--fu", and + not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + if (long_only && (argv[d->optind][2] + || !strchr (optstring, argv[d->optind][1]))) + { + int code; + d->__nextchar = argv[d->optind] + 1; + code = process_long_option (argc, argv, optstring, longopts, + longind, long_only, d, + print_errors, "-"); + if (code != -1) + return code; + } + } + + /* It is not a long option. Skip the initial punctuation. */ + d->__nextchar = argv[d->optind] + 1; + } + + /* Look at and handle the next short option-character. */ + + { + char c = *d->__nextchar++; + const char *temp = strchr (optstring, c); + + /* Increment 'optind' when we start to process its last character. */ + if (*d->__nextchar == '\0') + ++d->optind; + + if (temp == NULL || c == ':' || c == ';') + { + if (print_errors) + fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); + d->optopt = c; + return '?'; + } + + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL) + { + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + d->optarg = d->__nextchar; + else if (d->optind == argc) + { + if (print_errors) + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); + + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + d->optarg = argv[d->optind]; + + d->__nextchar = d->optarg; + d->optarg = NULL; + return process_long_option (argc, argv, optstring, longopts, longind, + 0 /* long_only */, d, print_errors, "-W "); + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + d->optind++; + } + else + d->optarg = NULL; + d->__nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); + + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented 'optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + d->__nextchar = NULL; + } + } + return c; + } +} + +int +_getopt_internal (int argc, char **argv, const char *optstring, + const struct option *longopts, int *longind, int long_only, + int posixly_correct) +{ + int result; + + getopt_data.optind = optind; + getopt_data.opterr = opterr; + + result = _getopt_internal_r (argc, argv, optstring, longopts, + longind, long_only, &getopt_data, + posixly_correct); + + optind = getopt_data.optind; + optarg = getopt_data.optarg; + optopt = getopt_data.optopt; + + return result; +} + +/* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt. + Standalone applications just get a POSIX-compliant getopt. + POSIX and LSB both require these functions to take 'char *const *argv' + even though this is incorrect (because of the permutation). */ +#define GETOPT_ENTRY(NAME, POSIXLY_CORRECT) \ + int \ + NAME (int argc, char *const *argv, const char *optstring) \ + { \ + return _getopt_internal (argc, (char **)argv, optstring, \ + 0, 0, 0, POSIXLY_CORRECT); \ + } + +#ifdef _LIBC +GETOPT_ENTRY(getopt, 0) +GETOPT_ENTRY(__posix_getopt, 1) +#else +GETOPT_ENTRY(getopt, 1) +#endif + + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of 'getopt'. */ + +int +main (int argc, char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value '%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/cpp/third_party/xz-5.8.3/lib/getopt.in.h b/cpp/third_party/xz-5.8.3/lib/getopt.in.h new file mode 100644 index 000000000..6d602c5da --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt.in.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* Declarations for getopt. + Copyright (C) 1989-2023 Free Software Foundation, Inc. + This file is part of gnulib. + Unlike most of the getopt implementation, it is NOT shared + with the GNU C Library, which supplies a different version of + this file. + + This file 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. + + This file 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 this program. If not, see . */ + +#ifndef _GETOPT_H + +#define _GETOPT_H 1 + +/* Standalone applications should #define __GETOPT_PREFIX to an + identifier that prefixes the external functions and variables + defined in this header. When this happens, include the + headers that might declare getopt so that they will not cause + confusion if included after this file. Then systematically rename + identifiers so that they do not collide with the system functions + and variables. Renaming avoids problems with some compilers and + linkers. */ +#if defined __GETOPT_PREFIX +# include +# include + +# ifndef _MSC_VER +# include +# endif +#endif + +/* From Gnulib's lib/arg-nonnull.h: */ +/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools + that the values passed as arguments n, ..., m must be non-NULL pointers. + n = 1 stands for the first argument, n = 2 for the second argument etc. */ +#ifndef _GL_ARG_NONNULL +# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__ +# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) +# else +# define _GL_ARG_NONNULL(params) +# endif +#endif + +#include +#include +#include + +#endif /* _GETOPT_H */ diff --git a/cpp/third_party/xz-5.8.3/lib/getopt1.c b/cpp/third_party/xz-5.8.3/lib/getopt1.c new file mode 100644 index 000000000..5cb3b913d --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt1.c @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + The GNU C Library 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. + + The GNU C Library 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 the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# ifdef HAVE_CONFIG_H +# include +# endif +#endif + +#include "getopt.h" +#include "getopt_int.h" + +int +getopt_long (int argc, char *__getopt_argv_const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return _getopt_internal (argc, (char **) argv, options, long_options, + opt_index, 0, 0); +} + +int +_getopt_long_r (int argc, char **argv, const char *options, + const struct option *long_options, int *opt_index, + struct _getopt_data *d) +{ + return _getopt_internal_r (argc, argv, options, long_options, opt_index, + 0, d, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (int argc, char *__getopt_argv_const *argv, + const char *options, + const struct option *long_options, int *opt_index) +{ + return _getopt_internal (argc, (char **) argv, options, long_options, + opt_index, 1, 0); +} + +int +_getopt_long_only_r (int argc, char **argv, const char *options, + const struct option *long_options, int *opt_index, + struct _getopt_data *d) +{ + return _getopt_internal_r (argc, argv, options, long_options, opt_index, + 1, d, 0); +} + + +#ifdef TEST + +#include +#include + +int +main (int argc, char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static const struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value '%s'\n", optarg); + break; + + case 'd': + printf ("option d with value '%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/cpp/third_party/xz-5.8.3/lib/getopt_int.h b/cpp/third_party/xz-5.8.3/lib/getopt_int.h new file mode 100644 index 000000000..2dcb55382 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/lib/getopt_int.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* Internal declarations for getopt. + Copyright (C) 1989-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + The GNU C Library 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. + + The GNU C Library 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 the GNU C Library; if not, see + . */ + +#ifndef _GETOPT_INT_H +#define _GETOPT_INT_H 1 + +#include + +extern int _getopt_internal (int ___argc, char **___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, int __posixly_correct); + + +/* Reentrant versions which can handle parsing multiple argument + vectors at the same time. */ + +/* Describe how to deal with options that follow non-option ARGV-elements. + + REQUIRE_ORDER means don't recognize them as options; stop option + processing when the first non-option is seen. This is what POSIX + specifies should happen. + + PERMUTE means permute the contents of ARGV as we scan, so that + eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written + to expect this. + + RETURN_IN_ORDER is an option available to programs that were + written to expect options and other ARGV-elements in any order + and that care about the ordering of the two. We describe each + non-option ARGV-element as if it were the argument of an option + with character code 1. + + The special argument '--' forces an end of option-scanning regardless + of the value of 'ordering'. In the case of RETURN_IN_ORDER, only + '--' can cause 'getopt' to return -1 with 'optind' != ARGC. */ + +enum __ord + { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER + }; + +/* Data type for reentrant functions. */ +struct _getopt_data +{ + /* These have exactly the same meaning as the corresponding global + variables, except that they are used for the reentrant + versions of getopt. */ + int optind; + int opterr; + int optopt; + char *optarg; + + /* Internal members. */ + + /* True if the internal members have been initialized. */ + int __initialized; + + /* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + char *__nextchar; + + /* See __ord above. */ + enum __ord __ordering; + + /* Handle permutation of arguments. */ + + /* Describe the part of ARGV that contains non-options that have + been skipped. 'first_nonopt' is the index in ARGV of the first + of them; 'last_nonopt' is the index after the last of them. */ + + int __first_nonopt; + int __last_nonopt; +}; + +/* The initializer is necessary to set OPTIND and OPTERR to their + default values and to clear the initialization flag. */ +#define _GETOPT_DATA_INITIALIZER { 1, 1 } + +extern int _getopt_internal_r (int ___argc, char **___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, struct _getopt_data *__data, + int __posixly_correct); + +extern int _getopt_long_r (int ___argc, char **___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + struct _getopt_data *__data); + +extern int _getopt_long_only_r (int ___argc, char **___argv, + const char *__shortopts, + const struct option *__longopts, + int *__longind, + struct _getopt_data *__data); + +#endif /* getopt_int.h */ diff --git a/cpp/third_party/xz-5.8.3/m4/ax_pthread.m4 b/cpp/third_party/xz-5.8.3/m4/ax_pthread.m4 new file mode 100644 index 000000000..3f26da626 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/ax_pthread.m4 @@ -0,0 +1,524 @@ +dnl SPDX-License-Identifier: GPL-3.0-or-later WITH Autoconf-exception-macro + +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is +# needed for multi-threaded programs (defaults to the value of CC +# respectively CXX otherwise). (This is necessary on e.g. AIX to use the +# special cc_r/CC_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also to link with them as well. For example, you might link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threaded programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# CXX="$PTHREAD_CXX" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# Copyright (c) 2019 Marc Stevens +# +# 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 31 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" + ;; +esac + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) + +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) + + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + + + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [ + AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) + AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) + ], + [ + AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) + AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) + ] + ) + ]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" +test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) +AC_SUBST([PTHREAD_CXX]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/cpp/third_party/xz-5.8.3/m4/build-to-host.m4 b/cpp/third_party/xz-5.8.3/m4/build-to-host.m4 new file mode 100644 index 000000000..d13649e0c --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/build-to-host.m4 @@ -0,0 +1,274 @@ +# build-to-host.m4 +# serial 5 +dnl Copyright (C) 2023-2024 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 This file is offered as-is, without any warranty. + +dnl Written by Bruno Haible. + +dnl When the build environment ($build_os) is different from the target runtime +dnl environment ($host_os), file names may need to be converted from the build +dnl environment syntax to the target runtime environment syntax. This is +dnl because the Makefiles are executed (mostly) by build environment tools and +dnl therefore expect file names in build environment syntax, whereas the runtime +dnl expects file names in target runtime environment syntax. +dnl +dnl For example, if $build_os = cygwin and $host_os = mingw32, filenames need +dnl be converted from Cygwin syntax to native Windows syntax: +dnl /cygdrive/c/foo/bar -> C:\foo\bar +dnl /usr/local/share -> C:\cygwin64\usr\local\share +dnl +dnl gl_BUILD_TO_HOST([somedir]) +dnl This macro takes as input an AC_SUBSTed variable 'somedir', which must +dnl already have its final value assigned, and produces two additional +dnl AC_SUBSTed variables 'somedir_c' and 'somedir_c_make', that designate the +dnl same file name value, just in different syntax: +dnl - somedir_c is the file name in target runtime environment syntax, +dnl as a C string (starting and ending with a double-quote, +dnl and with escaped backslashes and double-quotes in +dnl between). +dnl - somedir_c_make is the same thing, escaped for use in a Makefile. + +AC_DEFUN([gl_BUILD_TO_HOST], +[ + AC_REQUIRE([AC_CANONICAL_BUILD]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_BUILD_TO_HOST_INIT]) + + dnl Define somedir_c. + gl_final_[$1]="$[$1]" + dnl Translate it from build syntax to host syntax. + case "$build_os" in + cygwin*) + case "$host_os" in + mingw* | windows*) + gl_final_[$1]=`cygpath -w "$gl_final_[$1]"` ;; + esac + ;; + esac + dnl Convert it to C string syntax. + [$1]_c=`printf '%s\n' "$gl_final_[$1]" | sed -e "$gl_sed_double_backslashes" -e "$gl_sed_escape_doublequotes" | tr -d "$gl_tr_cr"` + [$1]_c='"'"$[$1]_c"'"' + AC_SUBST([$1_c]) + + dnl Define somedir_c_make. + [$1]_c_make=`printf '%s\n' "$[$1]_c" | sed -e "$gl_sed_escape_for_make_1" -e "$gl_sed_escape_for_make_2" | tr -d "$gl_tr_cr"` + dnl Use the substituted somedir variable, when possible, so that the user + dnl may adjust somedir a posteriori when there are no special characters. + if test "$[$1]_c_make" = '\"'"${gl_final_[$1]}"'\"'; then + [$1]_c_make='\"$([$1])\"' + fi + AC_SUBST([$1_c_make]) +]) + +dnl Some initializations for gl_BUILD_TO_HOST. +AC_DEFUN([gl_BUILD_TO_HOST_INIT], +[ + gl_sed_double_backslashes='s/\\/\\\\/g' + gl_sed_escape_doublequotes='s/"/\\"/g' +changequote(,)dnl + gl_sed_escape_for_make_1="s,\\([ \"&'();<>\\\\\`|]\\),\\\\\\1,g" +changequote([,])dnl + gl_sed_escape_for_make_2='s,\$,\\$$,g' + dnl Find out how to remove carriage returns from output. Solaris /usr/ucb/tr + dnl does not understand '\r'. + case `echo r | tr -d '\r'` in + '') gl_tr_cr='\015' ;; + *) gl_tr_cr='\r' ;; + esac +]) + + +dnl The following macros are convenience invocations of gl_BUILD_TO_HOST +dnl for some of the variables that are defined by Autoconf. +dnl To do so for _all_ the possible variables, use the module 'configmake'. + +dnl Defines bindir_c and bindir_c_make. +AC_DEFUN_ONCE([gl_BUILD_TO_HOST_BINDIR], +[ + dnl Find the final value of bindir. + gl_saved_prefix="${prefix}" + gl_saved_exec_prefix="${exec_prefix}" + gl_saved_bindir="${bindir}" + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + prefix="$ac_default_prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + exec_prefix='${prefix}' + fi + eval exec_prefix="$exec_prefix" + eval bindir="$bindir" + gl_BUILD_TO_HOST([bindir]) + bindir="${gl_saved_bindir}" + exec_prefix="${gl_saved_exec_prefix}" + prefix="${gl_saved_prefix}" +]) + +dnl Defines datadir_c and datadir_c_make, +dnl where datadir = $(datarootdir) +AC_DEFUN_ONCE([gl_BUILD_TO_HOST_DATADIR], +[ + dnl Find the final value of datadir. + gl_saved_prefix="${prefix}" + gl_saved_datarootdir="${datarootdir}" + gl_saved_datadir="${datadir}" + dnl Unfortunately, prefix gets only finally determined at the end of + dnl configure. + if test "X$prefix" = "XNONE"; then + prefix="$ac_default_prefix" + fi + eval datarootdir="$datarootdir" + eval datadir="$datadir" + gl_BUILD_TO_HOST([datadir]) + datadir="${gl_saved_datadir}" + datarootdir="${gl_saved_datarootdir}" + prefix="${gl_saved_prefix}" +]) + +dnl Defines libdir_c and libdir_c_make. +AC_DEFUN_ONCE([gl_BUILD_TO_HOST_LIBDIR], +[ + dnl Find the final value of libdir. + gl_saved_prefix="${prefix}" + gl_saved_exec_prefix="${exec_prefix}" + gl_saved_libdir="${libdir}" + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + prefix="$ac_default_prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + exec_prefix='${prefix}' + fi + eval exec_prefix="$exec_prefix" + eval libdir="$libdir" + gl_BUILD_TO_HOST([libdir]) + libdir="${gl_saved_libdir}" + exec_prefix="${gl_saved_exec_prefix}" + prefix="${gl_saved_prefix}" +]) + +dnl Defines libexecdir_c and libexecdir_c_make. +AC_DEFUN_ONCE([gl_BUILD_TO_HOST_LIBEXECDIR], +[ + dnl Find the final value of libexecdir. + gl_saved_prefix="${prefix}" + gl_saved_exec_prefix="${exec_prefix}" + gl_saved_libexecdir="${libexecdir}" + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + prefix="$ac_default_prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + exec_prefix='${prefix}' + fi + eval exec_prefix="$exec_prefix" + eval libexecdir="$libexecdir" + gl_BUILD_TO_HOST([libexecdir]) + libexecdir="${gl_saved_libexecdir}" + exec_prefix="${gl_saved_exec_prefix}" + prefix="${gl_saved_prefix}" +]) + +dnl Defines localedir_c and localedir_c_make. +AC_DEFUN_ONCE([gl_BUILD_TO_HOST_LOCALEDIR], +[ + dnl Find the final value of localedir. + gl_saved_prefix="${prefix}" + gl_saved_datarootdir="${datarootdir}" + gl_saved_localedir="${localedir}" + dnl Unfortunately, prefix gets only finally determined at the end of + dnl configure. + if test "X$prefix" = "XNONE"; then + prefix="$ac_default_prefix" + fi + eval datarootdir="$datarootdir" + eval localedir="$localedir" + gl_BUILD_TO_HOST([localedir]) + localedir="${gl_saved_localedir}" + datarootdir="${gl_saved_datarootdir}" + prefix="${gl_saved_prefix}" +]) + +dnl Defines pkgdatadir_c and pkgdatadir_c_make, +dnl where pkgdatadir = $(datadir)/$(PACKAGE) +AC_DEFUN_ONCE([gl_BUILD_TO_HOST_PKGDATADIR], +[ + dnl Find the final value of pkgdatadir. + gl_saved_prefix="${prefix}" + gl_saved_datarootdir="${datarootdir}" + gl_saved_datadir="${datadir}" + gl_saved_pkgdatadir="${pkgdatadir}" + dnl Unfortunately, prefix gets only finally determined at the end of + dnl configure. + if test "X$prefix" = "XNONE"; then + prefix="$ac_default_prefix" + fi + eval datarootdir="$datarootdir" + eval datadir="$datadir" + eval pkgdatadir="$pkgdatadir" + gl_BUILD_TO_HOST([pkgdatadir]) + pkgdatadir="${gl_saved_pkgdatadir}" + datadir="${gl_saved_datadir}" + datarootdir="${gl_saved_datarootdir}" + prefix="${gl_saved_prefix}" +]) + +dnl Defines pkglibdir_c and pkglibdir_c_make, +dnl where pkglibdir = $(libdir)/$(PACKAGE) +AC_DEFUN_ONCE([gl_BUILD_TO_HOST_PKGLIBDIR], +[ + dnl Find the final value of pkglibdir. + gl_saved_prefix="${prefix}" + gl_saved_exec_prefix="${exec_prefix}" + gl_saved_libdir="${libdir}" + gl_saved_pkglibdir="${pkglibdir}" + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + prefix="$ac_default_prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + exec_prefix='${prefix}' + fi + eval exec_prefix="$exec_prefix" + eval libdir="$libdir" + eval pkglibdir="$pkglibdir" + gl_BUILD_TO_HOST([pkglibdir]) + pkglibdir="${gl_saved_pkglibdir}" + libdir="${gl_saved_libdir}" + exec_prefix="${gl_saved_exec_prefix}" + prefix="${gl_saved_prefix}" +]) + +dnl Defines pkglibexecdir_c and pkglibexecdir_c_make, +dnl where pkglibexecdir = $(libexecdir)/$(PACKAGE) +AC_DEFUN_ONCE([gl_BUILD_TO_HOST_PKGLIBEXECDIR], +[ + dnl Find the final value of pkglibexecdir. + gl_saved_prefix="${prefix}" + gl_saved_exec_prefix="${exec_prefix}" + gl_saved_libexecdir="${libexecdir}" + gl_saved_pkglibexecdir="${pkglibexecdir}" + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + prefix="$ac_default_prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + exec_prefix='${prefix}' + fi + eval exec_prefix="$exec_prefix" + eval libexecdir="$libexecdir" + eval pkglibexecdir="$pkglibexecdir" + gl_BUILD_TO_HOST([pkglibexecdir]) + pkglibexecdir="${gl_saved_pkglibexecdir}" + libexecdir="${gl_saved_libexecdir}" + exec_prefix="${gl_saved_exec_prefix}" + prefix="${gl_saved_prefix}" +]) diff --git a/cpp/third_party/xz-5.8.3/m4/getopt.m4 b/cpp/third_party/xz-5.8.3/m4/getopt.m4 new file mode 100644 index 000000000..9d9141b28 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/getopt.m4 @@ -0,0 +1,70 @@ +dnl SPDX-License-Identifier: FSFULLR + +# getopt.m4 serial 49 (modified version) +dnl Copyright (C) 2002-2006, 2008-2023 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. + +# This version has been modified to reduce complexity since we only need +# GNU getopt_long and do not care about replacing getopt. +# +# Pass gl_replace_getopt=yes (or any non-empty value instead of "yes") as +# an argument to configure to force the use of the getopt_long replacement. + +AC_DEFUN([gl_FUNC_GETOPT_GNU], +[ + AC_REQUIRE([gl_GETOPT_CHECK_HEADERS]) + + if test -n "$gl_replace_getopt"; then + gl_GETOPT_SUBSTITUTE + fi +]) + +AC_DEFUN([gl_GETOPT_CHECK_HEADERS], +[ + if test -z "$gl_replace_getopt"; then + AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes]) + fi + + if test -z "$gl_replace_getopt"; then + AC_CHECK_FUNCS([getopt_long], [], [gl_replace_getopt=yes]) + fi + + dnl BSD getopt_long uses a way to reset option processing, that is different + dnl from GNU and Solaris (which copied the GNU behavior). We support both + dnl GNU and BSD style resetting of getopt_long(), so there's no need to use + dnl GNU getopt_long() on BSD due to different resetting style. + if test -z "$gl_replace_getopt"; then + AC_CHECK_DECL([optreset], + [AC_DEFINE([HAVE_OPTRESET], 1, + [Define to 1 if getopt.h declares extern int optreset.])], + [], [#include ]) + fi + + dnl POSIX 2008 does not specify leading '+' behavior, but see + dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on + dnl the next version of POSIX. We don't use that feature, so this + dnl is not a problem for us. Thus, the respective test was removed here. + + dnl Checks for getopt handling '-' as a leading character in an option + dnl string were removed, since we also don't use that feature. + +]) + +AC_DEFUN([gl_GETOPT_SUBSTITUTE], +[ + AC_LIBOBJ([getopt]) + AC_LIBOBJ([getopt1]) + + AC_CHECK_HEADERS_ONCE([sys/cdefs.h]) + + AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], + [Define to rpl_ if the getopt replacement functions and variables + should be used.]) + + GETOPT_H=getopt.h + AC_SUBST([GETOPT_H]) +]) + +AC_DEFUN([gl_GETOPT], [gl_FUNC_GETOPT_GNU]) diff --git a/cpp/third_party/xz-5.8.3/m4/gettext.m4 b/cpp/third_party/xz-5.8.3/m4/gettext.m4 new file mode 100644 index 000000000..d6a98efbf --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/gettext.m4 @@ -0,0 +1,392 @@ +# gettext.m4 +# serial 81 (gettext-0.23) +dnl Copyright (C) 1995-2014, 2016, 2018-2024 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 +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2024. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL must be one of 'external', 'use-libtool', 'here'. +dnl INTLSYMBOL should be 'external' for packages other than GNU gettext. +dnl It should be 'use-libtool' for the packages 'gettext-runtime' and +dnl 'gettext-tools'. +dnl It should be 'here' for the package 'gettext-runtime/intl'. +dnl If INTLSYMBOL is 'here', then a libtool library +dnl $(top_builddir)/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value '$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + m4_if([$1], [], , [m4_if([$1], [external], , [m4_if([$1], [use-libtool], , [m4_if([$1], [here], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + m4_if(m4_if([$1], [], [old])[]m4_if([$1], [no-libtool], [old]), [old], + [errprint([ERROR: Use of AM_GNU_GETTEXT without [external] argument is no longer supported. +])]) + m4_if([$2], [], , [m4_if([$2], [need-ngettext], , [m4_if([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define([gt_building_libintl_in_same_build_tree], + m4_if([$1], [use-libtool], [yes], [m4_if([$1], [here], [yes], [no])])) + gt_NEEDS_INIT + AM_GNU_GETTEXT_NEED([$2]) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl tests. But if configure.ac invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is not documented, we avoid it. + m4_if(gt_building_libintl_in_same_build_tree, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation. + gt_INTL_MACOSX + + dnl Set USE_NLS. + AC_REQUIRE([AM_NLS]) + + m4_if(gt_building_libintl_in_same_build_tree, yes, [ + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl Add a version number to the cache macros. + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + m4_if(gt_building_libintl_in_same_build_tree, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH([included-gettext], + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext]) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [eval "$gt_func_gnugettext_libc=yes"], + [eval "$gt_func_gnugettext_libc=no"])]) + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + m4_if(gt_building_libintl_in_same_build_tree, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + [$gt_func_gnugettext_libintl], + [gt_saved_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_saved_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [eval "$gt_func_gnugettext_libintl=yes"], + [eval "$gt_func_gnugettext_libintl=no"]) + dnl Now see whether libintl exists and depends on libiconv or other + dnl OS dependent libraries, specifically on macOS and AIX. + gt_LIBINTL_EXTRA="$INTL_MACOSX_LIBS" + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + aix*) gt_LIBINTL_EXTRA="-lpthread" ;; + esac + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } \ + && { test -n "$LIBICONV" || test -n "$gt_LIBINTL_EXTRA"; }; then + LIBS="$LIBS $LIBICONV $gt_LIBINTL_EXTRA" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [LIBINTL="$LIBINTL $LIBICONV $gt_LIBINTL_EXTRA" + LTLIBINTL="$LTLIBINTL $LTLIBICONV $gt_LIBINTL_EXTRA" + eval "$gt_func_gnugettext_libintl=yes" + ]) + fi + CPPFLAGS="$gt_saved_CPPFLAGS" + LIBS="$gt_saved_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools \ + && test "$PACKAGE" != libintl; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + m4_if(gt_building_libintl_in_same_build_tree, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + USE_INCLUDED_LIBINTL=yes + LIBINTL="m4_if([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LIBICONV $LIBTHREAD" + LTLIBINTL="m4_if([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LTLIBICONV $LTLIBTHREAD" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + CATOBJEXT= + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Some extra flags are needed during linking. + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE([ENABLE_NLS], [1], + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + AC_MSG_CHECKING([whether to use NLS]) + AC_MSG_RESULT([$USE_NLS]) + if test "$USE_NLS" = "yes"; then + AC_MSG_CHECKING([where the gettext function comes from]) + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + AC_MSG_RESULT([$gt_source]) + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE([HAVE_GETTEXT], [1], + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE([HAVE_DCGETTEXT], [1], + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + m4_if(gt_building_libintl_in_same_build_tree, yes, [ + dnl Make all variables we use known to autoconf. + AC_SUBST([USE_INCLUDED_LIBINTL]) + AC_SUBST([CATOBJEXT]) + ]) + + m4_if(gt_building_libintl_in_same_build_tree, yes, [], [ + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST([INTLLIBS]) + ]) + + dnl Make all documented variables known to autoconf. + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + AC_SUBST([POSUB]) + + dnl Define localedir_c and localedir_c_make. + gl_BUILD_TO_HOST_LOCALEDIR +]) + + +dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. +m4_define([gt_NEEDS_INIT], +[ + m4_divert_text([DEFAULTS], [gt_needs=]) + m4_define([gt_NEEDS_INIT], []) +]) + + +dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) +AC_DEFUN([AM_GNU_GETTEXT_NEED], +[ + m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) + + +dnl Usage: AM_GNU_GETTEXT_REQUIRE_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_REQUIRE_VERSION], []) diff --git a/cpp/third_party/xz-5.8.3/m4/host-cpu-c-abi.m4 b/cpp/third_party/xz-5.8.3/m4/host-cpu-c-abi.m4 new file mode 100644 index 000000000..ca021d6a9 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/host-cpu-c-abi.m4 @@ -0,0 +1,529 @@ +# host-cpu-c-abi.m4 +# serial 18 +dnl Copyright (C) 2002-2024 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 This file is offered as-is, without any warranty. + +dnl From Bruno Haible and Sam Steingold. + +dnl Sets the HOST_CPU variable to the canonical name of the CPU. +dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its +dnl C language ABI (application binary interface). +dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in +dnl config.h. +dnl +dnl This canonical name can be used to select a particular assembly language +dnl source file that will interoperate with C code on the given host. +dnl +dnl For example: +dnl * 'i386' and 'sparc' are different canonical names, because code for i386 +dnl will not run on SPARC CPUs and vice versa. They have different +dnl instruction sets. +dnl * 'sparc' and 'sparc64' are different canonical names, because code for +dnl 'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code +dnl contains 32-bit instructions, whereas 'sparc64' code contains 64-bit +dnl instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit +dnl mode, but not both. +dnl * 'mips' and 'mipsn32' are different canonical names, because they use +dnl different argument passing and return conventions for C functions, and +dnl although the instruction set of 'mips' is a large subset of the +dnl instruction set of 'mipsn32'. +dnl * 'mipsn32' and 'mips64' are different canonical names, because they use +dnl different sizes for the C types like 'int' and 'void *', and although +dnl the instruction sets of 'mipsn32' and 'mips64' are the same. +dnl * The same canonical name is used for different endiannesses. You can +dnl determine the endianness through preprocessor symbols: +dnl - 'arm': test __ARMEL__. +dnl - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL. +dnl - 'powerpc64': test __BIG_ENDIAN__ vs. __LITTLE_ENDIAN__. +dnl * The same name 'i386' is used for CPUs of type i386, i486, i586 +dnl (Pentium), AMD K7, Pentium II, Pentium IV, etc., because +dnl - Instructions that do not exist on all of these CPUs (cmpxchg, +dnl MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your +dnl assembly language source files use such instructions, you will +dnl need to make the distinction. +dnl - Speed of execution of the common instruction set is reasonable across +dnl the entire family of CPUs. If you have assembly language source files +dnl that are optimized for particular CPU types (like GNU gmp has), you +dnl will need to make the distinction. +dnl See . +AC_DEFUN([gl_HOST_CPU_C_ABI], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_C_ASM]) + AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi], + [case "$host_cpu" in + +changequote(,)dnl + i[34567]86 ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=i386 + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=x86_64-x32], + [gl_cv_host_cpu_c_abi=x86_64])], + [gl_cv_host_cpu_c_abi=i386]) + ;; + +changequote(,)dnl + alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=alpha + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __aarch64__ + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=arm64-ilp32], + [gl_cv_host_cpu_c_abi=arm64])], + [# Don't distinguish little-endian and big-endian arm, since they + # don't require different machine code for simple operations and + # since the user can distinguish them through the preprocessor + # defines __ARMEL__ vs. __ARMEB__. + # But distinguish arm which passes floating-point arguments and + # return values in integer registers (r0, r1, ...) - this is + # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which + # passes them in float registers (s0, s1, ...) and double registers + # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer + # sets the preprocessor defines __ARM_PCS (for the first case) and + # __ARM_PCS_VFP (for the second case), but older GCC does not. + echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c + # Look for a reference to the register d0 in the .s file. + AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1 + if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then + gl_cv_host_cpu_c_abi=armhf + else + gl_cv_host_cpu_c_abi=arm + fi + rm -f conftest* + ]) + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __LP64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=hppa64], + [gl_cv_host_cpu_c_abi=hppa]) + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=ia64-ilp32], + [gl_cv_host_cpu_c_abi=ia64]) + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mips64], + [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but + # may later get defined by ), and _MIPS_SIM == _ABIN32. + # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but + # may later get defined by ), and _MIPS_SIM == _ABIO32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (_MIPS_SIM == _ABIN32) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mipsn32], + [gl_cv_host_cpu_c_abi=mips])]) + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [# On powerpc64, there are two ABIs on Linux: The AIX compatible + # one and the ELFv2 one. The latter defines _CALL_ELF=2. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _CALL_ELF && _CALL_ELF == 2 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=powerpc64-elfv2], + [gl_cv_host_cpu_c_abi=powerpc64]) + ], + [gl_cv_host_cpu_c_abi=powerpc]) + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi=powerpc + ;; + + riscv32 | riscv64 ) + # There are 2 architectures (with variants): rv32* and rv64*. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if __riscv_xlen == 64 + int ok; + #else + error fail + #endif + ]])], + [cpu=riscv64], + [cpu=riscv32]) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [main_abi=lp64], + [main_abi=ilp32]) + # Float ABIs: + # __riscv_float_abi_double: + # 'float' and 'double' are passed in floating-point registers. + # __riscv_float_abi_single: + # 'float' are passed in floating-point registers. + # __riscv_float_abi_soft: + # No values are passed in floating-point registers. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_double + int ok; + #else + error fail + #endif + ]])], + [float_abi=d], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_single + int ok; + #else + error fail + #endif + ]])], + [float_abi=f], + [float_abi='']) + ]) + gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}" + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=s390x], + [gl_cv_host_cpu_c_abi=s390]) + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=sparc64], + [gl_cv_host_cpu_c_abi=sparc]) + ;; + + *) + gl_cv_host_cpu_c_abi="$host_cpu" + ;; + esac + ]) + + dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same. + HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'` + HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi" + AC_SUBST([HOST_CPU]) + AC_SUBST([HOST_CPU_C_ABI]) + + # This was + # AC_DEFINE_UNQUOTED([__${HOST_CPU}__]) + # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__]) + # earlier, but KAI C++ 3.2d doesn't like this. + sed -e 's/-/_/g' >> confdefs.h <. +dnl Don't make changes that are incompatible with that documentation! + +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. + gl_saved_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 + gl_saved_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="$gl_saved_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, macOS 14.4. + gl_saved_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...7.2 bug: Failures are not distinguishable from + successful returns. This is even documented in + */ + { + 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 macOS 14.4 bug: Failures are not distinguishable from + successful returns. + POSIX:2018 says: "The iconv() function shall ... return the number of + non-identical conversions performed." + But here, the conversion always does transliteration (the suffixes + "//TRANSLIT" and "//IGNORE" have no effect, nor does iconvctl()) and + does not report when it does a non-identical conversion. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\305\202"; /* LATIN SMALL LETTER L WITH STROKE */ + 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); + /* Here: + With glibc, GNU libiconv (including macOS up to 13): res == (size_t)-1, errno == EILSEQ. + With musl libc, NetBSD 10, Solaris 11: res == 1. + With macOS 14.4: res == 0, output is "l". */ + if (res == 0) + result |= 2; + 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 |= 4; + 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 |= 8; + 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 |= 16; + iconv_close (cd_88591_to_utf8); + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + { + /* Try standardized names. */ + iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP"); + /* Try IRIX, OSF/1 names. */ + iconv_t cd2 = iconv_open ("UTF-8", "eucJP"); + /* Try AIX names. */ + iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP"); + /* Try HP-UX names. */ + iconv_t cd4 = iconv_open ("utf8", "eucJP"); + if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) + && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) + result |= 32; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd3 != (iconv_t)(-1)) + iconv_close (cd3); + if (cd4 != (iconv_t)(-1)) + iconv_close (cd4); + } + 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="$gl_saved_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="$gl_saved_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) +]) + +dnl Define AM_ICONV using AC_DEFUN_ONCE, in order to avoid warnings like +dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". +AC_DEFUN_ONCE([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_CACHE_CHECK([whether iconv is compatible with its POSIX signature], + [gl_cv_iconv_nonconst], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); + ]], + [[]])], + [gl_cv_iconv_nonconst=yes], + [gl_cv_iconv_nonconst=no]) + ]) + else + dnl When compiling GNU libiconv on a system that does not have iconv yet, + dnl pick the POSIX compliant declaration without 'const'. + gl_cv_iconv_nonconst=yes + fi + if test $gl_cv_iconv_nonconst = yes; then + iconv_arg1="" + else + iconv_arg1="const" + fi + AC_DEFINE_UNQUOTED([ICONV_CONST], [$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 $gl_cv_iconv_nonconst != yes; then + ICONV_CONST="const" + fi + ]) + + dnl A summary result, for those packages which want to print a summary at the + dnl end of the configuration. + if test "$am_func_iconv" = yes; then + if test -n "$LIBICONV"; then + am_cv_func_iconv_summary='yes, in libiconv' + else + am_cv_func_iconv_summary='yes, in libc' + fi + else + if test "$am_cv_func_iconv" = yes; then + am_cv_func_iconv_summary='not working, consider installing GNU libiconv' + else + am_cv_func_iconv_summary='no, consider installing GNU libiconv' + fi + fi +]) diff --git a/cpp/third_party/xz-5.8.3/m4/intlmacosx.m4 b/cpp/third_party/xz-5.8.3/m4/intlmacosx.m4 new file mode 100644 index 000000000..4cf791673 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/intlmacosx.m4 @@ -0,0 +1,71 @@ +# intlmacosx.m4 +# serial 10 (gettext-0.23) +dnl Copyright (C) 2004-2014, 2016, 2019-2024 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 This file is offered as-is, without any warranty. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Checks for special options needed on Mac OS X. +dnl Defines INTL_MACOSX_LIBS. +AC_DEFUN([gt_INTL_MACOSX], +[ + dnl Check for API introduced in Mac OS X 10.4. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + [gt_cv_func_CFPreferencesCopyAppValue], + [gt_saved_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[CFPreferencesCopyAppValue(NULL, NULL)]])], + [gt_cv_func_CFPreferencesCopyAppValue=yes], + [gt_cv_func_CFPreferencesCopyAppValue=no]) + LIBS="$gt_saved_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], + [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi + dnl Don't check for the API introduced in Mac OS X 10.5, CFLocaleCopyCurrent, + dnl because in macOS 10.13.4 it has the following behaviour: + dnl When two or more languages are specified in the + dnl "System Preferences > Language & Region > Preferred Languages" panel, + dnl it returns en_CC where CC is the territory (even when English is not among + dnl the preferred languages!). What we want instead is what + dnl CFLocaleCopyCurrent returned in earlier macOS releases and what + dnl CFPreferencesCopyAppValue still returns, namely ll_CC where ll is the + dnl first among the preferred languages and CC is the territory. + AC_CACHE_CHECK([for CFLocaleCopyPreferredLanguages], [gt_cv_func_CFLocaleCopyPreferredLanguages], + [gt_saved_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[CFLocaleCopyPreferredLanguages();]])], + [gt_cv_func_CFLocaleCopyPreferredLanguages=yes], + [gt_cv_func_CFLocaleCopyPreferredLanguages=no]) + LIBS="$gt_saved_LIBS"]) + if test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYPREFERREDLANGUAGES], [1], + [Define to 1 if you have the Mac OS X function CFLocaleCopyPreferredLanguages in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes \ + || test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + dnl Starting with macOS version 14, CoreFoundation relies on CoreServices, + dnl and we have to link it in explicitly, otherwise an exception + dnl NSInvalidArgumentException "unrecognized selector sent to instance" + dnl occurs. + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation -Wl,-framework -Wl,CoreServices" + fi + AC_SUBST([INTL_MACOSX_LIBS]) +]) diff --git a/cpp/third_party/xz-5.8.3/m4/lib-ld.m4 b/cpp/third_party/xz-5.8.3/m4/lib-ld.m4 new file mode 100644 index 000000000..e6e16bb0b --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/lib-ld.m4 @@ -0,0 +1,170 @@ +# lib-ld.m4 +# serial 13 +dnl Copyright (C) 1996-2003, 2009-2024 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 This file is offered as-is, without any warranty. + +dnl Subroutines of libtool.m4, +dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid +dnl collision with libtool.m4. + +dnl From libtool-2.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 lds 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 + +if test -n "$LD"; then + AC_MSG_CHECKING([for ld]) +elif test "$GCC" = yes; then + AC_MSG_CHECKING([for ld used by $CC]) +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + AC_CACHE_VAL([acl_cv_path_LD], + [ + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw* | windows*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_saved_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_saved_IFS" + 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 variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 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 By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + ]) + AC_ARG_WITH(PACK[-prefix], +[[ --with-]]PACK[[-prefix[=DIR] search for ]]PACKLIBS[[ in DIR/include and DIR/lib + --without-]]PACK[[-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\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + additional_libdir2="$withval/$acl_libdirstem2" + additional_libdir3="$withval/$acl_libdirstem3" + fi + fi +]) + if test "X$additional_libdir2" = "X$additional_libdir"; then + additional_libdir2= + fi + if test "X$additional_libdir3" = "X$additional_libdir"; then + additional_libdir3= + fi + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Use breadth-first search. + 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 + for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do + if test "X$found_dir" = "X"; then + eval dir=\$$additional_libdir_variable + if test -n "$dir"; then + 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" && acl_is_expected_elfclass < "$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" && acl_is_expected_elfclass < "$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" && acl_is_expected_elfclass < "$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" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; 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 + fi + done + 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" && acl_is_expected_elfclass < "$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" && acl_is_expected_elfclass < "$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" && acl_is_expected_elfclass < "$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" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; 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" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem3"; 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" + ;; + */$acl_libdirstem3 | */$acl_libdirstem3/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'` + 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. + saved_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$saved_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $dependency_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$dependency_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then + haveit= + if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; 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$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + dnl Really add $dependency_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$dependency_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$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + dnl Really add $dependency_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$dependency_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. + dnl But on GNU systems, ignore -lc options, because + dnl - linking with libc is the default anyway, + dnl - linking with libc.a may produce an error + dnl "/usr/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie" + dnl or may produce an executable that always crashes, see + dnl . + dep=`echo "X$dep" | sed -e 's/^X-l//'` + if test "X$dep" != Xc \ + || case $host_os in + linux* | gnu* | k*bsd*-gnu) false ;; + *) true ;; + esac; then + names_next_round="$names_next_round $dep" + fi + ;; + *.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_saved_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_saved_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_saved_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_saved_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([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" \ + && test "X$dir" != "X/usr/$acl_libdirstem3"; 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" \ + && test "X$dir" != "X/usr/$acl_libdirstem3"; 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_saved_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_saved_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_saved_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_saved_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/cpp/third_party/xz-5.8.3/m4/lib-prefix.m4 b/cpp/third_party/xz-5.8.3/m4/lib-prefix.m4 new file mode 100644 index 000000000..cf72a5b48 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/lib-prefix.m4 @@ -0,0 +1,334 @@ +# lib-prefix.m4 +# serial 23 +dnl Copyright (C) 2001-2005, 2008-2024 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 This file is offered as-is, without any warranty. + +dnl From Bruno Haible. + +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_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_saved_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_saved_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_saved_prefix="$prefix" + prefix="$acl_final_prefix" + acl_saved_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_saved_exec_prefix" + prefix="$acl_saved_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a function acl_is_expected_elfclass, that tests whether standard input +dn; has a 32-bit or 64-bit ELF header, depending on the host CPU ABI, +dnl - 3 variables acl_libdirstem, acl_libdirstem2, acl_libdirstem3, containing +dnl the basename of the libdir to try in turn, either "lib" or "lib64" or +dnl "lib/64" or "lib32" or "lib/sparcv9" or "lib/amd64" or similar. +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib, lib32, and lib64. + dnl On most 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. However, on + dnl Arch Linux based distributions, it's the opposite: 32-bit libraries go + dnl under $prefix/lib32 and 64-bit libraries go under $prefix/lib. + dnl We determine the compiler's default mode by looking at the compiler's + dnl library search path. If at least one of its elements ends in /lib64 or + dnl points to a directory whose absolute pathname ends in /lib64, we use that + dnl for 64-bit ABIs. Similarly for 32-bit ABIs. Otherwise we use the default, + dnl 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]) + AC_REQUIRE([gl_HOST_CPU_C_ABI_32BIT]) + + AC_CACHE_CHECK([for ELF binary format], [gl_cv_elf], + [AC_EGREP_CPP([Extensible Linking Format], + [#if defined __ELF__ || (defined __linux__ && (defined __EDG__ || defined __SUNPRO_C)) + Extensible Linking Format + #endif + ], + [gl_cv_elf=yes], + [gl_cv_elf=no]) + ]) + if test $gl_cv_elf = yes; then + # Extract the ELF class of a file (5th byte) in decimal. + # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header + if od -A x < /dev/null >/dev/null 2>/dev/null; then + # Use POSIX od. + func_elfclass () + { + od -A n -t d1 -j 4 -N 1 + } + else + # Use BSD hexdump. + func_elfclass () + { + dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 "%3d "' + echo + } + fi + # Use 'expr', not 'test', to compare the values of func_elfclass, because on + # Solaris 11 OpenIndiana and Solaris 11 OmniOS, the result is 001 or 002, + # not 1 or 2. +changequote(,)dnl + case $HOST_CPU_C_ABI_32BIT in + yes) + # 32-bit ABI. + acl_is_expected_elfclass () + { + expr "`func_elfclass | sed -e 's/[ ]//g'`" = 1 > /dev/null + } + ;; + no) + # 64-bit ABI. + acl_is_expected_elfclass () + { + expr "`func_elfclass | sed -e 's/[ ]//g'`" = 2 > /dev/null + } + ;; + *) + # Unknown. + acl_is_expected_elfclass () + { + : + } + ;; + esac +changequote([,])dnl + else + acl_is_expected_elfclass () + { + : + } + fi + + dnl Allow the user to override the result by setting acl_cv_libdirstems. + AC_CACHE_CHECK([for the common suffixes of directories in the library search path], + [acl_cv_libdirstems], + [dnl Try 'lib' first, because that's the default for libdir in GNU, see + dnl . + acl_libdirstem=lib + acl_libdirstem2= + acl_libdirstem3= + 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. + if test $HOST_CPU_C_ABI_32BIT = no; then + acl_libdirstem2=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem3=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem3=lib/amd64 ;; + esac + fi + ;; + netbsd*) + dnl On NetBSD/sparc64, there is a 'sparc' subdirectory that contains + dnl 32-bit libraries. + if test $HOST_CPU_C_ABI_32BIT != no; then + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparc ;; + esac + fi + ;; + *) + dnl If $CC generates code for a 32-bit ABI, the libraries are + dnl surely under $prefix/lib or $prefix/lib32, not $prefix/lib64. + dnl Similarly, if $CC generates code for a 64-bit ABI, the libraries + dnl are surely under $prefix/lib or $prefix/lib64, not $prefix/lib32. + dnl Find the compiler's search path. However, non-system compilers + dnl sometimes have odd library search paths. But we can't simply invoke + dnl '/usr/bin/gcc -print-search-dirs' because that would not take into + dnl account the -m32/-m31 or -m64 options from the $CC or $CFLAGS. + searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \ + | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test $HOST_CPU_C_ABI_32BIT != no; then + # 32-bit or unknown ABI. + if test -d /usr/lib32; then + acl_libdirstem2=lib32 + fi + fi + if test $HOST_CPU_C_ABI_32BIT != yes; then + # 64-bit or unknown ABI. + if test -d /usr/lib64; then + acl_libdirstem3=lib64 + fi + fi + if test -n "$searchpath"; then + acl_saved_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;; + */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib32 ) acl_libdirstem2=lib32 ;; + */lib64 ) acl_libdirstem3=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_saved_IFS" + if test $HOST_CPU_C_ABI_32BIT = yes; then + # 32-bit ABI. + acl_libdirstem3= + fi + if test $HOST_CPU_C_ABI_32BIT = no; then + # 64-bit ABI. + acl_libdirstem2= + fi + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + test -n "$acl_libdirstem3" || acl_libdirstem3="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3" + ]) + dnl Decompose acl_cv_libdirstems into acl_libdirstem, acl_libdirstem2, and + dnl acl_libdirstem3. +changequote(,)dnl + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,//' -e 's/,.*//'` + acl_libdirstem3=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'` +changequote([,])dnl +]) diff --git a/cpp/third_party/xz-5.8.3/m4/libtool.m4 b/cpp/third_party/xz-5.8.3/m4/libtool.m4 new file mode 100644 index 000000000..5ccb3a813 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/libtool.m4 @@ -0,0 +1,8880 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2019, 2021-2025 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) 2025 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 . +]) + +# serial 66 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.64])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_DECL_FILECMD])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 and +# ICC, which need '.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 + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# 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], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _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_OBJECTIVE_C +# ------------------------------ +m4_defun([_LT_OBJECTIVE_C], [ + AC_CACHE_CHECK([for Objective C compilation], + [lt_cv_objc_compiles], + [ save_CFLAGS=$CFLAGS + CFLAGS=$OBJCFLAGS + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([#import +@interface Addition : NSObject +- (int)this:(int)a that:(int)b; +@end + +@implementation Addition +- (int)this:(int)a that:(int)b +{ + return a + b; +} +@end +],[])], + lt_cv_objc_compiles=yes, + lt_cv_objc_compiles=no + ) + CFLAGS=$save_CFLAGS + ] + ) + objc_compiles=$lt_cv_objc_compiles + _LT_DECL([], [objc_compiles], [1], + [Check for compiling Objective C and C++ code]) +]) + +m4_defun([_LT_ML64], [ + AC_CACHE_CHECK([for ML64 compilation], + [lt_cv_ml64_compiles], + [ save_CFLAGS=$CFLAGS + CFLAGS=$ML64FLAGS + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([ret +],[])], + lt_cv_ml64_compiles=yes, + lt_cv_ml64_compiles=no + ) + CFLAGS=$save_CFLAGS + ] + ) + objc_compiles=$lt_cv_objc_compiles + _LT_DECL([], [ml64_compiles], [1], + [Check for compiling ml64 code]) +]) + + +# _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), in case 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) 2025 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permission 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)], + [Objective-C], [_LT_LANG(OBJC)], + [Objective-C++], [_LT_LANG(OBJCXX)], + [Microsoft Macro Assembler], [_LT_LANG(ML64)], + [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_ML64], [ +m4_defun([AC_PROG_ML64], +[AC_LANG_PUSH(ML64)dnl +AC_ARG_VAR([ML64], [ml64 compiler command])dnl +AC_ARG_VAR([ML64FLAGS], [ml64 compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(ML64, ml64) +if test -z "$ML64"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(ML64, [${ac_tool_prefix}ml64], [${ac_tool_prefix}ml64]) + fi +fi +if test -z "$ML64"; then + AC_CHECK_PROG(ML64, ml64, ml64, false) +fi +])#m4_defun +])#m4_ifndef + + + +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([AC_PROG_OBJC], + [LT_LANG(OBJC)], + [m4_define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[LT_LANG(OBJC)])]) + +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [LT_LANG(OBJCXX)], + [m4_define([AC_PROG_OBJCXX], defn([AC_PROG_OBJCXX])[LT_LANG(OBJCXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_ML64], + [LT_LANG(ML64)], + [m4_define([AC_PROG_ML64], defn([AC_PROG_ML64])[LT_LANG(ML64)])]) +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]) + + # Feature test to disable chained fixups since it is not + # compatible with '-undefined dynamic_lookup' + AC_CACHE_CHECK([for -no_fixup_chains linker flag], + [lt_cv_support_no_fixup_chains], + [ save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([],[])], + lt_cv_support_no_fixup_chains=yes, + lt_cv_support_no_fixup_chains=no + ) + LDFLAGS=$save_LDFLAGS + ] + ) + + 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 $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR $AR_FLAGS 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(void) { 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*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' + if test yes = "$lt_cv_support_no_fixup_chains"; then + AS_VAR_APPEND([_lt_dar_allow_undefined], [' $wl-no_fixup_chains']) + fi + ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + _lt_dar_needs_single_mod=no + case $host_os in + rhapsody* | darwin1.*) + _lt_dar_needs_single_mod=yes ;; + darwin*) + # When targeting Mac OS X 10.4 (darwin 8) or later, + # -single_module is the default and -multi_module is unsupported. + # The toolchain on macOS 10.14 (darwin 18) and later cannot + # target any OS version that needs -single_module. + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*-darwin[[567]].*|10.[[0-3]],*-darwin[[5-9]].*|10.[[0-3]],*-darwin1[[0-7]].*) + _lt_dar_needs_single_mod=yes ;; + esac + ;; + esac + 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_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs $stdlibflag -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 $stdlibflag -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], +[m4_require([_LT_DECL_SED])dnl +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 + # Trim trailing / since we'll always append absolute paths and we want + # to avoid //, if only for less confusing output for the user. + lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'` + 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 `$FILECMD 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 `$FILECMD conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `$FILECMD 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 `$FILECMD conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `$FILECMD conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `$FILECMD 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*|x86_64-gnu*) + # 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 `$FILECMD conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*|x86_64-gnu*) + case `$FILECMD 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*|x86_64-gnu*) + 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 `$FILECMD 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} +_LT_DECL([], [AR], [1], [The archiver]) + +# Use ARFLAGS variable as AR's operation code to sync the variable naming with +# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have +# higher priority because that's what people were doing historically (setting +# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS +# variable obsoleted/removed. + +test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} +lt_ar_flags=$AR_FLAGS +_LT_DECL([], [lt_ar_flags], [1], [Flags to create an archive (by configure)]) + +# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override +# by AR_FLAGS because that was never working and AR_FLAGS is about to die. +_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], + [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_REQUIRE([AC_PROG_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 + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_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.expsym + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.expsym 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.expsym + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.expsym 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* | ironclad*) + # Under GNU Hurd and Ironclad, 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* | windows* | 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; + ;; + + darwin* | dragonfly* | freebsd* | midnightbsd* | 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 (void) __attribute__((visibility("default"))); +#endif + +int fnord (void) { return 42; } +int main (void) +{ + 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* | windows* | 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.expsym + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.expsym 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 -z "$STRIP"; then + AC_MSG_RESULT([no]) +else + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac + fi +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* | windows* | 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* | windows* | 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 --enable-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* | windows* | 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 + # If user builds GCC with multilib enabled, + # it should just install on $(libdir) + # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. + if test xyes = x"$multilib"; then + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + $install_prog $dir/$dlname $destdir/$dlname~ + chmod a+x $destdir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib $destdir/$dlname'\'' || exit \$?; + fi' + else + 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' + 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* | windows* | 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* | *,icl* | *,icx*) + # Native MSVC and Intel compilers + 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* | windows*) + 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 and ICC 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* | midnightbsd*) + # 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 + case $host_cpu in + powerpc64) + # On FreeBSD bi-arch platforms, a different variable is used for 32-bit + # binaries. See . + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[int test_pointer_size[sizeof (void *) - 5]; + ]])], + [shlibpath_var=LD_LIBRARY_PATH], + [shlibpath_var=LD_32_LIBRARY_PATH]) + ;; + *) + shlibpath_var=LD_LIBRARY_PATH + ;; + esac + 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_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib' + sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib' + hardcode_into_libs=no + ;; + +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 + ;; + +*-mlibc) + 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='mlibc ld.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + 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 $libname$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' + # -rpath works at least for libraries that are not overridden by + # libraries installed in system locations. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$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* directories 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' + enable_cxx_stdlib=yes + stdlibflag= + ;; + +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 + enable_cxx_stdlib=yes + stdlibflag= + ;; + +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*) + 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 + ;; + +serenity*) + 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=no + dynamic_linker='SerenityOS LibELF' + ;; + +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 + ;; + +emscripten*) + version_type=none + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + dynamic_linker="Emscripten linker" + _LT_COMPILER_PIC($1)='-fPIC' + _LT_TAGVAR(archive_cmds, $1)='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(no_undefined_flag, $1)= + ;; + +*) + 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* | *-*-windows*) + # 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. +# '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='$FILECMD -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* | windows* | 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|pe-aarch64)' + 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* | midnightbsd*) + 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=$FILECMD + 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=$FILECMD + 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 + ;; + +*-mlibc) + 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=$FILECMD + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + 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 + ;; + +serenity*) + 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* | windows* | 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* | windows*) 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* | windows* | 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_manifest_tool], + [lt_cv_path_manifest_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_manifest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_manifest_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* | *-*-mingw* | *-*-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* | windows* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BCDRT]]' + ;; +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 .* \([[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \([[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \([[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib[[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \([[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/ {\"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 .* \([[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \([[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/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* .* \([[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/ {\"\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[[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \([[a-zA-Z_]][[a-zA-Z0-9_]]*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw* | windows*) + 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++ or ICC, + # which start with @ or ?. And Cygwin gawk-4.1.4-3 and newer + # treats input as binary, have to drop carriage return first. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {sub(/\\r\$/,\"\")};"\ +" {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(void){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* | windows* | 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.expsym' + 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* | windows* | 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* | midnightbsd*) + # 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 + ;; + *-mlibc) + ;; + 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* | icpx*) + # 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*) + ;; + serenity*) + ;; + 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* | windows* | 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.expsym' + 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* | windows* | 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' + ;; + + *-mlibc) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu* | freebsd*) + 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* | ftn | f18* | f95*) + # Flang 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' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort* | icx* | ifx*) + _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' + ;; + + serenity*) + ;; + + 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 == "L") || (\$ 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* | windows* | cegcc*) + case $cc_basename in + cl* | icl* | icx* | icpx*) + # Native MSVC and Intel compilers + _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 + ;; + *) + _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* | windows* | pw32* | cegcc*) + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++ or Intel C++ Compiler. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) + with_gnu_ld=yes + ;; + 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* | windows* | 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'] + _LT_TAGVAR(file_list_spec, $1)='@' + + 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)=no + ;; + + 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 + _LT_TAGVAR(file_list_spec, $1)='@' + ;; + + 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' + ;; + + *-mlibc) + _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' + ;; + + 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* | ifx*) # 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(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _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 == "L") || (\$ 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* | windows* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++ or Intel C++ Compiler. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl* | icl* | icx* | icpx*) + # Native MSVC and Intel compilers + _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. + # A check exists to verify if there are linker flags, which will use + # different commands when linking. + _LT_TAGVAR(archive_cmds, $1)='$CC -Fe$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.expsym"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.expsym; + fi~ + if test -z "$linker_flags"; then + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.expsym" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"; + else + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.expsym" -Wl,$linker_flags-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"; + fi~ + 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 and ICC 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 -Fe$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* | midnightbsd*) + _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 + 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 + ;; + + *-mlibc) + ;; + + 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' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + 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*) + 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 + _LT_TAGVAR(file_list_spec, $1)='@' + ;; + + 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.expsym; done; printf "%s\\n" "-hidden">> $lib.expsym~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.expsym $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.expsym' + + # 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)=: + ;; + + serenity*) + ;; + + 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.expsym~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.expsym~echo "local: *; };" >> $lib.expsym~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.expsym $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.expsym' + 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.expsym~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.expsym~echo "local: *; };" >> $lib.expsym~ + $LD -G$allow_undefined_flag -M $lib.expsym -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.expsym' + ;; + *) + 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.expsym~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.expsym~echo "local: *; };" >> $lib.expsym~ + $CC -G$allow_undefined_flag -M $lib.expsym -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.expsym' + ;; + 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(void){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 + +## 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... +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 $stdlibflag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared $stdlibflag $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 $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 $stdlibflag $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 -v "^Driving:" | $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* | windows* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl* | ,icl* | no,icl* | ,icx* | no,icx* | ,icpx* | no,icpx*) + # Native MSVC and Intel compilers + # 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. + # A check exists to verify if there are linker flags, which will use + # different commands when linking. + _LT_TAGVAR(archive_cmds, $1)='$CC -Fe$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.expsym"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.expsym; + fi~ + if test -z "$linker_flags"; then + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.expsym" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"; + else + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.expsym" -Wl,$linker_flags-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"; + fi~ + 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 + _LT_TAGVAR(file_list_spec, $1)='@' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $stdlibflag $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 $stdlibflag $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 + _LT_TAGVAR(file_list_spec, $1)='@' + ;; + + 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* | midnightbsd*) + # 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)=no + ;; + + 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 $stdlibflag $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 $stdlibflag -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $stdlibflag $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 $stdlibflag $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 $stdlibflag $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 $stdlibflag $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 + ;; + + *-mlibc) + _LT_TAGVAR(ld_shlibs, $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* | icpx*) + # 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 + else + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + output_verbose_link_cmd=func_echo_all + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd*) + 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.expsym; done~ + echo "-hidden">> $lib.expsym~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.expsym `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.expsym' + _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 $stdlibflag $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 $stdlibflag $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 -v "^Driving:" | $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 + ;; + + serenity*) + ;; + + 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.expsym~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.expsym~echo "local: *; };" >> $lib.expsym~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.expsym -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.expsym' + + _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 $stdlibflag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.expsym~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.expsym~echo "local: *; };" >> $lib.expsym~ + $CC -shared $pic_flag $stdlibflag $wl-M $wl$lib.expsym $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.expsym' + + # 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 -v "^Driving:" | $GREP " [[-]]L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $stdlibflag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.expsym~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.expsym~echo "local: *; };" >> $lib.expsym~ + $CC -G $stdlibflag $wl-M $wl$lib.expsym $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.expsym' + + # 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 -v "^Driving:" | $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 + + if test yes = "$enable_cxx_stdlib"; then + output_verbose_link_cmd= + fi + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l* | */libclang_rt.*.a) + # Some compilers place space between "-{L,R,l}" and the path. + # Remove the space. + if test x-L = x"$p" || + test x-R = x"$p" || + test x-l = x"$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 + +## 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... +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_ML64_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the ML64 assembler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_ML64_CONFIG], +[AC_REQUIRE([LT_PROG_ML64])dnl +AC_LANG_SAVE + +# Source file extension for ML64 test sources. +ac_ext=asm + +#Object file extension for compile ML64 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="main PROC ret main ENDP" + +# Code to be used in simple link tests +lt_simple_link_test_code="main PROC ret main ENDP" + +# 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 + +# TODO? Check for compilation issues with ML64 flags. + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${ML64-"gcc"} +CFLAGS=$ML64FLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## 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... +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_ML64_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 + +## 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... +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_OBJC_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Objective-C compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_OBJC_CONFIG], +[AC_REQUIRE([LT_PROG_OBJC])dnl +AC_LANG_SAVE + +# Source file extension for OBJC test sources. +ac_ext=m + +# Object file extension for compiled OBJC 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(void){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 + +# Check for compilation issues with OBJC flags +_LT_OBJECTIVE_C +if test "yes" = "$lt_cv_gnustep_exists"; then + OBJCFLAGS="$OBJCFLAGS `gnustep-config --objc-flags`" +fi + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${OBJC-"gcc"} +CFLAGS=$OBJCFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## 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... +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_OBJC_CONFIG + + +# _LT_LANG_OBJCXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Objective-C++ compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_OBJCXX_CONFIG], +[AC_REQUIRE([LT_PROG_OBJCXX])dnl +AC_LANG_SAVE + +# Source file extension for OBJCXX test sources. +ac_ext=mm + +# Object file extension for compiled OBJCXX 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(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 + +# Check for compilation issues with OBJCXX flags +_LT_OBJECTIVE_C + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${OBJCXX-"g++"} +CFLAGS=$OBJCXXFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## 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... +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_OBJCXX_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_ML64 +# ----------- +AC_DEFUN([LT_PROG_ML64], +[AC_CHECK_TOOL(ML64, ml64,) +]) + + +# LT_PROG_OBJC +# ----------- +AC_DEFUN([LT_PROG_OBJC], +[AC_CHECK_TOOL(OBJC, gcc,) + AC_CHECK_TOOL(GNUSTEP_CONFIG, gnustep-config,) + if test Xgnustep-config = X"$GNUSTEP_CONFIG"; then + test set = "${OBJCFLAGS+set}" || OBJCFLAGS="`gnustep-config --objc-flags`" + fi + AC_SUBST(OBJCFLAGS)])])[]dnl +]) + +# LT_PROG_OBJCXX +# ----------- +AC_DEFUN([LT_PROG_OBJCXX], +[AC_CHECK_TOOL(OBJCXX, g++,) + AC_CHECK_TOOL(GNUSTEP_CONFIG, gnustep-config,) + if test Xgnustep-config = X"$GNUSTEP_CONFIG"; then + test set = "${OBJCXXFLAGS+set}" || OBJCXXFLAGS="`gnustep-config --objc-flags`" + fi + AC_SUBST(OBJCXXFLAGS)])])[]dnl +]) + +# 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_FILECMD +# ---------------- +# Check for a file(cmd) program that can be used to detect file type and magic +m4_defun([_LT_DECL_FILECMD], +[AC_CHECK_PROG([FILECMD], [file], [file], [:]) +_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) +])# _LD_DECL_FILECMD + +# _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 +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* | *-*-windows* ) # 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* | *-*-windows* ) # 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* | *-*-windows* ) + case $build in + *-*-mingw* | *-*-windows* ) # 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 + +AS_CASE([$host], + [*-*-mingw* | *-*-windows* | *-*-cygwin*], + [AS_CASE([$build], + [*-*-mingw* | *-*-windows* | *-*-cygwin*], + [AC_MSG_CHECKING([whether cygpath is installed]) + AC_CACHE_VAL([lt_cv_cygpath_installed], + [lt_cv_cygpath_installed=ignoring + cygpath --help &> /dev/null + _lt_result=$? + AS_IF([test 0 = "$_lt_result"], + [lt_cv_cygpath_installed=yes], + [lt_cv_cygpath_installed=no]) + ]) + AC_MSG_RESULT([$lt_cv_cygpath_installed]) + _LT_DECL([cygpath_installed], [lt_cv_cygpath_installed], + [0], [whether cygpath is installed])dnl + AS_IF([test "xyes" != "x$lt_cv_cygpath_installed"], + [ + AC_MSG_CHECKING([whether to use cmd with one slash or two slashes]) + AC_CACHE_VAL([lt_cv_cmd_slashes], + [ + _lt_result=`cmd /c echo one-slash works. Not checked //c echo two-slashes 2>/dev/null` + AS_IF([test 0 != $?], + [AC_MSG_ERROR([Do not know how to convert paths])]) + AS_CASE([$_lt_result], + [one-slash*],[lt_cv_cmd_slashes="one"], + [two-slashes*],[lt_cv_cmd_slashes="two"], + [AC_MSG_ERROR([Do not know how to convert paths])] + ) + ]) + AC_MSG_RESULT([$lt_cv_cmd_slashes]) + ]) + ]) + ] +)dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/cpp/third_party/xz-5.8.3/m4/ltoptions.m4 b/cpp/third_party/xz-5.8.3/m4/ltoptions.m4 new file mode 100644 index 000000000..9e93e6f04 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/ltoptions.m4 @@ -0,0 +1,519 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2025 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 12 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], [cxx-stdlib no-cxx-stdlib], [_LT_ENABLE_CXX_STDLIB]) + _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 + + +## --------------------------------- ## +## Macros to handle LT_INIT 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* | *-*-windows* | *-*-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 --enable-aix-soname configure option, 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_ENABLE([aix-soname], + [AS_HELP_STRING([--enable-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $enableval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --enable-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$enable_aix_soname], + [_AC_ENABLE_IF([with], [aix-soname], + [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)]) + enable_aix_soname=$lt_cv_with_aix_soname]) + with_aix_soname=$enable_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 + ;; +power*-*-aix[[5-9]]*,'') + AC_MSG_WARN([for $host, specify if building shared libraries for versioning (svr4|both)]) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + with_aix_soname=aix + AC_MSG_RESULT([(default) $with_aix_soname]) + ;; +*) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + with_aix_soname=aix + AC_MSG_RESULT([(default) $with_aix_soname]) + ;; +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 --enable-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_ENABLE([pic], + [AS_HELP_STRING([--enable-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $enableval in + yes|no) pic_mode=$enableval ;; + *) + 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 $enableval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [dnl Continue to support --with-pic and --without-pic, for backward + dnl compatibility. + _AC_ENABLE_IF([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], + [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], []) + + +# _LT_ENABLE_CXX_STDLIB([MODE]) +# -------------------- +# implement the --enable-cxx-stdlib flag, and support the 'cxx-stdlib' and 'no-cxx-stdlib' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'no'. +m4_define([_LT_ENABLE_CXX_STDLIB], +[m4_define([_LT_ENABLE_CXX_STDLIB_DEFAULT], [m4_if($1, yes, yes, no)])dnl +stdlibflag=-nostdlib +AC_ARG_ENABLE([cxx-stdlib], + [AS_HELP_STRING([--enable-cxx-stdlib@<:@=PKGS@:>@], + [let the compiler frontend decide what standard libraries to link when building C++ shared libraries and modules @<:@default=]_LT_ENABLE_CXX_STDLIB_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_cxx_stdlib=yes ;; + no) enable_cxx_stdlib=no ;; + *) + enable_cxx_stdlib=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_cxx_stdlib=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_cxx_stdlib=]_LT_ENABLE_CXX_STDLIB_DEFAULT) + +if test yes = "$enable_cxx_stdlib"; then + stdlibflag= +fi + +_LT_DECL([], [enable_cxx_stdlib], [0], [Whether to let the compiler frontend decide what standard libraries to link when building C++ shared libraries and modules])dnl +_LT_DECL([], [stdlibflag], [0], [Flag used for specifying not to link standard libraries])dnl +])# _LT_ENABLE_CXX_STDLIB + +LT_OPTION_DEFINE([LT_INIT], [cxx-stdlib], [_LT_ENABLE_CXX_STDLIB([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-cxx-stdlib], [_LT_ENABLE_CXX_STDLIB([no])]) + + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +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])]) diff --git a/cpp/third_party/xz-5.8.3/m4/ltsugar.m4 b/cpp/third_party/xz-5.8.3/m4/ltsugar.m4 new file mode 100644 index 000000000..5698955ba --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2025 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 +]) diff --git a/cpp/third_party/xz-5.8.3/m4/ltversion.m4 b/cpp/third_party/xz-5.8.3/m4/ltversion.m4 new file mode 100644 index 000000000..09bdaa5ee --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/ltversion.m4 @@ -0,0 +1,24 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2019, 2021-2025 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 4509 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.6.0]) +m4_define([LT_PACKAGE_REVISION], [2.6.0]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.6.0' +macro_revision='2.6.0' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/cpp/third_party/xz-5.8.3/m4/lt~obsolete.m4 b/cpp/third_party/xz-5.8.3/m4/lt~obsolete.m4 new file mode 100644 index 000000000..c1d7729b4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2025 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])]) diff --git a/cpp/third_party/xz-5.8.3/m4/nls.m4 b/cpp/third_party/xz-5.8.3/m4/nls.m4 new file mode 100644 index 000000000..219cbaa13 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/nls.m4 @@ -0,0 +1,33 @@ +# nls.m4 +# serial 6 (gettext-0.20.2) +dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016, 2019-2024 Free +dnl 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 +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ([2.50]) + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE([nls], + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT([$USE_NLS]) + AC_SUBST([USE_NLS]) +]) diff --git a/cpp/third_party/xz-5.8.3/m4/po.m4 b/cpp/third_party/xz-5.8.3/m4/po.m4 new file mode 100644 index 000000000..8c0d8602d --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/po.m4 @@ -0,0 +1,456 @@ +# po.m4 +# serial 33 (gettext-0.23) +dnl Copyright (C) 1995-2014, 2016, 2018-2022, 2024 Free Software Foundation, +dnl 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 +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2024. + +AC_PREREQ([2.60]) + +dnl Checks for all prerequisites of the po subdirectory. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AC_PROG_MKDIR_P])dnl + AC_REQUIRE([AC_PROG_SED])dnl + AC_REQUIRE([AM_NLS])dnl + + dnl Release version of the gettext macros. This is used to ensure that + dnl the gettext macros and po/Makefile.in.in are in sync. + AC_SUBST([GETTEXT_MACRO_VERSION], [0.22]) + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) + + dnl Test whether it is GNU msgfmt >= 0.15. +changequote(,)dnl + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([GMSGFMT_015]) + + dnl Search for GNU xgettext 0.12 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Test whether it is GNU xgettext >= 0.15. +changequote(,)dnl + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac +changequote([,])dnl + AC_SUBST([XGETTEXT_015]) + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) + + dnl Test whether it is GNU msgmerge >= 0.20. + if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt' + else + dnl Test whether it is GNU msgmerge >= 0.12. + if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet' + else + dnl With these old versions, $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) is + dnl slow. But this is not a big problem, as such old gettext versions are + dnl hardly in use any more. + MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet' + fi + fi + AC_SUBST([MSGMERGE_FOR_MSGFMT_OPTION]) + + dnl Support for AM_XGETTEXT_OPTION. + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) + + AC_CONFIG_COMMANDS([po-directories], [[ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + gt_tab=`printf '\t'` + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang" | "$presentlang"_* | "$presentlang".* | "$presentlang"@*) + useit=yes + ;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done]], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. + OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS" + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + +dnl Postprocesses a Makefile in a directory containing PO files. +AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], +[ + # When this code is run, in config.status, two variables have already been + # set: + # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, + # - LINGUAS is the value of the environment variable LINGUAS at configure + # time. + +changequote(,)dnl + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + # Find a way to echo strings without interpreting backslash. + if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='echo' + else + if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='printf %s\n' + else + echo_func () { + cat < "$ac_file.tmp" + tab=`printf '\t'` + if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + cat >> "$ac_file.tmp" < /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + cat >> "$ac_file.tmp" <> "$ac_file.tmp" </dev/null \ + && break;; + esac + done]) + + if test "$gl_cv_posix_shell" != no; then + POSIX_SHELL=$gl_cv_posix_shell + PREFERABLY_POSIX_SHELL=$POSIX_SHELL + else + POSIX_SHELL= + PREFERABLY_POSIX_SHELL=/bin/sh + fi + AC_SUBST([POSIX_SHELL]) + AC_SUBST([PREFERABLY_POSIX_SHELL]) +]) diff --git a/cpp/third_party/xz-5.8.3/m4/progtest.m4 b/cpp/third_party/xz-5.8.3/m4/progtest.m4 new file mode 100644 index 000000000..65ec1942a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/progtest.m4 @@ -0,0 +1,92 @@ +# progtest.m4 +# serial 10 (gettext-0.23) +dnl Copyright (C) 1996-2003, 2005, 2008-2024 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 +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1996. + +AC_PREREQ([2.53]) + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[ +# 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 + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL([ac_cv_path_$1], +[case "[$]$1" in + [[\\/]]* | ?:[[\\/]]*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + gt_saved_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in m4_if([$5], , $PATH, [$5]); do + IFS="$gt_saved_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$gt_saved_IFS" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +m4_if([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test m4_if([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$][$1]) +else + AC_MSG_RESULT([no]) +fi +AC_SUBST([$1])dnl +]) diff --git a/cpp/third_party/xz-5.8.3/m4/tuklib_common.m4 b/cpp/third_party/xz-5.8.3/m4/tuklib_common.m4 new file mode 100644 index 000000000..c83770340 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/tuklib_common.m4 @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# SYNOPSIS +# +# TUKLIB_COMMON +# +# DESCRIPTION +# +# Common checks for tuklib. +# +############################################################################# +# +# Author: Lasse Collin +# +############################################################################# + +AC_DEFUN_ONCE([TUKLIB_COMMON], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC_C99]) +AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +])dnl diff --git a/cpp/third_party/xz-5.8.3/m4/tuklib_cpucores.m4 b/cpp/third_party/xz-5.8.3/m4/tuklib_cpucores.m4 new file mode 100644 index 000000000..928ef3440 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/tuklib_cpucores.m4 @@ -0,0 +1,181 @@ +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# SYNOPSIS +# +# TUKLIB_CPUCORES +# +# DESCRIPTION +# +# Check how to find out the number of available CPU cores in the system. +# This information is used by tuklib_cpucores.c. +# +# Supported methods: +# - GetSystemInfo(): Windows (including Cygwin) +# - sched_getaffinity(): glibc (GNU/Linux, GNU/kFreeBSD) +# - cpuset_getaffinity(): FreeBSD +# - sysctl(): BSDs, OS/2 +# - sysconf(): GNU/Linux, Solaris, Tru64, IRIX, AIX, QNX, Cygwin (but +# GetSystemInfo() is used on Cygwin) +# - pstat_getdynamic(): HP-UX +# +############################################################################# +# +# Author: Lasse Collin +# +############################################################################# + +AC_DEFUN_ONCE([TUKLIB_CPUCORES], [ +AC_REQUIRE([TUKLIB_COMMON]) + +# sys/param.h might be needed by sys/sysctl.h. +AC_CHECK_HEADERS([sys/param.h]) + +AC_CACHE_CHECK([how to detect the number of available CPU cores], + [tuklib_cv_cpucores_method], [ + +# Maybe checking $host_os would be enough but this matches what +# tuklib_cpucores.c does. +# +# NOTE: IRIX has a compiler that doesn't error out with #error, so use +# a non-compilable text instead of #error to generate an error. +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#if defined(_WIN32) || defined(__CYGWIN__) +int main(void) { return 0; } +#else +compile error +#endif +]])], [tuklib_cv_cpucores_method=special], [ + +# glibc-based systems (GNU/Linux and GNU/kFreeBSD) have sched_getaffinity(). +# The CPU_COUNT() macro was added in glibc 2.9 so we try to link the +# test program instead of merely compiling it. glibc 2.9 is old enough that +# if someone uses the code on older glibc, the fallback to sysconf() should +# be good enough. +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +int +main(void) +{ + cpu_set_t cpu_mask; + sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask); + return CPU_COUNT(&cpu_mask); +} +]])], [tuklib_cv_cpucores_method=sched_getaffinity], [ + +# FreeBSD has both cpuset and sysctl. Look for cpuset first because +# it's a better approach. +# +# This test would match on GNU/kFreeBSD too but it would require +# -lfreebsd-glue when linking and thus in the current form this would +# fail on GNU/kFreeBSD. The above test for sched_getaffinity() matches +# on GNU/kFreeBSD so the test below should never run on that OS. +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +#include + +int +main(void) +{ + cpuset_t set; + cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, + sizeof(set), &set); + return 0; +} +]])], [tuklib_cv_cpucores_method=cpuset], [ + +# On OS/2, both sysconf() and sysctl() pass the tests in this file, +# but only sysctl() works. On QNX it's the opposite: only sysconf() works +# (although it assumes that _POSIX_SOURCE, _XOPEN_SOURCE, and _POSIX_C_SOURCE +# are undefined or alternatively _QNX_SOURCE is defined). +# +# We test sysctl() first and intentionally break the sysctl() test on QNX +# so that sysctl() is never used on QNX. +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#ifdef __QNX__ +compile error +#endif +#ifdef HAVE_SYS_PARAM_H +# include +#endif +#include +int +main(void) +{ +#ifdef HW_NCPUONLINE + /* This is preferred on OpenBSD, see tuklib_cpucores.c. */ + int name[2] = { CTL_HW, HW_NCPUONLINE }; +#else + int name[2] = { CTL_HW, HW_NCPU }; +#endif + int cpus; + size_t cpus_size = sizeof(cpus); + sysctl(name, 2, &cpus, &cpus_size, NULL, 0); + return 0; +} +]])], [tuklib_cv_cpucores_method=sysctl], [ + +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +int +main(void) +{ + long i; +#ifdef _SC_NPROCESSORS_ONLN + /* Many systems using sysconf() */ + i = sysconf(_SC_NPROCESSORS_ONLN); +#else + /* IRIX */ + i = sysconf(_SC_NPROC_ONLN); +#endif + return 0; +} +]])], [tuklib_cv_cpucores_method=sysconf], [ + +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +#include + +int +main(void) +{ + struct pst_dynamic pst; + pstat_getdynamic(&pst, sizeof(pst), 1, 0); + (void)pst.psd_proc_cnt; + return 0; +} +]])], [tuklib_cv_cpucores_method=pstat_getdynamic], [ + + tuklib_cv_cpucores_method=unknown +])])])])])])]) + +case $tuklib_cv_cpucores_method in + sched_getaffinity) + AC_DEFINE([TUKLIB_CPUCORES_SCHED_GETAFFINITY], [1], + [Define to 1 if the number of available CPU cores + can be detected with sched_getaffinity()]) + ;; + cpuset) + AC_DEFINE([TUKLIB_CPUCORES_CPUSET], [1], + [Define to 1 if the number of available CPU cores + can be detected with cpuset(2).]) + ;; + sysctl) + AC_DEFINE([TUKLIB_CPUCORES_SYSCTL], [1], + [Define to 1 if the number of available CPU cores + can be detected with sysctl().]) + ;; + sysconf) + AC_DEFINE([TUKLIB_CPUCORES_SYSCONF], [1], + [Define to 1 if the number of available CPU cores + can be detected with sysconf(_SC_NPROCESSORS_ONLN) + or sysconf(_SC_NPROC_ONLN).]) + ;; + pstat_getdynamic) + AC_DEFINE([TUKLIB_CPUCORES_PSTAT_GETDYNAMIC], [1], + [Define to 1 if the number of available CPU cores + can be detected with pstat_getdynamic().]) + ;; +esac +])dnl diff --git a/cpp/third_party/xz-5.8.3/m4/tuklib_integer.m4 b/cpp/third_party/xz-5.8.3/m4/tuklib_integer.m4 new file mode 100644 index 000000000..29f2c95f8 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/tuklib_integer.m4 @@ -0,0 +1,260 @@ +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# SYNOPSIS +# +# TUKLIB_INTEGER +# +# DESCRIPTION +# +# Checks for tuklib_integer.h: +# - Endianness +# - Does the compiler or the operating system provide byte swapping macros +# - Does the hardware support fast unaligned access to 16-bit, 32-bit, +# and 64-bit integers +# +############################################################################# +# +# Author: Lasse Collin +# +############################################################################# + +AC_DEFUN_ONCE([TUKLIB_INTEGER], [ +AC_REQUIRE([TUKLIB_COMMON]) +AC_REQUIRE([AC_C_BIGENDIAN]) + +AC_MSG_CHECKING([if __builtin_bswap16/32/64 are supported]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], + [[__builtin_bswap16(1); + __builtin_bswap32(1); + __builtin_bswap64(1);]])], +[ + AC_DEFINE([HAVE___BUILTIN_BSWAPXX], [1], + [Define to 1 if the GNU C extensions + __builtin_bswap16/32/64 are supported.]) + AC_MSG_RESULT([yes]) +], [ + AC_MSG_RESULT([no]) + + # Look for other byteswapping methods. + AC_CHECK_HEADERS([byteswap.h sys/endian.h sys/byteorder.h], [break]) + + # Even if we have byteswap.h we may lack the specific macros/functions. + if test x$ac_cv_header_byteswap_h = xyes ; then + m4_foreach([FUNC], [bswap_16,bswap_32,bswap_64], [ + AC_MSG_CHECKING([if FUNC is available]) + AC_LINK_IFELSE([AC_LANG_SOURCE([ +#include +int +main(void) +{ + FUNC[](42); + return 0; +} + ])], [ + AC_DEFINE(HAVE_[]m4_toupper(FUNC), [1], + [Define to 1 if] FUNC [is available.]) + AC_MSG_RESULT([yes]) + ], [AC_MSG_RESULT([no])]) + + ])dnl + fi +]) + +# On archs that we use tuklib_integer_strict_align() (see below), we need +# objdump to detect support for unaligned access. (Libtool needs objdump +# too, so Libtool does this same tool check as well.) +AC_CHECK_TOOL([OBJDUMP], [objdump], [false]) + +# An internal helper that attempts to detect if -mstrict-align or +# -mno-strict-align is in effect. This sets enable_unaligned_access=yes +# if compilation succeeds and the regex passed as an argument does *not* +# match the objdump output of a check program. Otherwise this sets +# enable_unaligned_access=no. +tuklib_integer_strict_align () +{ + # First guess no. + enable_unaligned_access=no + + # Force -O2 because without optimizations the memcpy() + # won't be optimized out. + tuklib_integer_saved_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -O2" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #include + unsigned int check_strict_align(const void *p) + { + unsigned int i; + memcpy(&i, p, sizeof(i)); + return i; + } + ]])], [ + # Disassemble the test function from the object file. + if $OBJDUMP -d conftest.$ac_objext > conftest.s ; then + # This function should be passed a regex that + # matches if there are instructions that load + # unsigned bytes. Such instructions indicate + # that -mstrict-align is in effect. + # + # NOTE: Use braces to avoid M4 parameter + # expansion. + if grep -- "${1}" conftest.s > /dev/null ; then + : + else + # No single-byte unsigned load + # instructions were found, + # so it seems that -mno-strict-align + # is in effect. + # Override our earlier guess. + enable_unaligned_access=yes + fi + fi + ]) + CFLAGS=$tuklib_integer_saved_CFLAGS +} + +AC_MSG_CHECKING([if unaligned memory access should be used]) +AC_ARG_ENABLE([unaligned-access], AS_HELP_STRING([--enable-unaligned-access], + [Enable if the system supports *fast* unaligned memory access + with 16-bit, 32-bit, and 64-bit integers. By default, + this is enabled on x86, x86-64, + 32/64-bit big endian PowerPC, + 64-bit little endian PowerPC, + and some ARM, ARM64, and RISC-V systems.]), + [], [enable_unaligned_access=auto]) +if test "x$enable_unaligned_access" = xauto ; then + # NOTE: There might be other architectures on which unaligned access + # is fast. + case $host_cpu in + i?86|x86_64|powerpc|powerpc64|powerpc64le) + enable_unaligned_access=yes + ;; + arm*|riscv*) + # On 32-bit ARM, GCC and Clang + # #define __ARM_FEATURE_UNALIGNED + # if and only if unaligned access is supported. + # + # RISC-V C API Specification says that if + # __riscv_misaligned_fast is defined then + # unaligned access is known to be fast. + # + # MSVC is handled as a special case: We assume that + # 32-bit ARM supports fast unaligned access. + # If MSVC gets RISC-V support then this will assume + # fast unaligned access on RISC-V too. + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + #if !defined(__ARM_FEATURE_UNALIGNED) \ + && !defined(__riscv_misaligned_fast) \ + && !defined(_MSC_VER) + compile error + #endif + int main(void) { return 0; } + ])], + [enable_unaligned_access=yes], + [enable_unaligned_access=no]) + ;; + aarch64*) + # On ARM64, Clang defines __ARM_FEATURE_UNALIGNED + # if and only if unaligned access is supported. + # However, GCC (at least up to 15.2.0) defines it + # even when using -mstrict-align, so autodetection + # with this macro doesn't work with GCC on ARM64. + # (It does work on 32-bit ARM.) See: + # + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111555 + # + # We need three checks: + # + # 1. If __ARM_FEATURE_UNALIGNED is defined and the + # compiler isn't GCC, unaligned access is enabled. + # If the compiler is MSVC, unaligned access is + # enabled even without __ARM_FEATURE_UNALIGNED. + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + #if defined(__ARM_FEATURE_UNALIGNED) \ + && (!defined(__GNUC__) \ + || defined(__clang__)) + #elif defined(_MSC_VER) + #else + compile error + #endif + int main(void) { return 0; } + ])], [enable_unaligned_access=yes]) + + # 2. If __ARM_FEATURE_UNALIGNED is not defined, + # unaligned access is disabled. + if test "x$enable_unaligned_access" = xauto ; then + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + #ifdef __ARM_FEATURE_UNALIGNED + compile error + #endif + int main(void) { return 0; } + ])], [enable_unaligned_access=no]) + fi + + # 3. Use heuristics to detect if -mstrict-align is + # in effect when building with GCC. + if test "x$enable_unaligned_access" = xauto ; then + [tuklib_integer_strict_align \ + '[[:blank:]]ldrb[[:blank:]]'] + fi + ;; + loongarch*) + # See sections 7.4, 8.1, and 8.2: + # https://github.com/loongson/la-softdev-convention/blob/v0.2/la-softdev-convention.adoc + # + # That is, desktop and server processors likely support + # unaligned access in hardware but embedded processors + # might not. GCC defaults to -mno-strict-align and so + # do majority of GNU/Linux distributions. As of + # GCC 15.2, there is no predefined macro to detect + # if -mstrict-align or -mno-strict-align is in effect. + # Use heuristics based on compiler output. + [ + tuklib_integer_strict_align \ + '[[:blank:]]ld\.bu[[:blank:]]' + ] + ;; + *) + enable_unaligned_access=no + ;; + esac +fi +if test "x$enable_unaligned_access" = xyes ; then + AC_DEFINE([TUKLIB_FAST_UNALIGNED_ACCESS], [1], [Define to 1 if + the system supports fast unaligned access to 16-bit, + 32-bit, and 64-bit integers.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_MSG_CHECKING([if unsafe type punning should be used]) +AC_ARG_ENABLE([unsafe-type-punning], + AS_HELP_STRING([--enable-unsafe-type-punning], + [This introduces strict aliasing violations and may result + in broken code. However, this might improve performance in + some cases, especially with old compilers (e.g. + GCC 3 and early 4.x on x86, GCC < 6 on ARMv6 and ARMv7).]), + [], [enable_unsafe_type_punning=no]) +if test "x$enable_unsafe_type_punning" = xyes ; then + AC_DEFINE([TUKLIB_USE_UNSAFE_TYPE_PUNNING], [1], [Define to 1 to use + unsafe type punning, e.g. char *x = ...; *(int *)x = 123; + which violates strict aliasing rules and thus is + undefined behavior and might result in broken code.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_MSG_CHECKING([if __builtin_assume_aligned is supported]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[__builtin_assume_aligned("", 1);]])], + [ + AC_DEFINE([HAVE___BUILTIN_ASSUME_ALIGNED], [1], + [Define to 1 if the GNU C extension + __builtin_assume_aligned is supported.]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +])dnl diff --git a/cpp/third_party/xz-5.8.3/m4/tuklib_mbstr.m4 b/cpp/third_party/xz-5.8.3/m4/tuklib_mbstr.m4 new file mode 100644 index 000000000..98b1d7a3d --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/tuklib_mbstr.m4 @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# SYNOPSIS +# +# TUKLIB_MBSTR +# +# DESCRIPTION +# +# Check if multibyte and wide character functionality is available +# for use by tuklib_mbstr_* functions. If not enough multibyte string +# support is available in the C library, the functions keep working +# with the assumption that all strings are a in single-byte character +# set without combining characters, e.g. US-ASCII or ISO-8859-*. +# +# This .m4 file and tuklib_mbstr.h are common to all tuklib_mbstr_* +# functions, but each function is put into a separate .c file so +# that it is possible to pick only what is strictly needed. +# +############################################################################# +# +# Author: Lasse Collin +# +############################################################################# + +AC_DEFUN_ONCE([TUKLIB_MBSTR], [ +AC_REQUIRE([TUKLIB_COMMON]) +AC_FUNC_MBRTOWC +AC_CHECK_FUNCS([wcwidth vasprintf]) +])dnl diff --git a/cpp/third_party/xz-5.8.3/m4/tuklib_physmem.m4 b/cpp/third_party/xz-5.8.3/m4/tuklib_physmem.m4 new file mode 100644 index 000000000..4bffe858a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/tuklib_physmem.m4 @@ -0,0 +1,217 @@ +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# SYNOPSIS +# +# TUKLIB_PHYSMEM +# +# DESCRIPTION +# +# Check how to get the amount of physical memory. +# This information is used in tuklib_physmem.c. +# +# Supported methods: +# +# - Windows (including Cygwin), OS/2, DJGPP (DOS), OpenVMS, AROS, +# and QNX have operating-system specific functions. +# +# - AIX has _system_configuration.physmem. +# +# - sysconf() works on GNU/Linux and Solaris, and possibly on +# some BSDs. +# +# - BSDs use sysctl(). +# +# - Tru64 uses getsysinfo(). +# +# - HP-UX uses pstat_getstatic(). +# +# - IRIX has setinvent_r(), getinvent_r(), and endinvent_r(). +# +# - sysinfo() works on Linux/dietlibc and probably on other Linux +# systems whose libc may lack sysconf(). +# +############################################################################# +# +# Author: Lasse Collin +# +############################################################################# + +AC_DEFUN_ONCE([TUKLIB_PHYSMEM], [ +AC_REQUIRE([TUKLIB_COMMON]) + +# sys/param.h might be needed by sys/sysctl.h. +AC_CHECK_HEADERS([sys/param.h]) + +AC_CACHE_CHECK([how to detect the amount of physical memory], + [tuklib_cv_physmem_method], [ + +# Maybe checking $host_os would be enough but this matches what +# tuklib_physmem.c does. +# +# NOTE: IRIX has a compiler that doesn't error out with #error, so use +# a non-compilable text instead of #error to generate an error. +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__OS2__) \ + || defined(__DJGPP__) || defined(__VMS) \ + || defined(AMIGA) || defined(__AROS__) || defined(__QNX__) +int main(void) { return 0; } +#else +compile error +#endif +]])], [tuklib_cv_physmem_method=special], [ + +# Look for AIX-specific solution before sysconf(), because the test +# for sysconf() will pass on AIX but won't actually work +# (sysconf(_SC_PHYS_PAGES) compiles but always returns -1 on AIX). +# +# NOTE: There is no need to link the check program because it's not calling +# any functions and thus implicit function declarations aren't a problem. +# The unused reference to _system_configuration.physmem might get optimized +# away, and thus the linker might not see that symbol anyway. +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include + +int +main(void) +{ + (void)_system_configuration.physmem; + return 0; +} +]])], [tuklib_cv_physmem_method=aix], [ + +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +int +main(void) +{ + long i; + i = sysconf(_SC_PAGESIZE); + i = sysconf(_SC_PHYS_PAGES); + return 0; +} +]])], [tuklib_cv_physmem_method=sysconf], [ + +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#ifdef HAVE_SYS_PARAM_H +# include +#endif +#include +int +main(void) +{ + int name[2] = { CTL_HW, HW_PHYSMEM }; + unsigned long mem; + size_t mem_ptr_size = sizeof(mem); + sysctl(name, 2, &mem, &mem_ptr_size, NULL, 0); + return 0; +} +]])], [tuklib_cv_physmem_method=sysctl], [ + +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +#include + +int +main(void) +{ + int memkb; + int start = 0; + getsysinfo(GSI_PHYSMEM, (caddr_t)&memkb, sizeof(memkb), &start); + return 0; +} +]])], [tuklib_cv_physmem_method=getsysinfo],[ + +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +#include + +int +main(void) +{ + struct pst_static pst; + pstat_getstatic(&pst, sizeof(pst), 1, 0); + (void)pst.physical_memory; + (void)pst.page_size; + return 0; +} +]])], [tuklib_cv_physmem_method=pstat_getstatic],[ + +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +int +main(void) +{ + inv_state_t *st = NULL; + setinvent_r(&st); + getinvent_r(st); + endinvent_r(st); + return 0; +} +]])], [tuklib_cv_physmem_method=getinvent_r], [ + +# This version of sysinfo() is Linux-specific. Some non-Linux systems have +# different sysinfo() so we must check $host_os. +case $host_os in + linux*) + AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +int +main(void) +{ + struct sysinfo si; + sysinfo(&si); + return 0; +} + ]])], [ + tuklib_cv_physmem_method=sysinfo + ], [ + tuklib_cv_physmem_method=unknown + ]) + ;; + *) + tuklib_cv_physmem_method=unknown + ;; +esac +])])])])])])])]) + +case $tuklib_cv_physmem_method in + aix) + AC_DEFINE([TUKLIB_PHYSMEM_AIX], [1], + [Define to 1 if the amount of physical memory + can be detected with _system_configuration.physmem.]) + ;; + sysconf) + AC_DEFINE([TUKLIB_PHYSMEM_SYSCONF], [1], + [Define to 1 if the amount of physical memory can + be detected with sysconf(_SC_PAGESIZE) and + sysconf(_SC_PHYS_PAGES).]) + ;; + sysctl) + AC_DEFINE([TUKLIB_PHYSMEM_SYSCTL], [1], + [Define to 1 if the amount of physical memory can + be detected with sysctl().]) + ;; + getsysinfo) + AC_DEFINE([TUKLIB_PHYSMEM_GETSYSINFO], [1], + [Define to 1 if the amount of physical memory can + be detected with getsysinfo().]) + ;; + pstat_getstatic) + AC_DEFINE([TUKLIB_PHYSMEM_PSTAT_GETSTATIC], [1], + [Define to 1 if the amount of physical memory can + be detected with pstat_getstatic().]) + ;; + getinvent_r) + AC_DEFINE([TUKLIB_PHYSMEM_GETINVENT_R], [1], + [Define to 1 if the amount of physical memory + can be detected with getinvent_r().]) + ;; + sysinfo) + AC_DEFINE([TUKLIB_PHYSMEM_SYSINFO], [1], + [Define to 1 if the amount of physical memory + can be detected with Linux sysinfo().]) + ;; +esac +])dnl diff --git a/cpp/third_party/xz-5.8.3/m4/tuklib_progname.m4 b/cpp/third_party/xz-5.8.3/m4/tuklib_progname.m4 new file mode 100644 index 000000000..b70d063ff --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/tuklib_progname.m4 @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# SYNOPSIS +# +# TUKLIB_PROGNAME +# +# DESCRIPTION +# +# Put argv[0] into a global variable progname. On DOS-like systems, +# modify it so that it looks nice (no full path or .exe suffix). +# +# This .m4 file is needed allow this module to use glibc's +# program_invocation_name. +# +############################################################################# +# +# Author: Lasse Collin +# +############################################################################# + +AC_DEFUN_ONCE([TUKLIB_PROGNAME], [ +AC_REQUIRE([TUKLIB_COMMON]) +AC_CHECK_DECL([program_invocation_name], [AC_DEFINE( + [HAVE_PROGRAM_INVOCATION_NAME], [1], + [Define to 1 if 'program_invocation_name' is declared in .])], + [], [#include ]) +])dnl diff --git a/cpp/third_party/xz-5.8.3/m4/visibility.m4 b/cpp/third_party/xz-5.8.3/m4/visibility.m4 new file mode 100644 index 000000000..4a741c5ea --- /dev/null +++ b/cpp/third_party/xz-5.8.3/m4/visibility.m4 @@ -0,0 +1,85 @@ +dnl SPDX-License-Identifier: FSFULLR + +# visibility.m4 +# serial 9 +dnl Copyright (C) 2005, 2008, 2010-2024 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 Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl Mac OS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +AC_DEFUN([gl_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + CFLAG_VISIBILITY= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + dnl First, check whether -Werror can be added to the command line, or + dnl whether it leads to an error because of some other option that the + dnl user has put into $CC $CFLAGS $CPPFLAGS. + AC_CACHE_CHECK([whether the -Werror option is usable], + [gl_cv_cc_vis_werror], + [gl_saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [gl_cv_cc_vis_werror=yes], + [gl_cv_cc_vis_werror=no]) + CFLAGS="$gl_saved_CFLAGS" + ]) + dnl Now check whether visibility declarations are supported. + AC_CACHE_CHECK([for simple visibility declarations], + [gl_cv_cc_visibility], + [gl_saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + dnl We use the option -Werror and a function dummyfunc, because on some + dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning + dnl "visibility attribute not supported in this configuration; ignored" + dnl at the first function definition in every compilation unit, and we + dnl don't want to use the option in this case. + if test $gl_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void); + int hiddenvar; + int exportedvar; + int hiddenfunc (void) { return 51; } + int exportedfunc (void) { return 1225736919; } + void dummyfunc (void) {} + ]], + [[]])], + [gl_cv_cc_visibility=yes], + [gl_cv_cc_visibility=no]) + CFLAGS="$gl_saved_CFLAGS" + ]) + if test $gl_cv_cc_visibility = yes; then + CFLAG_VISIBILITY="-fvisibility=hidden" + HAVE_VISIBILITY=1 + fi + fi + AC_SUBST([CFLAG_VISIBILITY]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) +]) diff --git a/cpp/third_party/xz-5.8.3/po/LINGUAS b/cpp/third_party/xz-5.8.3/po/LINGUAS new file mode 100644 index 000000000..67e9a8b9a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/LINGUAS @@ -0,0 +1,25 @@ +ca +cs +da +de +eo +es +fi +fr +hr +hu +it +ka +ko +nl +pl +pt +pt_BR +ro +sr +sv +tr +uk +vi +zh_CN +zh_TW diff --git a/cpp/third_party/xz-5.8.3/po/Makefile.in.in b/cpp/third_party/xz-5.8.3/po/Makefile.in.in new file mode 100644 index 000000000..acff1e1be --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/Makefile.in.in @@ -0,0 +1,517 @@ +# Makefile for PO directory in any package using GNU gettext. +# Copyright (C) 1995-2000 Ulrich Drepper +# Copyright (C) 2000-2024 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 any warranty. +# +# Origin: gettext-0.23 +GETTEXT_MACRO_VERSION = 0.22 + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + +SED = @SED@ +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +datadir = @datadir@ +localedir = @localedir@ +gettextsrcdir = $(datadir)/gettext/po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +# We use $(mkdir_p). +# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as +# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, +# @install_sh@ does not start with $(SHELL), so we add it. +# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined +# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake +# versions, $(mkinstalldirs) and $(install_sh) are unused. +mkinstalldirs = $(SHELL) @install_sh@ -d +install_sh = $(SHELL) @install_sh@ +MKDIR_P = @MKDIR_P@ +mkdir_p = @mkdir_p@ + +# When building gettext-tools, we prefer to use the built programs +# rather than installed programs. However, we can't do that when we +# are cross compiling. +CROSS_COMPILING = @CROSS_COMPILING@ + +GMSGFMT_ = @GMSGFMT@ +GMSGFMT_no = @GMSGFMT@ +GMSGFMT_yes = @GMSGFMT_015@ +GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) +XGETTEXT_ = @XGETTEXT@ +XGETTEXT_no = @XGETTEXT@ +XGETTEXT_yes = @XGETTEXT_015@ +XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +MSGMERGE = @MSGMERGE@ +MSGMERGE_UPDATE = @MSGMERGE@ --update +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +UPDATEPOFILES = @UPDATEPOFILES@ +DUMMYPOFILES = @DUMMYPOFILES@ +DISTFILES.common = Makefile.in.in remove-potcdate.sed \ +$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) +DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ +$(POFILES) $(GMOFILES) \ +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) + +POTFILES = \ + +CATALOGS = @CATALOGS@ + +POFILESDEPS_ = $(srcdir)/$(DOMAIN).pot +POFILESDEPS_yes = $(POFILESDEPS_) +POFILESDEPS_no = +POFILESDEPS = $(POFILESDEPS_$(PO_DEPENDS_ON_POT)) + +DISTFILESDEPS_ = update-po +DISTFILESDEPS_yes = $(DISTFILESDEPS_) +DISTFILESDEPS_no = +DISTFILESDEPS = $(DISTFILESDEPS_$(DIST_DEPENDS_ON_UPDATE_PO)) + +# Makevars gets inserted here. (Don't remove this line!) + +all: all-@USE_NLS@ + + +.SUFFIXES: +.SUFFIXES: .po .gmo .sed .nop .po-create .po-update + +# The .pot file, stamp-po, .po files, and .gmo files appear in release tarballs. +# The GNU Coding Standards say in +# : +# "GNU distributions usually contain some files which are not source files +# ... . Since these files normally appear in the source directory, they +# should always appear in the source directory, not in the build directory. +# So Makefile rules to update them should put the updated files in the +# source directory." +# Therefore we put these files in the source directory, not the build directory. + +# During .po -> .gmo conversion, take into account the most recent changes to +# the .pot file. This eliminates the need to update the .po files when the +# .pot file has changed, which would be troublesome if the .po files are put +# under version control. +$(GMOFILES): $(srcdir)/$(DOMAIN).pot +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + if test "$(PACKAGE)" = "gettext-tools" && test "$(CROSS_COMPILING)" != "yes"; then PATH=`pwd`/../src:$$PATH; fi; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) -o $${lang}.1po $${lang}.po $(DOMAIN).pot && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.1po && rm -f $${lang}.1po"; \ + cd $(srcdir) && \ + rm -f $${lang}.gmo && \ + $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) -o $${lang}.1po $${lang}.po $(DOMAIN).pot && \ + $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.1po && \ + mv t-$${lang}.gmo $${lang}.gmo && \ + rm -f $${lang}.1po + + +all-yes: $(srcdir)/stamp-po +all-no: + +# Ensure that the gettext macros and this Makefile.in.in are in sync. +CHECK_MACRO_VERSION = \ + test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ + || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ + exit 1; \ + } + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, $(srcdir)/stamp-po is a nop (i.e. a phony target). + +# $(srcdir)/stamp-po is a timestamp denoting the last time at which the CATALOGS +# have been loosely updated. Its purpose is that when a developer or translator +# checks out the package from a version control system, and the $(DOMAIN).pot +# file is not under version control, "make" will update the $(DOMAIN).pot and +# the $(CATALOGS), but subsequent invocations of "make" will do nothing. This +# timestamp would not be necessary if updating the $(CATALOGS) would always +# touch them; however, the rule for $(POFILES) has been designed to not touch +# files that don't need to be changed. +$(srcdir)/stamp-po: $(srcdir)/$(DOMAIN).pot + @$(CHECK_MACRO_VERSION) + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch $(srcdir)/stamp-po" && \ + echo timestamp > $(srcdir)/stamp-poT && \ + mv $(srcdir)/stamp-poT $(srcdir)/stamp-po; \ + } + +# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', +# otherwise packages like GCC can not be built if only parts of the source +# have been downloaded. + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +# The determination of whether the package xyz is a GNU one is based on the +# heuristic whether some file in the top level directory mentions "GNU xyz". +# If GNU 'find' is available, we avoid grepping through monster files. +$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in + package_gnu="$(PACKAGE_GNU)"; \ + test -n "$$package_gnu" || { \ + if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \ + LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep -i 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \ + else \ + LC_ALL=C grep -i 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \ + fi; \ + } | grep -v 'libtool:' >/dev/null; then \ + package_gnu=yes; \ + else \ + package_gnu=no; \ + fi; \ + }; \ + if test "$$package_gnu" = "yes"; then \ + package_prefix='GNU '; \ + else \ + package_prefix=''; \ + fi; \ + if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_prefix}@PACKAGE@" \ + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + ;; \ + esac + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot-header; then \ + sed -e '1,/^#$$/d' < $(DOMAIN).po > $(DOMAIN).1po && \ + cat $(srcdir)/$(DOMAIN).pot-header $(DOMAIN).1po > $(DOMAIN).po && \ + rm -f $(DOMAIN).1po \ + || exit 1; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f $(srcdir)/remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f $(srcdir)/remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(POFILESDEPS) + @test -f $(srcdir)/$(DOMAIN).pot || $(MAKE) $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + if test "$(PACKAGE)" = "gettext-tools" && test "$(CROSS_COMPILING)" != "yes"; then PATH=`pwd`/../src:$$PATH; fi; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) --quiet $(MSGMERGE_OPTIONS) --lang=$${lang} --previous $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) \ + && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.10 | 0.10.*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + 0.1[1-5] | 0.1[1-5].*) \ + $(MSGMERGE_UPDATE) --quiet $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + 0.1[6-7] | 0.1[6-7].*) \ + $(MSGMERGE_UPDATE) --quiet $(MSGMERGE_OPTIONS) --previous $${lang}.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE_UPDATE) --quiet $(MSGMERGE_OPTIONS) --lang=$${lang} --previous $${lang}.po $(DOMAIN).pot;; \ + esac; \ + }; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + for file in $(DISTFILES.common) Makevars.template; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + for file in Makevars; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +install-data-no: all +install-data-yes: all + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +install-strip: install + +installdirs: installdirs-exec installdirs-data +installdirs-exec: +installdirs-data: installdirs-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi +installdirs-data-no: +installdirs-data-yes: + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: uninstall-exec uninstall-data +uninstall-exec: +uninstall-data: uninstall-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in $(DISTFILES.common) Makevars.template; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +uninstall-data-no: +uninstall-data-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +check: all + +info dvi ps pdf html tags TAGS ctags CTAGS ID: + +install-dvi install-ps install-pdf install-html: + +mostlyclean: + rm -f $(srcdir)/stamp-poT + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(srcdir)/$(DOMAIN).pot $(srcdir)/stamp-po $(GMOFILES) + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: + test -z "$(DISTFILESDEPS)" || $(MAKE) $(DISTFILESDEPS) + @$(MAKE) dist2 +# This is a separate target because 'update-po' must be executed before. +dist2: $(srcdir)/stamp-po $(DISTFILES) + @dists="$(DISTFILES)"; \ + if test "$(PACKAGE)" = "gettext-tools"; then \ + dists="$$dists Makevars.template"; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + dists="$$dists $(DOMAIN).pot stamp-po"; \ + else \ + case $(XGETTEXT) in \ + :) echo "Warning: Creating a tarball without '$(DOMAIN).pot', because a suitable 'xgettext' program was not found in PATH." 1>&2;; \ + *) echo "Warning: Creating a tarball without '$(DOMAIN).pot', because 'xgettext' found no strings to extract. Check the contents of the POTFILES.in file and the XGETTEXT_OPTIONS in the Makevars file." 1>&2;; \ + esac; \ + fi; \ + if test -f $(srcdir)/ChangeLog; then \ + dists="$$dists ChangeLog"; \ + fi; \ + for i in 0 1 2 3 4 5 6 7 8 9; do \ + if test -f $(srcdir)/ChangeLog.$$i; then \ + dists="$$dists ChangeLog.$$i"; \ + fi; \ + done; \ + if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ + for file in $$dists; do \ + if test -f $$file; then \ + cp -p $$file $(distdir) || exit 1; \ + else \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + fi; \ + done + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools" && test "$(CROSS_COMPILING)" != "yes"; then PATH=`pwd`/../src:$$PATH; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) --quiet $(MSGMERGE_OPTIONS) --lang=$$lang --previous $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.10 | 0.10.*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + 0.1[1-5] | 0.1[1-5].*) \ + $(MSGMERGE) --quiet $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + 0.1[6-7] | 0.1[6-7].*) \ + $(MSGMERGE) --quiet $(MSGMERGE_OPTIONS) --previous -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE) --quiet $(MSGMERGE_OPTIONS) --lang=$$lang --previous -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + esac; \ + }; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: + +# Recreate Makefile by invoking config.status. Explicitly invoke the shell, +# because execution permission bits may not work on the current file system. +# Use @SHELL@, which is the shell determined by autoconf for the use by its +# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. +Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ + cd $(top_builddir) \ + && @SHELL@ ./config.status $(subdir)/$@.in po-directories + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# This Makefile contains rules which don't work with parallel make, +# namely dist2. +# See . +# So, turn off parallel execution in this Makefile. +.NOTPARALLEL: diff --git a/cpp/third_party/xz-5.8.3/po/Makevars b/cpp/third_party/xz-5.8.3/po/Makevars new file mode 100644 index 000000000..b2d8a7cfb --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/Makevars @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: FSFUL + +# Makefile variables for PO directory in any package using GNU gettext. +# +# Copyright (C) 2003-2019 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation gives +# unlimited permission to use, copy, distribute, and modify it. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --add-location=file --no-wrap --keyword=_ --keyword=N_ '--keyword=W_:1,"This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care."' + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = The XZ Utils authors and contributors + +# This tells whether or not to prepend "GNU " prefix to the package +# name that gets inserted into the header of the $(DOMAIN).pot file. +# Possible values are "yes", "no", or empty. If it is empty, try to +# detect it automatically by scanning the files in $(top_srcdir) for +# "GNU packagename" string. +PACKAGE_GNU = no + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = + +# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' +# context. Possible values are "yes" and "no". Set this to yes if the +# package uses functions taking also a message context, like pgettext(), or +# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. +USE_MSGCTXT = no + +# These options get passed to msgmerge. +# Useful options are in particular: +# --previous to keep previous msgids of translated messages, +# --quiet to reduce the verbosity. +MSGMERGE_OPTIONS = --add-location=file --no-wrap + +# These options get passed to msginit. +# If you want to disable line wrapping when writing PO files, add +# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and +# MSGINIT_OPTIONS. +# +# Although one may need slightly wider terminal than 80 chars, it is +# much nicer to edit the output of --help when --no-wrap is set. +MSGINIT_OPTIONS = --no-wrap + +# This tells whether or not to regenerate a PO file when $(DOMAIN).pot +# has changed. Possible values are "yes" and "no". Set this to no if +# the POT file is checked in the repository and the version control +# program ignores timestamps. +PO_DEPENDS_ON_POT = yes + +# This tells whether or not to forcibly update $(DOMAIN).pot and +# regenerate PO files on "make dist". Possible values are "yes" and +# "no". Set this to no if the POT file and PO files are maintained +# externally. +# +# NOTE: The the custom "mydist" target in ../Makefile.am updates xz.pot. +# An updated xz.pot will cause the .po files to be updated too but +# only when updating would change more than the POT-Creation-Date line. +DIST_DEPENDS_ON_UPDATE_PO = no diff --git a/cpp/third_party/xz-5.8.3/po/POTFILES.in b/cpp/third_party/xz-5.8.3/po/POTFILES.in new file mode 100644 index 000000000..dead5ed43 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/POTFILES.in @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: 0BSD + +# List of source files which contain translatable strings. +src/xz/args.c +src/xz/coder.c +src/xz/file_io.c +src/xz/hardware.c +src/xz/list.c +src/xz/main.c +src/xz/message.c +src/xz/mytime.c +src/xz/options.c +src/xz/sandbox.c +src/xz/signals.c +src/xz/suffix.c +src/xz/util.c +src/lzmainfo/lzmainfo.c +src/common/tuklib_exit.c +src/liblzma/common/string_conversion.c diff --git a/cpp/third_party/xz-5.8.3/po/Rules-quot b/cpp/third_party/xz-5.8.3/po/Rules-quot new file mode 100644 index 000000000..9e1305407 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/Rules-quot @@ -0,0 +1,66 @@ +# Special Makefile rules for English message catalogs with quotation marks. +# +# Copyright (C) 2001-2024 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 file is offered as-is, without any warranty. +# +# Written by Bruno Haible , 2001. + +DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sed Rules-quot + +.SUFFIXES: .insert-header .po-update-en + +en@quot.po-create: + $(MAKE) en@quot.po-update +en@boldquot.po-create: + $(MAKE) en@boldquot.po-update + +en@quot.po-update: en@quot.po-update-en +en@boldquot.po-update: en@boldquot.po-update-en + +.insert-header.po-update-en: + @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools" && test "$(CROSS_COMPILING)" != "yes"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + ll=`echo $$lang | sed -e 's/@.*//'`; \ + LC_ALL=C; export LC_ALL; \ + cd $(srcdir); \ + if $(MSGINIT) $(MSGINIT_OPTIONS) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null \ + | $(SED) -f $$tmpdir/$$lang.insert-header | $(SED) -e '/^%%/d' \ + | $(MSGCONV) -t UTF-8 | \ + { case `$(MSGFILTER) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-8] | 0.1[0-8].*) \ + $(MSGFILTER) $(SED) -f `echo $$lang | sed -e 's/.*@//'`.sed \ + ;; \ + *) \ + $(MSGFILTER) `echo $$lang | sed -e 's/.*@//'` \ + ;; \ + esac } 2>/dev/null > $$tmpdir/$$lang.new.po \ + ; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "creation of $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +en@quot.insert-header: insert-header.sed + sed -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sed > en@quot.insert-header + +en@boldquot.insert-header: insert-header.sed + sed -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sed > en@boldquot.insert-header + +mostlyclean: mostlyclean-quot +mostlyclean-quot: + rm -f *.insert-header diff --git a/cpp/third_party/xz-5.8.3/po/boldquot.sed b/cpp/third_party/xz-5.8.3/po/boldquot.sed new file mode 100644 index 000000000..3c1de54e6 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/boldquot.sed @@ -0,0 +1,21 @@ +# Sed script that converts quotations, by replacing ASCII quotation marks +# with Unicode quotation marks and highlighting the quotations in bold face. +# +# Copyright (C) 2001 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 file is offered as-is, without any warranty. +# +# Written by Bruno Haible , 2001. +# +s/"\([^"]*\)"/“\1â€/g +s/`\([^`']*\)'/‘\1’/g +s/ '\([^`']*\)' / ‘\1’ /g +s/ '\([^`']*\)'$/ ‘\1’/g +s/^'\([^`']*\)' /‘\1’ /g +s/“â€/""/g +s/“/“/g +s/â€/â€/g +s/‘/‘/g +s/’/’/g diff --git a/cpp/third_party/xz-5.8.3/po/ca.gmo b/cpp/third_party/xz-5.8.3/po/ca.gmo new file mode 100644 index 0000000000000000000000000000000000000000..4670cf7d2f22d967a5e4aba44e4593d347ef21ce GIT binary patch literal 15587 zcmb`Nd2n4^)ffAasWysVGbP{TqPLpAvgwnyUEoFdCTguRlc38r|bl{INg|@>C{d~_k z_brkvJ2ZE6-uEtN`JLZ(e&=`eZ_i)%!Dj?P@E~QF5}X?Z-vIvhIYIDD@Z}dc+yd^P z==vBq1U>}r1iuD8A3W#6AXo>!2s{sb8Tdl*Qt;QoT^?@+2Y7x9cnSCkkADHalIQP( zuLjS#CE*(clh@o0=Mw|SD?oEDYyfC&U1s{a`0O4WndM21$Ym5G58Sp za_}>t0sr3PPr(JAH!z6ib2nH4?+0H6eic-|{|UYnyqHScz-^%Vi$HyU8~6h75m0nJ z0bT?C9k?C5kdJ%7>p=1EUa$Z^3)a9b8ysC901-#<7$|;z4ty5)=l=Vb!AYKf2&&#L z22;Ij!DoY`;CgVvKfe(i;&~Rl0{j4|d3*_E>cPK)BjAt0VepC6N^Vz!F9B}@cY{ly`0*Lg@)O*}^TjmU2~L5c>s_F} zKMd{wzYJ>rzW_Dgb#w};!Fo{hHsBaI0K$?W0XKnf2c>_X0!827fTH_b;ML#{K#gbk zQM=us^koW^4J4rEeJ8jMd>GVxAMyA(Q1br@sCoSW6rGo$e4_I;py=BQ-VE*n9|j)) zQKeufjrIKihzbXjpy<2}+zT#%yTDI^Q{Z>OYr*XhDLH1~Rp7(me(;~cSAmycOtOzL z5OWT4P;}i5N-p<-20RH$zFz~SFaHFhs=@a`L=*fRl<8lDvFiIPJZ|#1-Q%?$$3cxZ zycNJl z!5rKU{sE}=-vnhB>tU|w-vKg2a2qH&y%kjbKk?t61X1PSxlC>=xEWMGZvr*W{h;*o zB&dF$1SQXl2Ap1B1FBvGq7uQqAS472flMJd1>OVx0Ms~ho1EU<1JYISMNt0WNf1>G zHZaH@a2VuOkbu(r4}%)#uR-gSUX^gI@-vcmDuB8~iS~9{dmg{4=n^^Dja1se({6{{obK zeiRg4e*}vEKLJO;S2F4I!P~+8U<2F+J_gGEo&?3O{{l7Mg*4XuUjn`s+yRO&1$Z0y zhv4ntxx7TA!5laPz85?Keg_o4uR_R@^R4_`1Ktll3;eprZ-N@<+n~n%Z}2AY9EjTh zz8O?McY=r@_y{PzoC4(szY41UcR=y8g0kTXf;mw0c?bAR@FDO3cmg~J{1GU9|1tP{ za2-mBsRb8Wg(2ui*= zD7xs@yPaN5gW}Jlpyc;0@J8@o zK-^jIUP^h%9u4Kz@{Bh$4P#?A}W@f@p#!CHEgR5An43lI<;0Hc&33 zNM_q9(wTLX3n}xI>nP==dCNz>hw>K68z>Q_yf6W)D|(J8;)AX?Q_iDorrbo4UP!i6 zlm$w89pdH=%DLqW@I#b)d!EI+W0b>`_fdYA@+Jyww-@Sa*Av)luiy4~yGQ8~s&8%U z^`K<>0A(+wph&lGrs(<&2fuGC<$eZvP97(-O=?T2YtVH z@+6(mb(I6_`yS-JLHRxZF7)_O@Ol3J1K>535BukPz+3$N1>pUZS5u_ZbCedPN-3|5 zn^#h#oANt%Q}$7Qjq(x7>nL@Ke2cE@DKDkGkaB=BOVRay2i9lQ{QXP7`zUXxtf!n$ zc?ac#6kRE0)ZV$hg>EnP&%>bnn0(D!DQ}~UP~J$nfigpR7v*;-zeRaB6ctL@lNACgCaQypGncT_wj85_qx=l-aX2@o!qZhKiHU? zL-BPcoimN7k!DLK&P^8G*^0BMHe_ZNB2$kWaiP~6^P#h?9%X7!i}P@{PCsfk7uTcp zzBuNX#ZluSeis^rwM};Y%MV*-WENwN{tdSm1qHN6?%_wWcc^;<; zWRzpo(>zY*y93RI3|H%XAI-8fgTSz+S|TM08&S8t`<_S9(cWG<&BsK0SXcWcvk>NH zU}HXD^48p3ytu{WN8@Ibc9s{ms;V&WR$Ma-%iTP8vxtJ*)7CHI>d~dOY9W@W(JYp_ z<3MmDH$@6f$09QuMTwCJYFkW49=&vF&X)WzF|Fii0T}aK~;A}mu9v!U5d0{70Rw@PK zsp|XIXw{3jS&yO1F~09>+AL5AqZzvQxd~C?EUFe*#&VkUF<)xTruDeG8qpJIbBMak zx9VYLXS}S3iB`QX_GDpIjG9YZNzEKzfd4CWY`1BIOS6$#N?X`z=s3{IBQr2KsQKo@ z113)L0^O1+mv0ANYv*xTuOn%1M;WKRmO2%8qZZkcRov86A)r86P2LPMM$r(RrZZ^@ zHOW#(8diB$h(p!#M#vNq7Nm#9$#7`#F591_>_`$VHeqiBeM}zGHPmT7#a4AzXOM5= z)KPuF&a4rlDND_=zr59KrkTcylOmeW;$jK*N7bXpOU@Vgc8`!_rP0xMdvYW73t<+*i@~3(F{4DH5d{ylWPz2!bJ7R+EkqM z+tf(yjuskKGY4-zG_tXZAyj1^A!|e)-(?xBk>Wban{RBHIT7xc6GYy;1{R} z+05c}7U05sLQ|Yqtqu#y3Nl_(3yaWkq+gV$vG3KY2K%I&?w8T^a6?!R_Mu&qb8{>L z_I4Uk*c)ja9JT`^Z!sNdTVkwaLW7(dF%+*+{W$tx;DC_d8ud~6YMN!OrX#_RETw?X zQu)zP7-MQt#~gTbJT4Ycnk=1_bHw$F%&uK7Ma58G4~VFKSKPE-0X-k8-?do=*Vn4A zL1|6L(eN_-Ft~x)R$NE@Vmx~fg_U4`A9-idy1&8k82^??v%R`Qu+#6M{;oCBT*&Gp zzhnkyhI!$mqhM6)v7Mq;o}NX*1r)3h$-MU^&f46XYBsj4PxiIsvQ;ZI&A92jwfiz3 z74}0XenKOQ76Dm3oac9?yXoomskBX71xtHRW9v{#|B&w)8$UQRdU)EnRkjj1>QEjQ zS35m?!{luvQ&Xc8`z>+O!jAQ<=)J#T-<*2eSqEx~8tYjVq(Cg|>3o9H)&lzpy((6$ zS!i4XL)M~1rA|Bp@2%rcq}=eGD7Vz@xq2&K7?h?#vTu|JV`6r20GEDTY9A-gVdGCL z!2ujblm+Ac{&$P9@s0Df&}PF`$#>2M3%$f7t;Q??#K6XCWq@w@F25AnaCOscYkqSe z7rs@?fOiXa5wOO%Y;`&mF2;>k!}u;yXXZ|aEOO{d+RB1MQR9eQw{EmwkoFTKmyf+} z-E*{_9=BSrq2}XbxEI%_jc%JmtF=U#S($6Ae99R~LEK=mAm1jB*K5L+U?Syj`3k?= zx{PB{7SGujM*{8Ep+OSyqj;@H;1iCmjt9i~LH9*7ORM->Oxcma$4R#=`#p+QT-L0EMh{L-9U7gOF*o2o z$0sMu#N><_pP0cQ3~Zef-^*0 zKT3|pS(?~T@K~6|1UZqURz)=I;GA>pkNaJ_MYb>Asnh?QRaeEoQGwG6mk9gu60=cp zTszA=ohz&d#1`%D+Yy`Na%ftw+L)ov}UMs;& zT7-2Q8reIPV+JDFa3i{fsNNi~4#{pldt5QJsFqy5-VQjU?Ro_AA5M{c{N*0(FntQ< zBB7Og8yCzU@tbDrpXt!As#ew)&cC$0lW1wn;mK3qNAF zTLeE=^E5^l9w)tk(c)+t3+W`InYecGlcsoucr{G08=n{5a92X6vCnP8JVR-0K4ph~uv5zs~EO&ja= z))u4RTQv4lYie84@J1I=`~4qt-hzs|IqVslJ~GzpXUh$$qWsd!6*Yw^+V^(eFfnaC zUBu=0y}=u!JXj_*x0Re-V!&=HhDh5P?y{w?XQ#L)n99;S*!2&N*9LEJexPF5x?VZ7 zb7*)F32s||IMP;q@K8?DYw)_(d_Fjns?Oe`buBXKo2gK}5ci7ggaH0yYo-8KP)uiSHFW^8a*x1Ok-i?YE{RxX7G z6|;-n-}yBeOq%vF-?MGEakqOmC42U4-E3ZKhE2t6-M#)M%e{(m3^j%4 zg7RF}0omk@T@ZSwX^2O(S`MubM%_9cWl_9{1IL9bUyNB12ecn!oftBsbyIJDT3O=u zCtaHOEE_4a9MF)Eu<|Jbl;e(Y&QzJ6}Sa4*4BQtSCvLnQD|($u_PWcC@74 z+`-Pi{Yh29O~i}l)X9zcsVCTW4y28!$l531eWlw&Sy`E921ZqFM%pK&%Vw*zX%PX_ zCQ9bRWU>8t-dD9tjuSombC<=+7_Wo`%L_?Gsu}&;&LWy$-UZxg>8n^|aMMu6@Z?SGmkySFO#gtZ3OVkT$Dv z`*HE9rw?@rX?I+o%|qLyi~iHM84P~}r6?b1Pt`_vOw!`X2c*gT@^d^+`n zOLRLk;7gs=1xMMjkFL?7Th>O@l_Cs+Th1uhSY)EuPmOQ^!F8Pj%R(OZ4$NF&zn1PI1WURUdo!3CfmaxEhjdL={B?GYsn&q zE$RCez~<5WGw9f>kEhB6I+i6P@k>otIbjPC!1 zk+?~yS8YN)E>rBKUb#R^Np+^R(XF_lzj1Y7gZ9?gv)rU#eQN{l&s$EEOLMn*@D!+6 zIi}aP=B6g5KrcZh9RtOL_#`;m~N(J&anZFF-4TeJh>e6)8l)K?i@Gt)G* zJSOeWH=-=HZeazvY+9<7Q&0FqB!w$kVm4VL+1yzZFq|BDx>TnoL$5v}QbYmgSl4H9 zo{jbijy*JzR$iuOdBNkIt&m3@Lv+qO+S>DS>LGv7KEb{9Im=gIP0jC*ZC_3E6lQ30X5;!8lwaU?G9X;<%5785_J05>z+uj60tCv zJuX3%{Evrqy{kolO1x>UvZp6nx9PYiKI{ox5x98ow-a6~ZTeKMPK>r3wp)3P+{ zs2>bdY?Xtt-+N*%#mPEK(eAbzQA?=hIm&=ZJNG(MnU47970X*rQtJIT-VxxVt$&ra zEvH6a-o{-2pMdMk1GJLf{D~8uJ!@&7&|wP<>*x{p(4_2(UwhdH+q{X31e1cEdXhC| z<(@8V1=LPwEeMgc7Lfq$6bT?soLjaQgRwBH5|i^U6IR%~avxGEa44fg z7kla=bf+%%Uk1%Yx=+D_dpN8KrQK5(#NSm1WtmuxSlFcI?x;nPP@c-W)uF5!V#{iP zTkktzo%T#{&7pDC4$el1JqDwJHdBiA1pot_yn?RQU`BNHR;5T^YA2Q&Olk51e$ zdGN^8h&`W~nAEG8@rjZBBOKiv9B4l{ZAK^j@yx#Q_5(xKT{|D{&K1x*X}JrS7zi^ zW$ZjU)&4+=!Lz+9uD?RcUPutj9P!a-)_^zdPqG8gG3#|C<)q*_udG zZ6=M(tjojjtj)`*lbrLQN##M$sgrnF_smfb+I;FH2R-hEJ?R;(>%SRETrMH;M literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/ca.po b/cpp/third_party/xz-5.8.3/po/ca.po new file mode 100644 index 000000000..1f22beadd --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/ca.po @@ -0,0 +1,1633 @@ +# SPDX-License-Identifier: 0BSD +# +# XZ Utils Catalan Translation +# Copyright (C) The XZ Utils authors and contributors +# This file is published under the BSD Zero Clause License. +# +# Jordi Mas i Hernàndez , 2022, 2024 +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.6.0-pre2\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2024-08-18 18:19+0300\n" +"Last-Translator: Jordi Mas i Hernàndez \n" +"Language-Team: Catalan \n" +"Language: ca\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) ? 0 : 1;\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: argument no vàlid per a --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: massa arguments per a --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "A --block-list, falta la mida del bloc després del número de cadena de filtres «%c:»" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 només es pot utilitzar com a últim element a --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: tipus de format de fitxer desconegut" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: tipus de comprovació d'integritat no admès" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Només es pot especificar un fitxer amb '--files' o '--files0'." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "La variable d'entorn %s conté massa arguments" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "El suport de compressió s'ha desactivat en temps de construcció" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "El suport de descompressió s'ha desactivat en temps de construcció" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "No s'admet la compressió de fitxers lzip (.lz)" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list s'ignora a menys que es comprimeixi al format .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Amb --format=raw, --suffix=.SUF és necessari si no s'escriu a la sortida estàndard" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "El nombre màxim de filtres és de quatre" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Error a l'opció --filters%s=FILTERS:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "El límit d'ús de la memòria és massa baix per a la configuració del filtre indicat." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "cadena de filtres %u utilitzada per --block-list però no especificada amb --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Es desaconsella l'ús d'un predefinit en mode RAW." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Les opcions exactes dels predefinits poden variar entre versions de programari." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "El format .lzma només admet el filtre LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "No es pot usar LZMA1 amb el format .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "La cadena de filtres %u és incompatible amb --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Es canvia al mode d'un sol fil a causa de --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Opcions no admeses a la cadena de filtres %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "S'utilitzen fins a % fils." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Cadena de filtres o opcions de filtre no admeses" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "La descompressió necessitarà %s MiB de memòria." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "S'ha reduït el nombre de fils de %s a %s per a no excedir el límit d'ús de memòria de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "S'ha reduït el nombre de fils de %s a un. El límit d'ús automàtic de memòria de %s MiB encara s'està excedint. Es requereix %s MiB de memòria. Es continua igualment." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "S'està canviant al mode d'un sol fil per a no excedir el límit d'ús de la memòria de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "S'ha ajustat la mida del diccionari LZMA%c de %s MiB a %s MiB per a no excedir el límit d'ús de memòria de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "S'ha ajustat la mida del diccionari LZMA%c per a --filters%u de %s MiB a %s MiBper a no excedir el límit d'ús de memòria de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "S'ha produït un error en canviar a la cadena de filtres %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "S'ha produït un error en crear una canonada: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: ha fallat la funció poll(): %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: sembla que el fitxer s'ha mogut, no s'elimina" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: no es pot eliminar: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: no es pot establir el propietari del fitxer: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: no es pot establir el grup de fitxers: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: no es poden establir els permisos del fitxer: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: ha fallat el tancament del fitxer: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: ha fallat el tancament del fitxer: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "S'ha produït un error en obtenir els indicadors d'estat del fitxer de l'entrada estàndard: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: és un enllaç simbòlic, s'omet" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: és un directori, s'omet" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: no és un fitxer normal, s'omet" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: el fitxer té el bit de setuid o setgid, s'omet" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: el fitxer té un bit enganxós, s'omet" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: el fitxer d'entrada té més d'un enllaç dur, s'omet" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Nom de fitxer buit, s'omet" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "S'ha produït un error en restaurar els indicadors d'estat a l'entrada estàndard: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "S'ha produït un error en obtenir els indicadors d'estat del fitxer de la sortida estàndard: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s: ha fallat el tancament del fitxer: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%s: no és un fitxer normal, s'omet" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "S'ha produït un error en restaurar l'indicador O_APPEND a la sortida estàndard: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: ha fallat el tancament del fitxer: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: ha fallat la cerca en intentar crear un fitxer dispers: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: error de lectura: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: error en cercar el fitxer: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: fi inesperat del fitxer" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: error d'escriptura: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Desactivat" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Quantitat de memòria física (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Nombre de fils del processador:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Compressió:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Descompressió:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Descompressió multifil:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Predeterminat per a -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Informació del maquinari:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Límits d'ús de la memòria:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Fluxos:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blocs:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Mida comprimida:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Mida no comprimida:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Relació:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Comprovació:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Farciment del flux:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Memòria necessària:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Mides a les capçaleres:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Nombre de fitxers:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Flux" + +#: src/xz/list.c +msgid "Block" +msgstr "Bloc" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blocs" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "CompOffset" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "UncompOffset" + +#: src/xz/list.c +msgid "CompSize" +msgstr "CompSize" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "UncompSize" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "TotalSize" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Relació" + +#: src/xz/list.c +msgid "Check" +msgstr "Comprovació" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "CheckVal" + +#: src/xz/list.c +msgid "Padding" +msgstr "Separació" + +#: src/xz/list.c +msgid "Header" +msgstr "Capçalera" + +#: src/xz/list.c +msgid "Flags" +msgstr "Senyals" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "MemUsage" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtres" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Cap" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "NoConeix2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "NoConeix3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "NoConeix5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "NoConeix6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "NoConeix7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "NoConeix8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "NoConeix9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "NoConeix11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "NoConeix12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "NoConeix13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "NoConeix14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "NoConeix15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: El fitxer està buit" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Massa petit per a ser un fitxer .xz vàlid" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Strms Blocs Comprimit NoComprimit Ràtio Check Nom de fitxer" + +#: src/xz/list.c +msgid "Yes" +msgstr "Sí" + +#: src/xz/list.c +msgid "No" +msgstr "No" + +#: src/xz/list.c +#, fuzzy +#| msgid " Minimum XZ Utils version: %s\n" +msgid "Minimum XZ Utils version:" +msgstr " Versió mínima de XZ Utils: %s\n" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s fitxer\n" +msgstr[1] "%s fitxers\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Totals:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list només funciona en fitxers .xz (--format=xz o --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Proveu «lzmainfo» amb fitxers .lzma." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list no admet la lectura des de l'entrada estàndard" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Error en llegir els noms de fitxer: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Final inesperat de l'entrada en llegir els noms de fitxer" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: S'ha trobat un caràcter nul en llegir els noms de fitxer. Potser volíeu utilitzar «--files0» en comptes de «--files»?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "La compressió i descompressió amb --robot encara no són admesos." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "No es poden llegir les dades de l'entrada estàndard en llegir els noms de fitxer de l'entrada estàndard" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Error intern (error)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "No es poden establir els gestors de senyals" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Sense comprovació d'integritat; no es verifica la integritat del fitxer" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Tipus no admès de comprovació d'integritat; no es verifica la integritat del fitxer" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "S'ha arribat al límit d'ús de la memòria" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "No s'ha reconegut el format del fitxer" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Opcions no admeses" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Les dades comprimides estan malmeses" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Final inesperat de l'entrada" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "Es requereixen %s MiB de memòria. El limitador està desactivat." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "Es requereixen %s MiB de memòria. El límit és %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Cadena de filtres: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Proveu «%s --help» per a més informació." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "Usage: %s [OPTION]... [FILE]...\n" +#| "Compress or decompress FILEs in the .xz format.\n" +#| "\n" +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" +"Ús: %s [OPCIÓ]... [FITXER]...\n" +"Comprimeix o descomprimeix FITXERS en format .xz.\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "" +"Els arguments obligatoris per a opcions llargues també són obligatoris\n" +"per a opcions curtes.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr " Mode d'operació:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force compression" +msgstr "Descompressió:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force decompression" +msgstr "Descompressió:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +" Modificadors de l'operació:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "Ha fallat l'escriptura a la sortida estàndard" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --single-stream decompress only the first stream, and silently\n" +#| " ignore possible remaining input data" +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" +" --single-stream descomprimeix només el primer flux, i silenciosament\n" +" ignora les possibles dades d'entrada restants" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Basic file format and compression options:\n" +msgid "Basic file format and compression options:" +msgstr "" +"\n" +" Opcions bàsiques de format i compressió de fitxers:\n" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --ignore-check don't verify the integrity check when decompressing" +msgid "don't verify the integrity check when decompressing" +msgstr " --ignore-check no verifiquis la comprovació d'integritat en descomprimir" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -0 ... -9 compression preset; default is 6; take compressor *and*\n" +#| " decompressor memory usage into account before using 7-9!" +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" +" -0 ... -9 compressió predefinida; per defecte és 6; tingueu en\n" +" compte l'ús de memòria del compressor *i* del\n" +" descompressor abans d'utilitzar 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -e, --extreme try to improve compression ratio by using more CPU time;\n" +#| " does not affect decompressor memory requirements" +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" +" -e, --extreme intenta millorar la ràtio de compressió usant més temps\n" +" de CPU; no afecta els requisits de memòria del\n" +" descompressor" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -T, --threads=NUM use at most NUM threads; the default is 0 which uses\n" +#| " as many threads as there are processor cores" +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" +" -T, --threads=NUM usa com a màxim NUM fils; el valor predeterminat és 0;\n" +" que utilitza tants fils com nuclis té el processador" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-size=SIZE\n" +#| " start a new .xz block after every SIZE bytes of input;\n" +#| " use this to set the block size for threaded compression" +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" +" --block-size=MIDA\n" +" inicia un bloc nou .xz després de cada MIDA de bytes\n" +" d'entrada; utilitzeu-ho per a establir la mida del bloc\n" +" per a la compressió amb fils" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-list=BLOCKS\n" +#| " start a new .xz block after the given comma-separated\n" +#| " intervals of uncompressed data; optionally, specify a\n" +#| " filter chain number (0-9) followed by a ':' before the\n" +#| " uncompressed data size" +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" +" --block-list=BLOCS\n" +" inicia un bloc .xz nou després de la separació d'intervals\n" +" amb comes donada de dades sense comprimir; opcionalment,\n" +" especifiqueu un número de cadena de filtres (0-9) seguit\n" +" d'un «:» abans de la mida de dades sense comprimir" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --flush-timeout=TIMEOUT\n" +#| " when compressing, if more than TIMEOUT milliseconds has\n" +#| " passed since the previous flush and reading more input\n" +#| " would block, all pending data is flushed out" +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" +" --flush-timeout=TEMPS\n" +" en comprimir, si han passat més de mil·lisegons de temps\n" +" d'espera des de l'anterior fluix i llegir més entrades\n" +" blocaria, totes les dades pendents es buiden" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --no-adjust if compression settings exceed the memory usage limit,\n" +#| " give an error instead of adjusting the settings downwards" +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" +" --no-adjust si la configuració de compressió excedeix el límit d'ús\n" +" de memòria, dona error en lloc de reduir la configuració" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Custom filter chain for compression (alternative for using presets):" +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" +"\n" +" Cadena de filtres personalitzada per a la compressió (alternativa per a l'ús\n" +" de predefinits):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " --filters=FILTERS set the filter chain using the liblzma filter string\n" +#| " syntax; use --filters-help for more information" +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" +"\n" +" --filters=FILTERS estableix la cadena de filtres utilitzant la sintaxi\n" +" de cadena de filtres del liblzma\n" +" Useu --filters-help per a més informació" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters1=FILTERS ... --filters9=FILTERS\n" +#| " set additional filter chains using the liblzma filter\n" +#| " string syntax to use with --block-list" +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" +" --filters1=FILTRES ... --filters9=FILTRES\n" +" estableix cadenes de filtres addicionals utilitzant\n" +" la sintaxi de cadena del filtre liblzmava a usar amb\n" +" --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters-help display more information about the liblzma filter string\n" +#| " syntax and exit." +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" +" --filters-help mostra més informació sobre la sintaxi de cadena del\n" +" filtre i surt." + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Number of processor threads:" +msgid "number of position bits" +msgstr "Nombre de fils del processador:" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "compression mode" +msgstr "Descompressió:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +" Altres opcions:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -Q, --no-warn make warnings not affect the exit status" +msgid "make warnings not affect the exit status" +msgstr " -Q, --no-warn fes que els avisos no afectin l'estat de sortida" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr "" +" --robot usa missatges analitzables per la màquina\n" +" (útil per a scripts)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --info-memory display the total amount of RAM and the currently active\n" +#| " memory usage limits, and exit" +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" +" --info-memory mostra la quantitat total de RAM i els límits actualment\n" +" actius d'ús de memòria, i surt" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version mostra el número de versió i surt" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"Sense FITXER, o quan el FITXER és -, es llegeix l'entrada estàndard.\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Informa d'errors a <%s> (en anglès o finès).\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "Pàgina inicial de %s: <%s>\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "AQUESTA ÉS UNA VERSIÓ DE DESENVOLUPAMENT NO DESTINADA A L'ÚS EN PRODUCCIÓ." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "" +#| "Filter chains are set using the --filters=FILTERS or\n" +#| "--filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain\n" +#| "can be separated by spaces or '--'. Alternatively a preset <0-9>[e] can be\n" +#| "specified instead of a filter chain.\n" +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" +"Les cadenes de filtres s'estableixen utilitzant --filters=FILTERS o les\n" +"opcions --filters1=FILTRES ... --filters9=FILTERS. Cada filtre de la cadena\n" +"es pot separar per espais o '--'. Alternativament pot ser un predefinit\n" +" <0-9>[e] especificat en comptes d'una cadena de filtres.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Els filtres admesos i les seves opcions són:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be 'name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s: les opcions han de ser parelles «name=value» separades per comes" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: nom d'opció no vàlid" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s: el valor de l'opció no és vàlid" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "No s'admet el LZMA1/LZMA2 predefinit: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "La suma de lc i lp no ha de superar 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: El nom de fitxer té un sufix desconegut, s'omet" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: El fitxer ja té el sufix «%s», s'ometrà" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: El sufix del nom de fitxer no és vàlid" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%s: El valor no és un enter decimal no negatiu" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: el sufix multiplicador no és vàlid" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Els sufixos vàlids són «KiB» (2^10), «MiB» (2^20) i «GiB» (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "El valor de l'opció «%s» ha d'estar a l'interval [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Les dades comprimides no es poden llegir des d'un terminal" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Les dades comprimides no es poden escriure en un terminal" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" +"Ús: %s [--help] [--version] [FITXER]...\n" +"Mostra la informació emmagatzemada a la capçalera del fitxer .lzma" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Show information stored in the .lzma file header." +msgstr "" +"Ús: %s [--help] [--version] [FITXER]...\n" +"Mostra la informació emmagatzemada a la capçalera del fitxer .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "El fitxer és massa petit per a ser un fitxer .xz" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "No és un fitxer .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Ha fallat l'escriptura a la sortida estàndard" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Error desconegut" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "Opcions no admeses" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "Cadena de filtres o opcions de filtre no admeses" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s: nom d'opció no vàlid" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s: el sufix multiplicador no és vàlid" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s: tipus de format de fitxer desconegut" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "No es pot usar LZMA1 amb el format .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "El nombre màxim de filtres és de quatre" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -z, --compress force compression\n" +#~ " -d, --decompress force decompression\n" +#~ " -t, --test test compressed file integrity\n" +#~ " -l, --list list information about .xz files" +#~ msgstr "" +#~ " -z, --compress força la compressió\n" +#~ " -d, --decompress força la descompressió\n" +#~ " -t, --test comprova la integritat del fitxer comprimit\n" +#~ " -l, --list informació sobre els fitxers .xz" + +#~ msgid "" +#~ " -k, --keep keep (don't delete) input files\n" +#~ " -f, --force force overwrite of output file and (de)compress links\n" +#~ " -c, --stdout write to standard output and don't delete input files" +#~ msgstr "" +#~ " -k, --keep manté (no suprimeixis) els fitxers d'entrada\n" +#~ " -f, --force força la sobreescriptura del fitxer de sortida i\n" +#~ " (des)comprimeix els enllaços\n" +#~ " -c, --stdout escriu a la sortida estàndard i no suprimeixis els\n" +#~ " fitxers d'entrada" + +#~ msgid "" +#~ " --no-sparse do not create sparse files when decompressing\n" +#~ " -S, --suffix=.SUF use the suffix '.SUF' on compressed files\n" +#~ " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~ " omitted, filenames are read from the standard input;\n" +#~ " filenames must be terminated with the newline character\n" +#~ " --files0[=FILE] like --files but use the null character as terminator" +#~ msgstr "" +#~ " --no-sparse no creïs fitxers dispersos en descomprimir\n" +#~ " -S, --suffix=.SUF usa el sufix «.SUF» en fitxers comprimits\n" +#~ " --files[=FILE] llegeix els noms de fitxer a processar des del FITXER;\n" +#~ " si s'omet, els noms de fitxer es llegeixen de l'entrada\n" +#~ " estàndard; els noms de fitxer s'han de finalitzar amb el\n" +#~ " caràcter de línia nova\n" +#~ " --files0[=FILE] com --files però usa el caràcter nul com a terminador" + +#~ msgid "" +#~ " -F, --format=FMT file format to encode or decode; possible values are\n" +#~ " 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'\n" +#~ " -C, --check=CHECK integrity check type: 'none' (use with caution),\n" +#~ " 'crc32', 'crc64' (default), or 'sha256'" +#~ msgstr "" +#~ " -F, --format=FMT fitxer de format per a codificar o descodificar; els\n" +#~ " valors possibles són «auto» (predeterminat), «xz»,\n" +#~ " «lzma», «lzip» i «raw»\n" +#~ " -C, --check=CHECK el tipus de comprovació d'integritat: «none» (useu amb\n" +#~ " precaució), «crc32», «crc64» (predeterminat), o «sha256»" + +#, no-c-format +#~ msgid "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " --memlimit-mt-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " set memory usage limit for compression, decompression,\n" +#~ " threaded decompression, or all of these; LIMIT is in\n" +#~ " bytes, % of RAM, or 0 for defaults" +#~ msgstr "" +#~ " --memlimit-compress=LÃMIT\n" +#~ " --memlimit-decompress=LÃMIT\n" +#~ " --memlimit-mt-decompress=LÃMIT\n" +#~ " -M, --memlimit=LÃMIT\n" +#~ " estableix el límit d'ús de memòria per a la compressió,\n" +#~ " descompressió, descompressió amb fils, o tots ells; el\n" +#~ " LÃMIT és en bytes, % de RAM, o 0 per als predeterminats" + +#~ msgid "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n" +#~ " --lzma2[=OPTS] more of the following options (valid values; default):\n" +#~ " preset=PRE reset options to a preset (0-9[e])\n" +#~ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM number of literal context bits (0-4; 3)\n" +#~ " lp=NUM number of literal position bits (0-4; 0)\n" +#~ " pb=NUM number of position bits (0-4; 2)\n" +#~ " mode=MODE compression mode (fast, normal; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM maximum search depth; 0=automatic (default)" +#~ msgstr "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 o LZMA2; OPTS és una llista separada per comes de\n" +#~ " --lzma2[=OPTS] zero o més opcions de les següents (valors vàlids;\n" +#~ " predeterminat):\n" +#~ " preset=PRE restableix les opcions a un predefinit\n" +#~ " (0-9[e])\n" +#~ " dict=NUM mida del diccionari (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM nombre de bits de context literal (0-4; 3)\n" +#~ " lp=NUM nombre de bits de posició literal (0-4; 0)\n" +#~ " pb=NUM nombre de bits de posició (0-4; 2)\n" +#~ " mode=MODE mode de compressió (ràpid, normal; normal)\n" +#~ " nice=NUM longitud de coincidència (2-273; 64)\n" +#~ " mf=NAME cercador de coincidències (hc3, hc4, bt2,\n" +#~ " bt3, bt4; bt4)\n" +#~ " depth=NUM profunditat màxima de cerca; 0=automàtic\n" +#~ " (predeterminat)" + +#~ msgid "" +#~ "\n" +#~ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~ " --arm[=OPTS] ARM BCJ filter\n" +#~ " --armthumb[=OPTS] ARM-Thumb BCJ filter\n" +#~ " --arm64[=OPTS] ARM64 BCJ filter\n" +#~ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~ " --sparc[=OPTS] SPARC BCJ filter\n" +#~ " --riscv[=OPTS] RISC-V BCJ filter\n" +#~ " Valid OPTS for all BCJ filters:\n" +#~ " start=NUM start offset for conversions (default=0)" +#~ msgstr "" +#~ "\n" +#~ " --x86[=OPTS] filtre BCJ x86 (32-bit i 64-bit)\n" +#~ " --arm[=OPTS] filtre BCJ ARM\n" +#~ " --armthumb[=OPTS] filtre BCJ ARM-Thumb\n" +#~ " --arm64[=OPTS] filtre ARM64 BCJ\n" +#~ " --powerpc[=OPTS] filtre BCJ PowerPC (només endian gran)\n" +#~ " --ia64[=OPTS] filtre IA-64 (Itanium) BCJ\n" +#~ " --sparc[=OPTS] filtre BCJ SPARC\n" +#~ " --riscv[=OPTS] filtre RISC-V BCJ\n" +#~ " OPTS vàlids per a tots els filtres BCJ:\n" +#~ " start=Núm. decalatge d'inici per a les conversions\n" +#~ " (per defecte=0)" + +#~ msgid "" +#~ "\n" +#~ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" +#~ " dist=NUM distance between bytes being subtracted\n" +#~ " from each other (1-256; 1)" +#~ msgstr "" +#~ "\n" +#~ " --delta[=OPTS] Filtre delta; OPT (valors vàlids; predeterminat):\n" +#~ " dist=Núm. entre bytes que es resten de\n" +#~ " l'altre (1-256; 1)" + +#~ msgid "" +#~ " -q, --quiet suppress warnings; specify twice to suppress errors too\n" +#~ " -v, --verbose be verbose; specify twice for even more verbose" +#~ msgstr "" +#~ " -q, --quiet suprimeix els avisos; especifiqueu-ho dues vegades per a\n" +#~ " suprimir també els errors\n" +#~ " -v, --verbose sigues detallat; especifiqueu dues vegades per a tenir\n" +#~ " encara més detall" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help mostra l'ajuda curta (només mostra les opcions bàsiques)\n" +#~ " -H, --long-help mostra aquesta ajuda llarga i surt" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help mostra aquesta ajuda curta i surt\n" +#~ " -H, --long-help mostra l'ajuda llarga (llista també opcions avançades)" + +#~ msgid "Failed to enable the sandbox" +#~ msgstr "No s'ha pogut habilitar l'espai aïllat" diff --git a/cpp/third_party/xz-5.8.3/po/cs.gmo b/cpp/third_party/xz-5.8.3/po/cs.gmo new file mode 100644 index 0000000000000000000000000000000000000000..f9ebe3d90b343a6ef4f0b24d2e1bf028bf4287b0 GIT binary patch literal 7983 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/cs.po b/cpp/third_party/xz-5.8.3/po/cs.po new file mode 100644 index 000000000..57949f732 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/cs.po @@ -0,0 +1,1679 @@ +# XZ Utils Czech translation +# This file is put in the public domain. +# Marek ÄŒernocký , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: xz-utils\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2010-12-03 11:32+0100\n" +"Last-Translator: Marek ÄŒernocký \n" +"Language-Team: Czech \n" +"Language: cs\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==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n" +"X-Poedit-Language: Czech\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Neznámý typ formátu souboru" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Neznámý typ kontroly integrity" + +#: src/xz/args.c +#, fuzzy +#| msgid "Only one file can be specified with `--files' or `--files0'." +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Spolu s pÅ™epínaÄi „--files“ nebo „--files0“ může být zadán pouze jeden soubor" + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "PromÄ›nná prostÅ™edí %s obsahuje příliÅ¡ mnoho argumentů" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "" + +#: src/xz/args.c +#, fuzzy +#| msgid "%s: With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "%s: S pÅ™epínaÄem --format=raw je vyžadován --sufix=.PRIP, vyjma zápisu do standardního výstupu" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Maximální poÄet filtrů je ÄtyÅ™i" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Omezení použitelné pamÄ›ti je příliÅ¡ malé pro dané nastavení filtru." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Použití pÅ™ednastavení v režimu raw je nevhodné." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "PÅ™esné volby u pÅ™ednastavení se mohou liÅ¡it mezi různými verzemi softwaru." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Formát .lzma podporuje pouze filtr LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 nelze použít s formátem .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Unsupported options" +msgid "Unsupported options in filter chain %u" +msgstr "Nepodporovaná volba" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "" + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Nepodporovaný omezující filtr nebo volby filtru" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Dekomprimace bude vyžadovat %s MiB pamÄ›ti." + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "PÅ™izpůsobit velikost slovníku LZMA%c z %s MiB na %s MiB, tak aby nebylo pÅ™ekroÄeno omezení použitelné pamÄ›ti %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "PÅ™izpůsobit velikost slovníku LZMA%c z %s MiB na %s MiB, tak aby nebylo pÅ™ekroÄeno omezení použitelné pamÄ›ti %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "PÅ™izpůsobit velikost slovníku LZMA%c z %s MiB na %s MiB, tak aby nebylo pÅ™ekroÄeno omezení použitelné pamÄ›ti %s MiB" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "PÅ™izpůsobit velikost slovníku LZMA%c z %s MiB na %s MiB, tak aby nebylo pÅ™ekroÄeno omezení použitelné pamÄ›ti %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Vypadá to, že soubor byl pÅ™esunut, proto nebude odstranÄ›n" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Nelze odstranit: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Nelze nastavit vlastníka souboru: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Nelze nastavit skupinu souboru: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Nelze nastavit oprávnÄ›ní souboru: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Selhalo zavÅ™ení souboru: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Selhalo zavÅ™ení souboru: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Jedná se o symbolický odkaz, vynechává se" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Jedná se o složku, vynechává se" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Nejedná se o běžný soubor, vynechává se" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Soubor má nastavený bit setuid nebo setgid, vynechává se" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Soubor má nastavený bit sticky, vynechává se" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Vstupní soubor má více než jeden pevný odkaz, vynechává se" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Prázdný název souboru, vynechává se" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Selhalo zavÅ™ení souboru: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%s: Nejedná se o běžný soubor, vynechává se" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Chyba pÅ™i obnovení příznaku O_APPEND na standardní výstup: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Selhalo zavÅ™ení souboru: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Selhalo nastavení pozice pÅ™i pokusu o vytvoÅ™ení souboru řídké matice: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Chyba Ätení: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Chyba pÅ™i posunu v rámci souboru: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: NeoÄekávaný konec souboru" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Chyba zápisu: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Vypnuto" + +#: src/xz/hardware.c +#, fuzzy +#| msgid "Total amount of physical memory (RAM): " +msgid "Amount of physical memory (RAM):" +msgstr "Celkové množství fyzické pamÄ›ti (RAM): " + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "" + +#: src/xz/hardware.c +#, fuzzy +#| msgid "Memory usage limit for decompression: " +msgid "Multi-threaded decompression:" +msgstr "Omezení použitelné pamÄ›ti pro dekomprimaci:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "" + +#: src/xz/hardware.c +#, fuzzy +#| msgid "Memory usage limit reached" +msgid "Memory usage limits:" +msgstr "Dosaženo omezení použitelné pamÄ›ti" + +#: src/xz/list.c +msgid "Streams:" +msgstr "" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "" + +#: src/xz/list.c +#, fuzzy +#| msgid " Compressed size: %s\n" +msgid "Compressed size:" +msgstr " Komprimovaná velikost: %s\n" + +#: src/xz/list.c +#, fuzzy +#| msgid " Uncompressed size: %s\n" +msgid "Uncompressed size:" +msgstr " Nekomprimovaná velikost: %s\n" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "" + +#: src/xz/list.c +msgid "Check:" +msgstr "" + +#: src/xz/list.c +#, fuzzy +#| msgid " Stream padding: %s\n" +msgid "Stream Padding:" +msgstr " Zarovnání proudu: %s\n" + +#: src/xz/list.c +#, fuzzy +#| msgid " Memory needed: %s MiB\n" +msgid "Memory needed:" +msgstr " PotÅ™ebná paměť: %s MiB\n" + +#: src/xz/list.c +#, fuzzy +#| msgid " Sizes in headers: %s\n" +msgid "Sizes in headers:" +msgstr " Velikosti v hlaviÄkách: %s\n" + +#: src/xz/list.c +#, fuzzy +#| msgid " Number of files: %s\n" +msgid "Number of files:" +msgstr " PoÄet souborů: %s\n" + +#: src/xz/list.c +msgid "Stream" +msgstr "" + +#: src/xz/list.c +msgid "Block" +msgstr "" + +#: src/xz/list.c +msgid "Blocks" +msgstr "" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "" + +#: src/xz/list.c +msgid "CompSize" +msgstr "" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "" + +#: src/xz/list.c +#, fuzzy +#| msgid "Totals:" +msgid "TotalSize" +msgstr "Celkem:" + +#: src/xz/list.c +msgid "Ratio" +msgstr "" + +#: src/xz/list.c +msgid "Check" +msgstr "" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "" + +#: src/xz/list.c +msgid "Padding" +msgstr "" + +#: src/xz/list.c +msgid "Header" +msgstr "" + +#: src/xz/list.c +msgid "Flags" +msgstr "" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "" + +#: src/xz/list.c +msgid "Filters" +msgstr "" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "žádná" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "neznámá-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "neznámá-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "neznámá-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "neznámá-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "neznámá-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "neznámá-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "neznámá-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "neznámá-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "neznámá-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "neznámá-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "neznámá-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "neznámá-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Soubor je prázdný" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Je příliÅ¡ malý na to, aby to mohl být platný soubor .xz" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Proud Bloky Komprim Nekomprim PomÄ›r Kontrl Název souboru" + +#: src/xz/list.c +msgid "Yes" +msgstr "Ano" + +#: src/xz/list.c +msgid "No" +msgstr "Ne" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s soubor\n" +msgstr[1] "%s soubory\n" +msgstr[2] "%s souborů\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Celkem:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list pracuje pouze se soubory .xz (--format=xz nebo --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "" + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list nepodporuje Ätení ze standardního vstupu" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Chyba pÅ™i Ätení názvů souborů: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: NeoÄekávaný konec vstupu pÅ™i Ätení názvů souborů" + +#: src/xz/main.c +#, fuzzy, c-format +#| msgid "%s: Null character found when reading filenames; maybe you meant to use `--files0' instead of `--files'?" +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Byl nalezen nulový znak pÅ™i Ätení názvů souborů; nechtÄ›li jste náhodou použít „--files0“ místo „--files“?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Komprimace a dekomprimace s pÅ™epínaÄem --robot není zatím podporovaná." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Ze standardního vstupu nelze Äíst data, když se ze standardního vstupu naÄítají názvy souborů" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "" + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Interní chyba" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Nelze ustanovit ovladaÄ signálu" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Žádná kontrola integrity; integrita souboru se nebude ověřovat" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Nepodporovaný typ kontroly integrity; integrita souboru se nebude ověřovat" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Dosaženo omezení použitelné pamÄ›ti" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Formát souboru nebyl rozpoznán" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Nepodporovaná volba" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Komprimovaná data jsou poÅ¡kozená" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "NeoÄekávaný konec vstupu" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "Je vyžadováno %s MiB pamÄ›ti. Limit je %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Omezující filtr: %s\n" + +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "Try `%s --help' for more information." +msgid "Try '%s --help' for more information." +msgstr "Zkuste „%s --help“ pro více informací" + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "Usage: %s [OPTION]... [FILE]...\n" +#| "Compress or decompress FILEs in the .xz format.\n" +#| "\n" +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" +"Použití: %s [PŘEPÃNAÄŒ]... [SOUBOR]...\n" +"Komprimuje nebo dekomprimuje SOUBORy ve formátu xz.\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Povinné argumenty pro dlouhé pÅ™epínaÄe jsou povinné rovněž pro krátké pÅ™epínaÄe.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr "OperaÄní režim:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Memory usage limit for decompression: " +msgid "force compression" +msgstr "Omezení použitelné pamÄ›ti pro dekomprimaci:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Memory usage limit for decompression: " +msgid "force decompression" +msgstr "Omezení použitelné pamÄ›ti pro dekomprimaci:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +"Modifikátory operací:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "Zápis do standardního výstupu selhal" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Basic file format and compression options:\n" +msgid "Basic file format and compression options:" +msgstr "" +"\n" +"Základní pÅ™epínaÄe pro formát souboru a komprimaci:\n" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -0 ... -9 compression preset; default is 6; take compressor *and*\n" +#| " decompressor memory usage into account before using 7-9!" +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" +" -0 .. -9 pÅ™ednastavení komprimace; výchozí je 6; než použijete\n" +" hodnoty 7 – 9, vezmÄ›te do úvahy množství použité pamÄ›ti" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -e, --extreme try to improve compression ratio by using more CPU time;\n" +#| " does not affect decompressor memory requirements" +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" +" -e, --extreme zkusit zlepÅ¡it pomÄ›r komprimace využitím více Äasu\n" +" procesoru; nemá vliv na paměťové nároky dekomprimace" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --no-adjust if compression settings exceed the memory usage limit,\n" +#| " give an error instead of adjusting the settings downwards" +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" +" --no-adjust pokud nastavení komprimace pÅ™esáhne omezení použitelné\n" +" pamÄ›ti, pÅ™edat chybu namísto snížení nastavení" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Custom filter chain for compression (alternative for using presets):" +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" +"\n" +"Vlastní omezující filtr pro komprimaci (alternativa k použití pÅ™ednastavených):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "compression mode" +msgstr "OperaÄní režim:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +" Ostatní pÅ™epínaÄe:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -Q, --no-warn make warnings not affect the exit status" +msgid "make warnings not affect the exit status" +msgstr " -Q, --no-warn způsobí, že varování neovlivní stav ukonÄení" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr "" +" --robot použít strojovÄ› analyzovatelné zprávy (užiteÄné pro\n" +" skripty)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --info-memory display the total amount of RAM and the currently active\n" +#| " memory usage limits, and exit" +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" +" --info-memory zobrazit celkové množství pamÄ›ti RAM a souÄasné aktivní\n" +" omezení použitelné pamÄ›ti a skonÄit" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version zobrazit Äíslo verze a skonÄit" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"Pokud SOUBOR není zadán nebo pokud je -, bude se Äíst ze standardního vstupu.\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Chyby hlaste na <%s> (v angliÄtinÄ› nebo finÅ¡tinÄ›).\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "Domovská stránka %s: <%s>\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "The supported filters and their options are:" +msgstr "Nepodporovaný omezující filtr nebo volby filtru" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be `name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s: Volby musí být páry „název=hodnota“ oddÄ›lené Äárkami" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Neplatný název volby" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s: Neplatná hodnota volby" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Nepodporované pÅ™ednastavení LZMA1/LZMA2: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "SouÄet lc a lp nesmí pÅ™ekroÄit hodnotu 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Název souboru má neznámou příponu, vynechává se" + +#: src/xz/suffix.c +#, fuzzy, c-format +#| msgid "%s: File already has `%s' suffix, skipping" +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Soubor již má příponu „%s“, vynechává se" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Neplatná přípona názvu souboru" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%s: Hodnota není nezáporné desítkové Äíslo" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Neplatná jednotka s pÅ™edponou" + +#: src/xz/util.c +#, fuzzy +#| msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)." +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Platné jednotky s pÅ™edponami jsou „KiB“ (2^10 B), „MiB“ (2^20 B) a „GiB“ (2^30 B)." + +#: src/xz/util.c +#, fuzzy, c-format +#| msgid "Value of the option `%s' must be in the range [%, %]" +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Hodnota volby „%s“ musí být v rozsahu [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Z terminálu nelze Äíst komprimovaná data" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Do terminálu nelze zapisovat komprimovaná data" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "%s: Too small to be a valid .xz file" +msgid "File is too small to be a .lzma file" +msgstr "%s: Je příliÅ¡ malý na to, aby to mohl být platný soubor .xz" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Zápis do standardního výstupu selhal" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Neznámá chyba" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "Nepodporovaná volba" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "Nepodporovaný omezující filtr nebo volby filtru" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s: Neplatný název volby" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s: Neplatná jednotka s pÅ™edponou" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s: Neznámý typ formátu souboru" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "LZMA1 nelze použít s formátem .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "Maximální poÄet filtrů je ÄtyÅ™i" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -z, --compress force compression\n" +#~ " -d, --decompress force decompression\n" +#~ " -t, --test test compressed file integrity\n" +#~ " -l, --list list information about .xz files" +#~ msgstr "" +#~ " -z, --compress provést komprimaci\n" +#~ " -d, --decompress provést dekomprimaci\n" +#~ " -t, --test testovat integritu komprimovaného souboru\n" +#~ " -l, --list vypsat informace o souborech .xz" + +#~ msgid "" +#~ " -k, --keep keep (don't delete) input files\n" +#~ " -f, --force force overwrite of output file and (de)compress links\n" +#~ " -c, --stdout write to standard output and don't delete input files" +#~ msgstr "" +#~ " -k, --keep zachovat (nemazat) vstupní soubory\n" +#~ " -f, --force vynutit pÅ™epis výstupního souboru a de/komprimovat odkazy\n" +#~ " -c, --stdout zapisovat na standardní výstup a nemazat vstupní soubory" + +#, fuzzy +#~| msgid "" +#~| " --no-sparse do not create sparse files when decompressing\n" +#~| " -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n" +#~| " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~| " omitted, filenames are read from the standard input;\n" +#~| " filenames must be terminated with the newline character\n" +#~| " --files0[=FILE] like --files but use the null character as terminator" +#~ msgid "" +#~ " --no-sparse do not create sparse files when decompressing\n" +#~ " -S, --suffix=.SUF use the suffix '.SUF' on compressed files\n" +#~ " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~ " omitted, filenames are read from the standard input;\n" +#~ " filenames must be terminated with the newline character\n" +#~ " --files0[=FILE] like --files but use the null character as terminator" +#~ msgstr "" +#~ " --no-sparse nevytvářet pÅ™i dekomprimaci soubory řídkých matic\n" +#~ " -S, --suffix=.PRIP použít u komprimovaných souborů příponu „.PRIP“\n" +#~ " --files[=SOUBOR] Äíst názvy souborů, které se mají zpracovat, ze SOUBORu;\n" +#~ " pokud není SOUBOR zadán, Äte se ze standardního vstupu;\n" +#~ " názvy souborů musí být zakonÄeny znakem nového řádku\n" +#~ " --files0[=SOUBOR] stejné jako --files, ale použít k zakonÄování nulový znak" + +#, fuzzy +#~| msgid "" +#~| " -F, --format=FMT file format to encode or decode; possible values are\n" +#~| " `auto' (default), `xz', `lzma', and `raw'\n" +#~| " -C, --check=CHECK integrity check type: `none' (use with caution),\n" +#~| " `crc32', `crc64' (default), or `sha256'" +#~ msgid "" +#~ " -F, --format=FMT file format to encode or decode; possible values are\n" +#~ " 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'\n" +#~ " -C, --check=CHECK integrity check type: 'none' (use with caution),\n" +#~ " 'crc32', 'crc64' (default), or 'sha256'" +#~ msgstr "" +#~ " -F, --format=FORMÃT formát souboru k zakódování nebo dekódování; možné\n" +#~ " hodnoty jsou „auto“ (výchozí), „xz“, „lzma“ a „raw“\n" +#~ " -C, --check=KONTROLA typ kontroly integrity: „none“ (používejte s rozmyslem),\n" +#~ " „crc32“, „crc64“ (výchozí) nebo „sha256“" + +#, fuzzy, no-c-format +#~| msgid "" +#~| " --memlimit-compress=LIMIT\n" +#~| " --memlimit-decompress=LIMIT\n" +#~| " -M, --memlimit=LIMIT\n" +#~| " set memory usage limit for compression, decompression,\n" +#~| " or both; LIMIT is in bytes, % of RAM, or 0 for defaults" +#~ msgid "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " --memlimit-mt-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " set memory usage limit for compression, decompression,\n" +#~ " threaded decompression, or all of these; LIMIT is in\n" +#~ " bytes, % of RAM, or 0 for defaults" +#~ msgstr "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " nastaví omezení použitelné pamÄ›ti pro komprimaci,\n" +#~ " dekomprimaci nebo obojí; LIMIT je v bajtech, % z pamÄ›ti\n" +#~ " RAM nebo 0 pro výchozí" + +#~ msgid "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n" +#~ " --lzma2[=OPTS] more of the following options (valid values; default):\n" +#~ " preset=PRE reset options to a preset (0-9[e])\n" +#~ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM number of literal context bits (0-4; 3)\n" +#~ " lp=NUM number of literal position bits (0-4; 0)\n" +#~ " pb=NUM number of position bits (0-4; 2)\n" +#~ " mode=MODE compression mode (fast, normal; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM maximum search depth; 0=automatic (default)" +#~ msgstr "" +#~ "\n" +#~ " --lzma1[=VOLBY] LZMA1 nebo LZMA2; VOLBY je Äárkou oddÄ›lovaný seznam žádné\n" +#~ " --lzma2[=VOLBY] nebo více následujících voleb (platné hodnoty; výchozí):\n" +#~ " preset=PŘE zmÄ›nit volby na PŘEdnastavené (0 – 9[e])\n" +#~ " dict=POÄŒ velikost slovníku (4 KiB – 1536 MiB; 8 MiB)\n" +#~ " lc=POÄŒ poÄet kontextových bitů literálu (0 – 4; 3)\n" +#~ " lp=POÄŒ poÄet poziÄních bitů literálu (0 – 4; 0)\n" +#~ " pb=POÄŒ poÄet poziÄních bitů (0 – 4; 2)\n" +#~ " mode=REŽIM režim komprimace (fast, normal; normal)\n" +#~ " nice=NUM příznivá délka shody (2 – 273; 64)\n" +#~ " mf=NÃZEV hledání shod (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=POÄŒ maximální hloubka prohledávání;\n" +#~ " 0 = automaticky (výchozí)" + +#, fuzzy +#~| msgid "" +#~| "\n" +#~| " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~| " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~| " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~| " --arm[=OPTS] ARM BCJ filter (little endian only)\n" +#~| " --armthumb[=OPTS] ARM-Thumb BCJ filter (little endian only)\n" +#~| " --sparc[=OPTS] SPARC BCJ filter\n" +#~| " Valid OPTS for all BCJ filters:\n" +#~| " start=NUM start offset for conversions (default=0)" +#~ msgid "" +#~ "\n" +#~ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~ " --arm[=OPTS] ARM BCJ filter\n" +#~ " --armthumb[=OPTS] ARM-Thumb BCJ filter\n" +#~ " --arm64[=OPTS] ARM64 BCJ filter\n" +#~ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~ " --sparc[=OPTS] SPARC BCJ filter\n" +#~ " --riscv[=OPTS] RISC-V BCJ filter\n" +#~ " Valid OPTS for all BCJ filters:\n" +#~ " start=NUM start offset for conversions (default=0)" +#~ msgstr "" +#~ "\n" +#~ " --x86[=VOLBY] Filtr x86 BCJ (32bitový a 64bitový)\n" +#~ " --powerpc[=VOLBY] Filtr PowerPC BCJ (pouze big endian)\n" +#~ " --ia64[=VOLBY] Filtr IA64 (Itanium) BCJ\n" +#~ " --arm[=VOLBY] Filtr ARM BCJ (pouze little endian)\n" +#~ " --armthumb[=VOLBY] Filtr ARM-Thumb BCJ (pouze little endian)\n" +#~ " --sparc[=VOLBY] Filtr SPARC BCJ\n" +#~ " Platné volby pro vÅ¡echny filtry BCJ:\n" +#~ " start=POÄŒ poÄáteÄní posun pro pÅ™evody (výchozí=0)" + +#~ msgid "" +#~ "\n" +#~ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" +#~ " dist=NUM distance between bytes being subtracted\n" +#~ " from each other (1-256; 1)" +#~ msgstr "" +#~ "\n" +#~ " --delta[=VOLBY] Filtr Delta; platné VOLBY (platné hodnoty; výchozí):\n" +#~ " dist=POÄŒ vzdálenost mezi bajty, které jsou odeÄítány\n" +#~ " jeden od druhého (1 – 256; 1)" + +#~ msgid "" +#~ " -q, --quiet suppress warnings; specify twice to suppress errors too\n" +#~ " -v, --verbose be verbose; specify twice for even more verbose" +#~ msgstr "" +#~ " -q, --quiet potlaÄit varování; zadáním dvakrát, potlaÄíte i chyby\n" +#~ " -v, --verbose podrobnÄ›jší zprávy; zadáním dvakrát, budou jeÅ¡tÄ›\n" +#~ " podrobnÄ›jší" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help zobrazit krátkou nápovÄ›du (vypíše jen základní pÅ™epínaÄe)\n" +#~ " -H, --long-help zobrazit tuto úplnou nápovÄ›du a skonÄit" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help zobrazit tuto zkrácenou nápovÄ›du a skonÄit\n" +#~ " -H, --long-help zobrazit úplnou nápovÄ›du (vypíše i pokroÄilé pÅ™epínaÄe)" + +#~ msgid "Memory usage limit for compression: " +#~ msgstr "Omezení použitelné pamÄ›ti pro komprimaci: " + +#, c-format +#~ msgid " Streams: %s\n" +#~ msgstr " Proudů: %s\n" + +#, c-format +#~ msgid " Blocks: %s\n" +#~ msgstr " Bloků: %s\n" + +#, c-format +#~ msgid " Ratio: %s\n" +#~ msgstr " PomÄ›r komprimace: %s\n" + +#, c-format +#~ msgid " Check: %s\n" +#~ msgstr " Typ kontroly: %s\n" + +#~ msgid "" +#~ " Streams:\n" +#~ " Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding" +#~ msgstr "" +#~ " Proudy:\n" +#~ " Proud Bloky KomprPozice NekomprPozice KomprVelikost NekomprVelikost PomÄ›r Kontrola Zarovnání" + +#, c-format +#~ msgid "" +#~ " Blocks:\n" +#~ " Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check" +#~ msgstr "" +#~ " Bloky:\n" +#~ " Proud Blok KomprPozice NekomprPozice CelkVelikost NekomprVelikost PomÄ›r Kontrola" + +#, c-format +#~ msgid " CheckVal %*s Header Flags CompSize MemUsage Filters" +#~ msgstr " KontrHod %*s HlaviÄ Příznaky KomprVel PoužiPam Filtry" + +#, c-format +#~ msgid "The selected match finder requires at least nice=%" +#~ msgstr "Vybraný vyhledávaÄ shod vyžaduje minimálnÄ› nice=%" + +#~ msgid "Limit was %s MiB, but %s MiB would have been needed" +#~ msgstr "Limit byl %s MiB, ale bylo by zapotÅ™ebí %s MiB" + +#~ msgid "%s MiB (%s bytes)\n" +#~ msgstr "%s MiB (%s bajtů)\n" + +#~ msgid "" +#~ " -e, --extreme use more CPU time when encoding to increase compression\n" +#~ " ratio without increasing memory usage of the decoder" +#~ msgstr "" +#~ " -e, --extreme využít více procesorového Äasu pro kódování, Äímž se\n" +#~ " zvýší kompresní pomÄ›r bez zvýšení pamÄ›ti použité kodérem" + +#~ msgid "" +#~ " -M, --memory=NUM use roughly NUM bytes of memory at maximum; 0 indicates\n" +#~ " the default setting, which is 40 % of total RAM" +#~ msgstr "" +#~ " -M, --memory=POÄŒ použít zhruba POÄŒ bajtů pamÄ›ti jako maximum; 0 znamená\n" +#~ " výchozí nastavení, což je 40% celkového množství pamÄ›ti" + +#~ msgid "" +#~ "\n" +#~ " --subblock[=OPTS] Subblock filter; valid OPTS (valid values; default):\n" +#~ " size=NUM number of bytes of data per subblock\n" +#~ " (1 - 256Mi; 4Ki)\n" +#~ " rle=NUM run-length encoder chunk size (0-256; 0)" +#~ msgstr "" +#~ "\n" +#~ " --subblock[=VOLBY] Subblokový filtr; platné VOLBY (platné hodnoty; výchozí):\n" +#~ " size=POÄŒ poÄet bajtů dat na subblok\n" +#~ " (1 - 256 Mi; 4 Ki)\n" +#~ " rle=POÄŒ velikost dávky pro kodér run-length (0-256; 0)" + +#~ msgid "" +#~ "On this system and configuration, this program will use a maximum of roughly\n" +#~ "%s MiB RAM and " +#~ msgstr "" +#~ "Na tomto systému a s tímto nastavením použije tento program maximum ze zhruba\n" +#~ "%s MiB RAM a " + +#~ msgid "" +#~ "one thread.\n" +#~ "\n" +#~ msgstr "" +#~ "jedno vlákno.\n" +#~ "\n" + +#~ msgid "%s: Invalid multiplier suffix. Valid suffixes:" +#~ msgstr "%s: Neplatná přípona. Platné přípony jsou:" diff --git a/cpp/third_party/xz-5.8.3/po/da.gmo b/cpp/third_party/xz-5.8.3/po/da.gmo new file mode 100644 index 0000000000000000000000000000000000000000..460dae3cf0da253aa610134613b98dab9238e11a GIT binary patch literal 9040 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 I`r+*V1E)SyivR!s literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/da.po b/cpp/third_party/xz-5.8.3/po/da.po new file mode 100644 index 000000000..bea97ac0f --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/da.po @@ -0,0 +1,1436 @@ +# Danish translation xz. +# This file is put in the public domain. +# Joe Hansen , 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.2.4\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2019-03-04 23:08+0100\n" +"Last-Translator: Joe Hansen \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Ugyldigt parameter til --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: For mange argumenter til --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 kan kun bruges som det sidste element i --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Ukendt filformattype" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Typen for integritetkontrol er ikke understøttet" + +#: src/xz/args.c +#, fuzzy +#| msgid "Only one file can be specified with `--files' or `--files0'." +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Kun en fil kan angives med »--files« eller »--files0«." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, fuzzy, c-format +#| msgid "%s: " +msgid "%s: %s" +msgstr "%s: " + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Miljøvariablen %s indeholder for mange argumenter" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Komprimeringsunderstøttelse blev deaktiveret pÃ¥ byggetidspunktet" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Dekomprimeringsunderstøttelse blev deaktiveret pÃ¥ byggetidspunktet" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "" + +#: src/xz/args.c +#, fuzzy +#| msgid "%s: With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "%s: med --format=raw, --suffix=.SUF er krævet med mindre der skrives til standardud" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Maksimalt antal filtre er fire" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Begræsningen for brug af hukommelse er for lav for den givne filteropsætning." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Det frarÃ¥des at bruge en forhÃ¥ndskonfiguration i rÃ¥ tilstand (raw mode)." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "De præcise indstillinger for forhÃ¥ndskonfigurationerne kan variere mellem programversioner." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Formatet .lzma understøtter kun LZMA1-filteret" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 kan ikke bruges med .xz-formatet" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "The filter chain is incompatible with --flush-timeout" +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Filterkæden er ikke kompatibel med --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Skifter til enkelt trÃ¥det tilstand pÃ¥ grund af --flush-timeout" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Unsupported options" +msgid "Unsupported options in filter chain %u" +msgstr "Tilvalg er ikke understøttede" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Bruger op til % trÃ¥de." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Filterkæde eller filterindstillinger er ikke understøttet" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Dekomprimering vil kræve %s MiB hukommelse." + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Justerede antallet af trÃ¥de fra %s til %s for ikke at overskride begræsningen pÃ¥ brug af hukommelse pÃ¥ %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Justerede antallet af trÃ¥de fra %s til %s for ikke at overskride begræsningen pÃ¥ brug af hukommelse pÃ¥ %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Justerede LZMA%c-ordbogsstørrelsen fra %s MiB til %s MiB for ikke at overskride begrænsningen pÃ¥ brug af hukommelse pÃ¥ %s MiB" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Justerede LZMA%c-ordbogsstørrelsen fra %s MiB til %s MiB for ikke at overskride begrænsningen pÃ¥ brug af hukommelse pÃ¥ %s MiB" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Error creating a pipe: %s" +msgid "Error changing to filter chain %u: %s" +msgstr "Det opstod en fejl under oprettelse af en datakanal: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Det opstod en fejl under oprettelse af en datakanal: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() mislykkedes: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Filen er vist blevet flyttet, sletter ikke" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Kan ikke fjerne: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Kan ikke angive filejeren: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Kan ikke angive filgruppen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Kan ikke angive filtilladelser: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Lukning af filen fejlede: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Lukning af filen fejlede: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Der opstod en fejl under indhentelse af filstatusflag fra standardind: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Er en symbolsk henvisning, udelader" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Er en mappe, udelader" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Er ikke en normal fil, udelader" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Filen har setuid- eller setgid-bitsæt, udelader" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Fil har klæbende bitsæt, udelader" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Inddatafil har mere end en hÃ¥rd henvisning, udelader" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Tomt filnavn, udelader" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Der opstod en fejl under gendannelse af statusflagene til standardind: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Der opstod en fejl under indhentelse af filstatusflag fra standardud: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Lukning af filen fejlede: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%s: Er ikke en normal fil, udelader" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Der opstod en fejl under gendannelse af flaget O_APPEND til standardud: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Lukning af filen fejlede: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Søgning fejlede under forsøg pÃ¥ at oprette en tynd fil: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Læsefejl: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Der opstod en fejl under søgning efter filen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Uventet filafslutning" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Skrivefejl: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Deaktiveret" + +#: src/xz/hardware.c +#, fuzzy +#| msgid "Total amount of physical memory (RAM): " +msgid "Amount of physical memory (RAM):" +msgstr "Samlet mængde fysisk hukommelse (RAM): " + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "" + +#: src/xz/hardware.c +#, fuzzy +#| msgid "Memory usage limit for decompression: " +msgid "Multi-threaded decompression:" +msgstr "Grænse for hukommelsesforbug til dekomprimering: " + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "" + +#: src/xz/hardware.c +#, fuzzy +#| msgid "Memory usage limit reached" +msgid "Memory usage limits:" +msgstr "Begrænsning pÃ¥ brug af hukommelse er nÃ¥et" + +#: src/xz/list.c +msgid "Streams:" +msgstr "" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "" + +#: src/xz/list.c +#, fuzzy +#| msgid " Compressed size: %s\n" +msgid "Compressed size:" +msgstr " Komprimeret str.: %s\n" + +#: src/xz/list.c +#, fuzzy +#| msgid " Uncompressed size: %s\n" +msgid "Uncompressed size:" +msgstr " Ukomprimeret str.: %s\n" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "" + +#: src/xz/list.c +msgid "Check:" +msgstr "" + +#: src/xz/list.c +#, fuzzy +#| msgid " Stream padding: %s\n" +msgid "Stream Padding:" +msgstr " Strømfyld: %s\n" + +#: src/xz/list.c +#, fuzzy +#| msgid " Memory needed: %s MiB\n" +msgid "Memory needed:" +msgstr " Hukommelse krævet: %s MiB\n" + +#: src/xz/list.c +#, fuzzy +#| msgid " Sizes in headers: %s\n" +msgid "Sizes in headers:" +msgstr " Størrelser i teksthoveder: %s\n" + +#: src/xz/list.c +#, fuzzy +#| msgid " Number of files: %s\n" +msgid "Number of files:" +msgstr " Antal filer: %s\n" + +#: src/xz/list.c +msgid "Stream" +msgstr "" + +#: src/xz/list.c +msgid "Block" +msgstr "" + +#: src/xz/list.c +msgid "Blocks" +msgstr "" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "" + +#: src/xz/list.c +msgid "CompSize" +msgstr "" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "" + +#: src/xz/list.c +#, fuzzy +#| msgid "Totals:" +msgid "TotalSize" +msgstr "I alt:" + +#: src/xz/list.c +msgid "Ratio" +msgstr "" + +#: src/xz/list.c +msgid "Check" +msgstr "" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "" + +#: src/xz/list.c +msgid "Padding" +msgstr "" + +#: src/xz/list.c +msgid "Header" +msgstr "" + +#: src/xz/list.c +msgid "Flags" +msgstr "" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "" + +#: src/xz/list.c +msgid "Filters" +msgstr "" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Ingen" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Ukendt-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Ukendt-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Ukendt-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Ukendt-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Ukendt-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Ukendt-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Ukendt-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Ukendt-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Ukendt-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Ukendt-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Ukendt-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Ukendt-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Filen er tom" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: For lille til at være en gyldig .xz-fil" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "" + +#: src/xz/list.c +msgid "Yes" +msgstr "Ja" + +#: src/xz/list.c +msgid "No" +msgstr "Nej" + +#: src/xz/list.c +#, fuzzy +#| msgid " Minimum XZ Utils version: %s\n" +msgid "Minimum XZ Utils version:" +msgstr " Minimum for XZ Utils-version: %s\n" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s fil\n" +msgstr[1] "%s filer\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "I alt:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "" + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list understøtter ikke læsning fra standardind" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Der opstod en fejl under forsøg pÃ¥ læsning af filnavne: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Uventet afslutning pÃ¥ inddata under forsøg pÃ¥ læsning af filnavne" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Komprimering og dekomprimering med --robot er endnu ikke understøttet." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Intern fejl (fejl)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Kan ikke etbalere signalhÃ¥ndteringer" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Ingen integritetkontrol; verificerer ikke filintegritet" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Begrænsning pÃ¥ brug af hukommelse er nÃ¥et" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Filformatet blev ikke genkendt" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Tilvalg er ikke understøttede" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Komprimerede data er ødelagte" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Uventet afslutning pÃ¥ inddata" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB hukommelse er krævet. Begrænseren er deaktiveret." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB hukommelse er krævet. Begrænsningen er %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Filterkæde: %s\n" + +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "Try `%s --help' for more information." +msgid "Try '%s --help' for more information." +msgstr "Prøv »%s --help« for yderligere information." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "" +"Obligatoriske argumenter til lange tilvalg er ogsÃ¥ obligatoriske for korte\n" +"tilvalg.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr " Operationstilstand:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Memory usage limit for decompression: " +msgid "force compression" +msgstr "Grænse for hukommelsesforbug til dekomprimering: " + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Memory usage limit for decompression: " +msgid "force decompression" +msgstr "Grænse for hukommelsesforbug til dekomprimering: " + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +"Operationsændrere:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "Skrivning til standardud mislykkedes" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "compression mode" +msgstr " Operationstilstand:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +"Andre tilvalg:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr "" +" --robot brug beskeder der kan fortolkes maskinelt (nyttigt\n" +" for skripter)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version vis versionsnummer og afslut" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"Med ingen FIL, eller nÃ¥r FIL er -, læs standardind.\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"Rapporter fejl til <%s> (pÃ¥ engelsk eller finsk).\n" +"Rapporter oversættelsesfejl til .\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "%s hjemmeside: <%s>\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "DETTE ER EN UDVIKLINGSVERSION - BRUG IKKE I PRODUKTION." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "The supported filters and their options are:" +msgstr "Filterkæde eller filterindstillinger er ikke understøttet" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be `name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s: Tilvalg skal være »navne=værdi«-par adskilt med kommaer" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Ugyldigt tilvalgsnavn" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s: Ugyldigt tilvalgsværdi" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "LZMA1/LZMA2-forhÃ¥ndskonfiguration er ikke understøttet: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Summen af lc og lp mÃ¥ ikke være højere end 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Filnavn har ukendt endelse, udelader" + +#: src/xz/suffix.c +#, fuzzy, c-format +#| msgid "%s: File already has `%s' suffix, skipping" +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Filen har allrede endelsen »%s«, udelader." + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Ugyldig filnavnendelse" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%s: Værdi er ikke et positivt decimalheltal" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Ugyldig multiplikatorendelse" + +#: src/xz/util.c +#, fuzzy +#| msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)." +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Gyldige endelser er »KiB« (2^10), »MiB« (2^20) og »GiB« (2^30)." + +#: src/xz/util.c +#, fuzzy, c-format +#| msgid "Value of the option `%s' must be in the range [%, %]" +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Værdien for tilvalget »%s« skal være i intervallet [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Komprimerede data kan ikke læses fra en terminal" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Komprimerede data kan ikke skrives til en terminal" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "%s: Too small to be a valid .xz file" +msgid "File is too small to be a .lzma file" +msgstr "%s: For lille til at være en gyldig .xz-fil" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Skrivning til standardud mislykkedes" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Ukendt fejl" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "Tilvalg er ikke understøttede" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "Filterkæde eller filterindstillinger er ikke understøttet" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s: Ugyldigt tilvalgsnavn" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s: Ugyldig multiplikatorendelse" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s: Ukendt filformattype" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "LZMA1 kan ikke bruges med .xz-formatet" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "Maksimalt antal filtre er fire" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help vis den korte hjælpetekst (viser kun grundlæggende\n" +#~ " tilvalg)\n" +#~ " -H, --long-help vis den lange hjælpetekst og afslut" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help vis den korte hjælpetekst og afslut\n" +#~ " -H, --long-help vis den lange hjælpetekst (viser ogsÃ¥ de avancerede\n" +#~ " tilvalg)" + +#~ msgid "Sandbox is disabled due to incompatible command line arguments" +#~ msgstr "Sandkassen er deaktiveret pÃ¥ grund af inkompatible kommandolinjeargumenter" + +#~ msgid "Sandbox was successfully enabled" +#~ msgstr "Sandkassen blev aktiveret" + +#~ msgid "Failed to enable the sandbox" +#~ msgstr "Kunne ikke aktivere sandkassen" + +#~ msgid "Memory usage limit for compression: " +#~ msgstr "Grænse for hukommelsesforbrug til komprimering: " + +#, c-format +#~ msgid " Streams: %s\n" +#~ msgstr " Strømme: %s\n" + +#, c-format +#~ msgid " Blocks: %s\n" +#~ msgstr " Blokke: %s\n" + +#, c-format +#~ msgid " Ratio: %s\n" +#~ msgstr " Pakkeforhold: %s\n" + +#, c-format +#~ msgid " Check: %s\n" +#~ msgstr " Kontrol: %s\n" + +#~ msgid "" +#~ " Streams:\n" +#~ " Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding" +#~ msgstr "" +#~ " Strømme:\n" +#~ " Strøm Blokke KompForsk. DekompForsk. KompStr. DekompStr. Forh. Kontrol Fyld" + +#, c-format +#~ msgid "" +#~ " Blocks:\n" +#~ " Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check" +#~ msgstr "" +#~ " Blokke:\n" +#~ " Strøm Blok KompForsk. DekompForsk. Ialtstr. DekompStr. Forh. Kontrol" + +#, c-format +#~ msgid " CheckVal %*s Header Flags CompSize MemUsage Filters" +#~ msgstr " KontrolVær %*sTeksth Flag Kompstr. HukForb. Filtre" + +#, c-format +#~ msgid "The selected match finder requires at least nice=%" +#~ msgstr "Den valgte matchfinder kræver mindst nice=%" diff --git a/cpp/third_party/xz-5.8.3/po/de.gmo b/cpp/third_party/xz-5.8.3/po/de.gmo new file mode 100644 index 0000000000000000000000000000000000000000..b1880f4e73982b1a4a8d7a7cccf928f851fce873 GIT binary patch literal 29882 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 IITt1RPd`e2e*gdg literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/de.po b/cpp/third_party/xz-5.8.3/po/de.po new file mode 100644 index 000000000..ab7d433b7 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/de.po @@ -0,0 +1,1267 @@ +# SPDX-License-Identifier: 0BSD +# +# German translation for xz. +# This file is published under the BSD Zero Clause License. +# André Noll , 2010. +# Anna Henningsen , 2015. +# Mario Blättermann , 2019, 2022-2025. +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-01-26 11:02+0100\n" +"Last-Translator: Mario Blättermann \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 24.12.1\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Ungültiges Argument für --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Zu viele Argumente für --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "In --block-list fehlt die Blockgröße nach der Filterkettennummer »%c:«" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 kann nur das letzte Element in --block-list sein" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Unbekanntes Dateiformat" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Integritätsprüfungstyp nicht unterstützt" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Nur eine Datei kann als Argument für »--files« oder »--files0« angegeben werden." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Die Umgebungsvariable %s enthält zu viele Argumente" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Die Unterstützung für Kompression wurde zum Zeitpunkt der Erstellung deaktiviert" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Die Unterstützung für Dekompression wurde zum Zeitpunkt der Erstellung deaktiviert" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Kompression von lzip-Dateien (.lz) wird nicht unterstützt" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list wird ignoriert, außer wenn in das .xz-Format komprimiert wird" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Mit --format=raw ist --suffix=.SUF notwendig, falls nicht in die Standardausgabe geschrieben wird" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Maximal vier Filter möglich" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Fehler in der Option --filters%s=FILTER:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Die Speicherbedarfsbegrenzung ist für die gegebene Filter-Konfiguration zu niedrig." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "Filterkette %u wird von --block-list verwendet, wurde aber nicht mit --filters%u= angegeben" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Verwendung einer Voreinstellung im Roh-Modus wird nicht empfohlen." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Die genauen Optionen der Voreinstellung können zwischen Softwareversionen variieren." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Das .lzma-Format unterstützt nur den LZMA1-Filter" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 kann nicht mit dem .xz-Format verwendet werden" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Die Filterkette %u ist inkompatibel zu --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Wegen --flush-timeout wird auf den Einzelthread-Modus umgeschaltet" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Nicht unterstützte Optionen in Filterkette %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Bis zu % Threads werden benutzt." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Filterkette oder Filteroptionen werden nicht unterstützt" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Dekompression wird %s MiB Speicher brauchen." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Anzahl der Threads wurde von %s auf %s reduziert, um die Speicherbedarfsbegrenzung von %s MiB nicht zu übersteigen" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Anzahl der Threads wurde von %s auf einen reduziert. Die automatische Begrenzung des Speicherverbrauchs auf %s MiB wird immer noch überschritten. %s MiB an Speicher sind erforderlich. Es wird dennoch fortgesetzt." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Es wurde in den Einzelthread-Modus gewechselt, um die Speicherbedarfsbegrenzung von %s MiB nicht zu übersteigen" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Die LZMA%c-Wörterbuchgröße wurde von %s MiB auf %s MiB angepasst, um die Speicherbedarfsbegrenzung von %s MiB nicht zu übersteigen" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Die LZMA%c-Wörterbuchgröße für --filters%u wurde von %s MiB auf %s MiB angepasst, um die Speicherbedarfsbegrenzung von %s MiB nicht zu übersteigen" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Fehler beim Wechsel zur Filterkette %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Fehler beim Erzeugen der Pipeline: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() ist fehlgeschlagen: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Datei scheint verschoben worden zu sein, daher wird sie nicht gelöscht" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Löschen nicht möglich: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Dateieigentümer kann nicht gesetzt werden: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Dateigruppe kann nicht gesetzt werden: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Zugriffsrechte können nicht gesetzt werden: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Fehler beim Synchronisieren der Datei: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Fehler beim Synchronisieren des Verzeichnisses der Datei: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Dateistatus-Markierungen können nicht aus der Standardeingabe ermittelt werden: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Ist ein symbolischer Link, wird übersprungen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Ist ein Verzeichnis, wird übersprungen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Keine reguläre Datei, wird übersprungen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Datei hat das setuid- oder setgid-Bit gesetzt, wird übersprungen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Datei hat sticky-Bit gesetzt, wird übersprungen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Eingabedatei hat mehr als einen harten Link, wird übersprungen" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Leerer Dateiname, wird übersprungen" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Fehler beim Wiederherstellen der Status-Markierungen für die Standardeingabe: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Status-Markierungen der Standardausgabe können nicht ermittelt werden: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Fehler beim Öffnen des Verzeichnisses: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: Ziel ist keine reguläre Datei" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Fehler beim Wiederherstellen der O_APPEND-Markierungen für die Standardausgabe: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Fehler beim Schließen der Datei: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Positionierungsfehler beim Versuch, eine Sparse-Datei (dünnbesetzte Datei) zu erzeugen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Lesefehler: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Fehler beim Durchsuchen der Datei: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Unerwartetes Ende der Datei" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Schreibfehler: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Deaktiviert" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Gesamtmenge physischer Speicher (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Anzahl der Prozessor-Threads:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Kompression:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Dekompression:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Multithread-Dekompression:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Vorgabe für -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Hardware-Information:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Speicherbedarfsbegrenzung:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Datenströme:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blöcke:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Größe komprimiert:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Größe unkomprimiert:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Verhältnis:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Prüfung:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Datenstromauffüllung:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Benötigter Speicher:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Größe in Köpfen:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Anzahl Dateien:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Datenstrom" + +#: src/xz/list.c +msgid "Block" +msgstr "Block" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blöcke" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "KompVers" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "UnkompVers" + +#: src/xz/list.c +msgid "CompSize" +msgstr "KompGröße" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "UnkompGröße" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "Gesamt" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Verhältnis" + +#: src/xz/list.c +msgid "Check" +msgstr "Prüfung" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "Prüfwert" + +#: src/xz/list.c +msgid "Padding" +msgstr "Auffüllung" + +#: src/xz/list.c +msgid "Header" +msgstr "Kopf" + +#: src/xz/list.c +msgid "Flags" +msgstr "Flags" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "SpeichVerb" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filter" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Keine" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Unbek.2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Unbek.3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Unbek.5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Unbek.6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Unbek.7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Unbek.8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Unbek.9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Unbek.11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Unbek.12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Unbek.13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Unbek.14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Unbek.15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Datei ist leer" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Zu klein, um eine gültige .xz-Datei zu sein" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr " Str. Blöcke Kompr. Unkompr. Verh. Check Dateiname" + +#: src/xz/list.c +msgid "Yes" +msgstr "Ja" + +#: src/xz/list.c +msgid "No" +msgstr "Nein" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Minimal erforderliche XZ Utils-Version:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s Datei\n" +msgstr[1] "%s Dateien\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Gesamt:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list funktioniert nur mit .xz-Dateien (--format=xz oder --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Versuchen Sie »lzmainfo« mit .lzma-Dateien." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list unterstützt kein Lesen aus der Standardeingabe" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Fehler beim Lesen der Dateinamen: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Unerwartetes Ende der Eingabe beim Lesen der Dateinamen" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Null-Zeichen beim Lesen der Dateinamen gefunden; meinten Sie »--files0« statt »--files«?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Kompression und Dekompression mit --robot wird noch nicht unterstützt." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Lesen der Daten aus der Standardeingabe ist nicht möglich, wenn die Dateinamen auch aus der Standardeingabe gelesen werden" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Interner Fehler (Bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Signalroutine kann nicht gesetzt werden" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Keine Integritätsprüfung; Integrität der Datei wird nicht überprüft" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Typ der Integritätsprüfung wird nicht unterstützt; Integrität der Datei wird nicht überprüft" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Speicherbedarfsbegrenzung erreicht" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Dateiformat nicht erkannt" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Optionen nicht unterstützt" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Komprimierte Daten sind beschädigt" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Unerwartetes Ende der Eingabe" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB Speicher wird benötigt. Die Begrenzung ist deaktiviert." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB Speicher wird benötigt. Die Begrenzung ist %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Filterkette: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Versuchen Sie »%s --help« für mehr Informationen." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Fehler bei der Ausgabe des Hilfetextes (Fehlercode %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Aufruf: %s [OPTION] … [DATEI] …\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Komprimiert oder dekomprimiert .xz-DATEI(EN)." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "" +"Obligatorische Argumente für lange Optionen sind auch für kurze Optionen\n" +"zwingend." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Aktionsmodus:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "Kompression erzwingen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "Dekompression erzwingen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "Integrität der komprimierten Datei überprüfen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "Informationen zu .xz-Dateien auflisten" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Aktionsmodifikatoren:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "Eingabedateien beibehalten (nicht löschen)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "Überschreiben der Ausgabedatei erzwingen und Links (de)komprimieren" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "In die Standardausgabe schreiben und die Eingabedateien nicht löschen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "Ausgabedatei nicht auf dem Speichergerät synchronisieren, bevor die Eingabedatei gelöscht wird" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "Nur den ersten Datenstrom dekomprimieren und stillschweigend mögliche weitere Eingabedaten ignorieren" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "Beim Dekomprimieren keine Sparse-Dateien erzeugen" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".END" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "».END« als Endung für komprimierte Dateien benutzen" + +#: src/xz/message.c +msgid "FILE" +msgstr "DATEI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "Zu verarbeitende Dateinamen aus DATEI lesen; falls keine DATEI angegeben wurde, werden Dateinamen aus der Standardeingabe gelesen. Dateinamen müssen durch einen Zeilenumbruch voneinander getrennt werden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "Wie --files, aber das Null-Zeichen wird als Trenner benutzt" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Grundlegende Optionen für Dateiformat und Kompression:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMAT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "Dateiformat zur Kodierung oder Dekodierung; mögliche Werte sind »auto« (Voreinstellung), »xz«, »lzma«, »lzip« und »raw«" + +#: src/xz/message.c +msgid "NAME" +msgstr "NAME" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "Typ der Integritätsprüfung: »none« (Vorsicht!), »crc32«, »crc64« (Voreinstellung) oder »sha256«" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "Integritätsprüfung beim Dekomprimieren nicht ausführen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "Kompressionseinstellung; Voreinstellung ist 6. Beachten Sie den Speicherbedarf des Kompressors *und* des Dekompressors, wenn Sie 7-9 benutzen!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "Versuchen, durch stärkere CPU-Auslastung das Kompressionsverhältnis zu verbessern. Dies beeinflusst nicht den Speicherbedarf des Dekompressors." + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "ANZAHL" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "Höchstens die angegebene ANZAHL Threads erzeugen; die Voreinstellung ist 0, wobei so viele Threads erzeugt werden, wie Prozessorkerne vorhanden sind" + +#: src/xz/message.c +msgid "SIZE" +msgstr "GRÖẞE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "Einen neuen .xz-Block nach der angegebenen GRÖẞE der Eingabe in Bytes beginnen; benutzen Sie diese Option, um die Blockgröße für die Kompression mit mehreren Threads zu setzen" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLÖCKE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "Einen neuen .xz-Block gemäß der angegebenen, durch Kommata getrennten Intervalle an unkomprimierten Daten beginnen; optional kann eine Filterkettennummer (0-9) angegeben werden, gefolgt von einem »:« und der unkomprimierten Datengröße" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "Wenn beim Komprimieren mehr als die angegebene ANZAHL an Millisekunden seit der letzten Leerungsaktion vergangen ist und das Lesen von zusätzlichen Eingabedaten den Prozess blockieren würde, dann werden alle noch ausstehenden Daten geschrieben" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "BEGRENZUNG" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "Speicherbedarfsbegrenzung für Kompression, Dekompression oder beides setzen; die BEGRENZUNG wird in Bytes oder als Prozentsatz RAM angegeben. Geben Sie 0 an, um die Grundeinstellungen zu verwenden." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "Wenn die Kompressionseinstellungen die Speicherbedarfsbegrenzung übersteigen, wird ein Fehler ausgegeben, statt die Einstellungen nach unten anzupassen." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Benutzerdefinierte Filterkette für Kompression (alternativ zur Verwendung von Voreinstellungen):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTER" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "Die Filterkette anhand der Liblzma-Filterkettensyntax setzen; mit --filters-help erhalten Sie weitere Informationen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "Zusätzliche Filter anhand der Liblzma-Filterkettensyntax setzen, die mit --block-list verwendet werden sollen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "Weitere Informationen über die Liblzma-Filterkettensyntax anzeigen und beenden." + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "OPTIONEN" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 oder LZMA2; OPTIONEN ist eine durch Kommata getrennte Liste bestehend aus den folgenden Optionen (zulässige Werte; Voreinstellung):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "ZAHL" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "Optionen auf Voreinstellungsstufe zurücksetzen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "Wörterbuchgröße" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "Anzahl der Literal-Kontext-Bits" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "Anzahl der Literal-Positions-Bits" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "Anzahl der Positions-Bits" + +#: src/xz/message.c +msgid "MODE" +msgstr "MODUS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "Kompressionsmodus" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "Nice-Länge eines Treffers" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "Algorithmus zum Auffinden von Übereinstimmungen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "Maximale Suchtiefe; 0=automatisch (Voreinstellung)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ-Filter (32-bit und 64-bit)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM-BCJ-Filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb-BCJ-Filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64-BCJ-Filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC-BCJ-Filter (nur Big Endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA64-(Itanium-)BCJ-Filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC-BCJ-Filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V-BCJ-Filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "Zulässige Optionen für alle BCJ-Filter:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "Startversatz für Konversion (Voreinstellung=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Delta-Filter; zulässige Optionen (gültige Werte; Voreinstellung):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "Abstand zwischen den Bytes, die voneinander subtrahiert werden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Andere Optionen:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "Warnungen unterdrücken; wird diese Option zweimal angegeben, werden auch Fehlermeldungen unterdrückt" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "Ausführlicher Modus; wird diese Option zweimal angegeben, erfolgen noch ausführlichere Ausgaben" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "Warnungen verändern nicht den Exit-Status" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "Maschinenlesbare Meldungen ausgeben (nützlich für Skripte)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "Gesamtspeicher (RAM) sowie die gegenwärtig aktive Speicherbedarfsbegrenzung anzeigen und das Programm beenden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "Kurze Hilfe anzeigen (zeigt nur die grundlegenden Optionen)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "Diese lange Hilfe anzeigen und das Programm beenden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "Diese kurze Hilfe anzeigen und das Programm beenden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "Die lange Hilfe (und damit auch fortgeschrittene Optionen) anzeigen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "Versionsnummer anzeigen und beenden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Wenn DATEI nicht angegeben wurde oder DATEI gleich - ist, dann wird aus der Standardeingabe gelesen." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Melden Sie Fehler an <%s> (auf Englisch oder Finnisch)." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "%s-Homepage: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "DIES IST EINE NICHT FÜR DEN PRODUKTIVBETRIEB GEEIGNETE ENTWICKLERVERSION." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Filterketten werden durch Setzen der Optionen --filters=FILTER oder --filters1=FILTER … --filters9=FILTER definiert. Die Filter können innerhalb der Kette durch Leerzeichen oder »--« getrennt werden. Alternativ kann eine Voreinstellung %s anstelle einer Filterkette verwendet werden." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Folgende Filterkettem und Filteroptionen werden unterstützt:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Optionen müssen in der Form »Name=Wert« gegeben werden, getrennt durch Kommata" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Ungültiger Optionsname" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Ungültiger Optionswert" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "LZMA1/LZMA2-Voreinstellung wird nicht unterstützt: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Die Summe aus lc und lp darf höchstens 4 sein" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Dateiname hat unbekanntes Suffix, wird übersprungen" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Datei hat bereits das Suffix »%s«, wird übersprungen" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Ungültige Dateiendung" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Wert ist keine nicht-negative dezimale Ganzzahl" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Ungültige Einheit" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Gültige Einheiten sind »KiB« (2^10), »MiB« (2^20) und »GiB« (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Wert der Option »%s« muss im Bereich [%, %] sein" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Komprimierte Daten können nicht vom Terminal gelesen werden" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Komprimierte Daten können nicht auf das Terminal geschrieben werden" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Aufruf: %s [--help] [--version] [DATEI] …\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Im .lzma-Dateikopf gespeicherte Informationen anzeigen." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Die Datei ist zu klein, um eine .lzma-Datei zu sein" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Keine .lzma-Datei" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Schreiben in die Standardausgabe fehlgeschlagen" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Unbekannter Fehler" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Voreinstellung wird nicht unterstützt" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Nicht unterstützter Schalter in der Voreinstellung" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Unbekannter Optionsname" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Optionswert darf nicht leer sein" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Wert ist außerhalb des zulässigen Bereichs" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Diese Option unterstützt keine Einheiten-Endungen" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Ungültige Einheit (KiB, MiB oder GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Unbekannter Filtername" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Dieser Filter kann nicht im .xz-Format verwendet werden" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Speicherzuweisung ist fehlgeschlagen" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Leere Zeichenkette ist nicht erlaubt; versuchen Sie »6«, wenn der Vorgabewert erwünscht ist" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Maximal vier Filter sind möglich" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Filtername fehlt" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Unzulässige Filterkette (»lzma2« fehlt am Ende?)" diff --git a/cpp/third_party/xz-5.8.3/po/en@boldquot.header b/cpp/third_party/xz-5.8.3/po/en@boldquot.header new file mode 100644 index 000000000..ac96ad9f3 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/en@boldquot.header @@ -0,0 +1,35 @@ +%% A header that gets inserted into message catalogs named en@boldquot.po. +%% +%% Copyright (C) 2001 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 file is offered as-is, without any warranty. +%% +%% Written by Bruno Haible , 2001. +%% +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# +# This catalog furthermore displays the text between the quotation marks in +# bold face, assuming the VT100/XTerm escape sequences. +# diff --git a/cpp/third_party/xz-5.8.3/po/en@quot.header b/cpp/third_party/xz-5.8.3/po/en@quot.header new file mode 100644 index 000000000..287e2e735 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/en@quot.header @@ -0,0 +1,32 @@ +%% A header that gets inserted into message catalogs named en@quot.po. +%% +%% Copyright (C) 2001 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 file is offered as-is, without any warranty. +%% +%% Written by Bruno Haible , 2001. +%% +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# diff --git a/cpp/third_party/xz-5.8.3/po/eo.gmo b/cpp/third_party/xz-5.8.3/po/eo.gmo new file mode 100644 index 0000000000000000000000000000000000000000..7839b5360b2dd9819c8174168223f7adb22042cc GIT binary patch literal 15060 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, 2019, 2023–2024. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.6.0-pre2\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2024-02-24 00:16-0500\n" +"Last-Translator: Keith Bowes \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Nevalida parametro por --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Tro da argumentoj por --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "En --block-list, la blokgrando mankas post numero de la filtrila ĉeno '%c:'" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 povas nur esti uzata kiel la lasta elemento en --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Nekonata dosierformata tipo" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Nekomprenata tipo de integra kontrolo" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Nur unu dosiero estas specifebla per '--files' aÅ­ '--files0'." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "La medivariablo %s enhavas troajn argumentojn" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Rego de kunpremado estas malaktivigita dum muntotempo" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Rego de malkunpremado estas malaktivigita dum muntotempo" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Ne povas kunpremi lzip-dosierojn (.lz)" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list estas ignorata se ne kunpremas al la formato .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Kun --format=raw, --suffix=.SUF estas postulata se ne skribi al la ĉefeligujo" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Maksimuma nombra da filtriloj estas kvar" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Erora en la --filters%s=FILTRILOJ elekto:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Memoruzada limigo estas tro malgranda por la donita filtrila elekto." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "filtrila ĉeno %u uzata de --block-list sed ne specifita per --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Uzi aprioraĵon en kruda reÄimo estas malkonsilinda." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "La Äustaj elektoj de la aprioraĵoj povas varii inter programoj eldonoj." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "La .lzma-formato komprenas sole la filtrilon LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA ne estas uzebla por la .xz-formato" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "La filtrila ĉeno %u estas nekongrua kun --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "ÅœanÄas al unufadena reÄimo pro --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Nekomprenataj elektoj en filtrila ĉeno %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Uzas Äis % fadenoj" + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Nekomprenata filtrila ĉeno aÅ­ filtrilaj elektoj" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Malkunpremado postulos %s megabajtojn da memoro." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Malpliigis la nombron da fadenoj de %s Äis %s por ne superi la memoruzadan limigo de %s megabajtoj" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Malpliigis la nombron da fadenoj de %s Äis unu. La aÅ­tomata memoruzada limigo de %s megabajtoj ankoraÅ­ estas superata. %s megabajtoj da memoro estas postulata. Senkonsidere daÅ­rigas." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "ÅœanÄas al unufadena reÄimo por ne superi la memoruzadan limigon de %s megabajtoj" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "AlÄÅ­stigis vortara grando de LZMA%c de %s megabajtoj Äis %s megabajtoj por ne superi la memoruzadan limigon de %s megabajtoj" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "AlÄustigis vortara grando de LZMA%c por --filters%u de %s megabajtoj Äis %s megabajtoj por ne superi la memoruzadan limigon de %s megabajtoj" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Eraro dum ÅanÄiÄo al filtrila ĉeno %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Eraro dum krei dukton: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() malsukcesis: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Dosiero Åajne estis movita, ne forigos" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Ne eblas forigi: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Ne eblas agordi la dosieran estron: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Ne eblas agordi la dosieran grupon: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Ne eblas agordi la dosierajn atingopermesojn: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Fermo de la dosiero malsukcesis: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Fermo de la dosiero malsukcesis: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Eraro dum atingi la dosierstatajn flagojn de ĉefenigujon: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Estas simbola ligilo, preterpasas" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Estas dosierujo, preterpasas" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Ne regula dosiero, preterpasas" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Dosiero havas setuid- aÅ­ setgid-biton, preterpasas" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Dosiero havas glueman biton, preterpasas" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Enmeta dosiero havas pli ol rektan ligilon, preterpasas" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Malplena dosiero, preterpasas" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Eraro dum restarigi la statajn flagojn de la ĉefenigujo: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Eraro dum atingi la dosierstatajn flagojn el la ĉefenigujo: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Fermo de la dosiero malsukcesis: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%s: Ne regula dosiero, preterpasas" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Eraro dum restarigi la flagon O_APPEND de la ĉefenigujo: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Fermo de la dosiero malsukcesis: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Serĉado malsukcesis dum provi krei maldensan dosieron: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Legeraro: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Eraro dum serĉi la dosieron: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Neatendita dosierfino" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Skriberaro: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Malaktiva" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Kiomo da efektiva memoro (ĉefmemoro)" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Nombro da procesoraj fadenoj:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Kunpremo:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Malkunmpreno:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Plurfadena malkunpremado:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Aprioraĵo por -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Aparataro-informoj:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Memoruzada limigoj:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Fluoj:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blokoj:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Kunpremita grando:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Nekunpremita grando:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Proporcio:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Kontrolo:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Fluo-remburo:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Memoro postulata:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Grandoj en ĉapoj:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Nombro da dosieroj:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Fluo" + +#: src/xz/list.c +msgid "Block" +msgstr "Bloko" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blokoj" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "KunpMsam" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "MKunMSam" + +#: src/xz/list.c +msgid "CompSize" +msgstr "Kunpgrando" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "Mkunpgrando" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "KiomGrando" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Proporcio" + +#: src/xz/list.c +msgid "Check" +msgstr "Kontrolo" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "KontVal" + +#: src/xz/list.c +msgid "Padding" +msgstr "Remburo" + +#: src/xz/list.c +msgid "Header" +msgstr "Ĉapo" + +#: src/xz/list.c +msgid "Flags" +msgstr "Flago" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "Memuzado" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtriloj" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Nenio" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Nekonata-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Nekonata-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Nekonata-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Nekonata-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Nekonata-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Nekonata-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Nekonata-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Nekonata-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Nekonata-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Nekonata-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Nekonata-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Nekonata-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Dosiero malplenas" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Tro malgranda por esti valida .xz-dosiero" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Fluoj Blokoj Kunpremita Nekunpremita Propor Kontrol Dosiernomo" + +#: src/xz/list.c +msgid "Yes" +msgstr "Jes" + +#: src/xz/list.c +msgid "No" +msgstr "Ne" + +#: src/xz/list.c +#, fuzzy +#| msgid " Minimum XZ Utils version: %s\n" +msgid "Minimum XZ Utils version:" +msgstr " Minimuma eldono de XZ Utils: %s\n" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s dosiero\n" +msgstr[1] "%s dosieroj\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Sumoj:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list funkcias nur por .xz-dosierojn (--format=xz aÅ­ --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Provi la programon 'lzmainfo' por .lzma-dosieroj." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list ne regas legadon el la ĉefenigujo" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Eraro dum legi dosiernomojn: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Neatendita fino de enigo dum legi dosiernomojn" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Nula signo trovita dum legi dosiernomojn; eble vi celis uzi la parametron '--files0' anstataÅ­ '--files'" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Kunpremo kaj malkunmpremo per --robot ankoraÅ­ ne estas regataj." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Ne eblas legi datumojn el la ĉefenigujo dum legi dosiernomojn el la ĉefenigujo" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Interna programeraro" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Ne eblas establi signalajn traktilojn" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Neniu integra kontrolo; ne certigos dosieran integron" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Nekomprenata tipo de integra kontrolo; ne certigos dosieran integron" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Memoruzada limigo atingita" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Dosierformato ne rekonata" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Nekomprenataj elektoj" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Kunpremitaj datumoj estas koruptaj" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Neatendita fino de enigo" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s megabajtoj da memoro estas postulataj. La limigilo estas malaktiva." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s megabajtoj da memoro estas postulata. La limigo estas %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Filtrila ĉeno: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "'%s --help' por pliaj informaj." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "Usage: %s [OPTION]... [FILE]...\n" +#| "Compress or decompress FILEs in the .xz format.\n" +#| "\n" +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" +"Uzmaniero: %s [ELEKTO].. [DOSIERO]...\n" +"Kunpremi aÅ­ malkunpremi DOSIEROjN laÅ­ la .xz-formato.\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "" +"Devigitaj parametroj por longaj elektoj estas ankaÅ­ devigitaj por\n" +"mallongaj elektoj.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr " Operacia reÄimo:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force compression" +msgstr "Malkunmpreno:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force decompression" +msgstr "Malkunmpreno:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +" Operacia modifiloj:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "Skribi al la ĉefeligujo malsukcesis" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --single-stream decompress only the first stream, and silently\n" +#| " ignore possible remaining input data" +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" +" --single-stream\n" +" malkunpremi nur la unuan fluon kaj silente\n" +" ignori eventualajn ceterajn enigajn datumojn" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Basic file format and compression options:\n" +msgid "Basic file format and compression options:" +msgstr "" +"\n" +" Bazaj dosierformataj kaj kunpremaj elektoj:\n" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --ignore-check don't verify the integrity check when decompressing" +msgid "don't verify the integrity check when decompressing" +msgstr " --ignore-check ne certigi la integran kontrolon dum malkunpremo" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -0 ... -9 compression preset; default is 6; take compressor *and*\n" +#| " decompressor memory usage into account before using 7-9!" +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" +" -0 ... -9 kunpremnivelo; apriore 6; pripensu memoruzadon antaÅ­ ol\n" +" uzi la nivelojn 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -e, --extreme try to improve compression ratio by using more CPU time;\n" +#| " does not affect decompressor memory requirements" +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" +" -e, --extreme provi plibonigi kunpreman proporcion per uzado de\n" +" ĉefprocesoran tempon; ne influas la memorajn postulojn\n" +" de malkunpremo" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -T, --threads=NUM use at most NUM threads; the default is 0 which uses\n" +#| " as many threads as there are processor cores" +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" +" -T, --threads=NOMBRO\n" +" uzi maksimume NOMBRO da fadenoj; apriore 0, kiu\n" +" uzas fadenojn samnombrajn kiel procesorajn kernojn" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-size=SIZE\n" +#| " start a new .xz block after every SIZE bytes of input;\n" +#| " use this to set the block size for threaded compression" +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" +" --block-size=GRANDO\n" +" komenci novan .xz-blokon post ĉiu GRANDO bajtoj da enigo;\n" +" uzi por agordi la blokan grandon por kunfadena kunpremo" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-list=BLOCKS\n" +#| " start a new .xz block after the given comma-separated\n" +#| " intervals of uncompressed data; optionally, specify a\n" +#| " filter chain number (0-9) followed by a ':' before the\n" +#| " uncompressed data size" +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" +" --block-list=BLOKOJ\n" +" komenci novan .xz-blokon post la donitajn intertempojn de\n" +" nekunpremitaj datumoj, apartigataj de komoj. LaÅ­vole\n" +" specifi numero (0-9) de filtrila ĉeno kaj poste ':' antaÅ­\n" +" la malkunpremita datuma grando" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --flush-timeout=TIMEOUT\n" +#| " when compressing, if more than TIMEOUT milliseconds has\n" +#| " passed since the previous flush and reading more input\n" +#| " would block, all pending data is flushed out" +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" +" --flush-timeout=TEMPOLIMO\n" +" dum kunpremo se pli ol TEMPOLIMO milisekundoj\n" +" okazis post la antaÅ­an elbufrigo kaj legi pliajn enigojn\n" +" paÅ­zigus, ĉiuj atendataj datumoj estas elbufrigataj" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --no-adjust if compression settings exceed the memory usage limit,\n" +#| " give an error instead of adjusting the settings downwards" +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" +" --no-adjust se kunprema agordo superas la memoruzadan limigon\n" +" montri eraron anstataÅ­ malgrandigi la agordaĵon" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Custom filter chain for compression (alternative for using presets):" +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" +"\n" +" Propra filtrila ĉeno por kunpremo (alternativaj por uzi antaÅ­agordaĵon):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " --filters=FILTERS set the filter chain using the liblzma filter string\n" +#| " syntax; use --filters-help for more information" +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" +"\n" +" --filters=FILTRILOJ agordi la filtrilan ĉenan uzanta la sintakso de la\n" +" lzma-filtrila ĉeno. --filters-help or pliaj informoj" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters1=FILTERS ... --filters9=FILTERS\n" +#| " set additional filter chains using the liblzma filter\n" +#| " string syntax to use with --block-list" +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" +" --filters=FILTRILOJ ... --filters9=FILTRILOJ\n" +" agordi aldonajn filtrilajn ĉenojn por uzi kun\n" +" --block-list per la sintakso de liblzma-filtrila ĉeno" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters-help display more information about the liblzma filter string\n" +#| " syntax and exit." +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" +" --filters-help montri pliajn informojn pri la sintakso de la\n" +" liblzma-filtrila ĉeno kaj poste eliri." + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Number of processor threads:" +msgid "number of position bits" +msgstr "Nombro da procesoraj fadenoj:" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "compression mode" +msgstr "Malkunmpreno:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +" Aliaj elektoj:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -Q, --no-warn make warnings not affect the exit status" +msgid "make warnings not affect the exit status" +msgstr " -Q, --no-warn avertoj ne influu la eliran staton" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr " --robot uzi mesaÄojn facile analizeblaj per skriptoj" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --info-memory display the total amount of RAM and the currently active\n" +#| " memory usage limits, and exit" +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" +" --info-memory montri la totalan kiomon de la ĉefmemoro kaj la nune\n" +" aktivaj memoruzadaj limigoj, kaj finiÄi" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version montri la eldonan numeron kaj finiÄi" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"Kun neniu DOSIERO aÅ­ kiam DOSIERO estas -, legi el la ĉefenigujo.\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Raporti programerarojn al <%s> (en la angla aÅ­ la suoma).\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "%s ĉefpaÄo: <%s>\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ĈI TIU ESTAS DISVOLVA REDAKCIO, NE CELATA POR ĈIUTAGA UZADO." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "" +#| "Filter chains are set using the --filters=FILTERS or\n" +#| "--filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain\n" +#| "can be separated by spaces or '--'. Alternatively a preset <0-9>[e] can be\n" +#| "specified instead of a filter chain.\n" +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" +"Filtrilaj ĉenoj estas agorditaj per la elektoj --filters=FIILTRILOJ aÅ­\n" +"--filters1=FILTRILOJ ... --filters9=FILTRILOJ. Ĉiu filtrilo en la ĉeno\n" +"estas apartigebla per spacetoj aÅ­ '--'. Alternative antaÅ­argordo <0-9>[e]\n" +"anstataÅ­ filtrila ĉeno estas specifebla.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "La komprenataj filtriloj aÅ­ filtrilaj elektoj estas:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be 'name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s: Elektoj devas esti paroj de 'name=value', apartigitaj per komoj" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Nevalida elekto-nomo" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s: Nevalida elekto-valoro" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Nevalida LZMA1/LZMA2 antaÅ­agordaĵo: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "La sumo de lc kaj lp devas ne esti pli ol 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Dosiernomo havas nekonatan sufikson, preterpasas" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Dosiero jam havas la sufikson '%s', preterpasas" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Nevalida dosiernoma sufikso" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%s: Valoro ne estas nenegativa dekuma entjero" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Nevalida multiplika sufikso" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Validaj sufiksoj estas 'KiB' (2^10), 'MiB' (2^20) kaj 'GiB' (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Valoro de la elekto '%s' devas esti inkluzive inter % kaj %" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Kunpremitaj datumoj ne povas esti ligataj de terminalo" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Kunpremitaj datumoj ne povas esti skribataj al terminalo" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" +"Uzmaniero: %s [--help] [--version] [DOSIERO]...\n" +"Montri informojn konservitaj en la .lzma-dosiera ĉapo" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Show information stored in the .lzma file header." +msgstr "" +"Uzmaniero: %s [--help] [--version] [DOSIERO]...\n" +"Montri informojn konservitaj en la .lzma-dosiera ĉapo" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Dosiero malgrandas por esti .lzma-dosiero" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Ne .lzma-dosiero" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Skribi al la ĉefeligujo malsukcesis" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Nekonata eraro" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "Nekomprenataj elektoj" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "Nekomprenata filtrila ĉeno aÅ­ filtrilaj elektoj" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s: Nevalida elekto-nomo" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s: Nevalida multiplika sufikso" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s: Nekonata dosierformata tipo" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "LZMA ne estas uzebla por la .xz-formato" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "Maksimuma nombra da filtriloj estas kvar" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -z, --compress force compression\n" +#~ " -d, --decompress force decompression\n" +#~ " -t, --test test compressed file integrity\n" +#~ " -l, --list list information about .xz files" +#~ msgstr "" +#~ " -z, --compress eldevigi kunpremon\n" +#~ " -d, --decompress eldevigi malkunpremon\n" +#~ " -t, --test certigi la integron de kunpremitan dosieron\n" +#~ " -l, --list listigi informojn pri .xz-dosierojn" + +#~ msgid "" +#~ " -k, --keep keep (don't delete) input files\n" +#~ " -f, --force force overwrite of output file and (de)compress links\n" +#~ " -c, --stdout write to standard output and don't delete input files" +#~ msgstr "" +#~ " -k, --keep ne forigi enigajn dosierojn\n" +#~ " -f, --force eldevigi anstataÅ­igi eligajn dosierojn kaj\n" +#~ " (mal)kunpmremajn ligilojn \n" +#~ " -c, --stdout skribi al la ĉefeligujo kaj ne forigi enigajn dosierojn" + +#~ msgid "" +#~ " --no-sparse do not create sparse files when decompressing\n" +#~ " -S, --suffix=.SUF use the suffix '.SUF' on compressed files\n" +#~ " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~ " omitted, filenames are read from the standard input;\n" +#~ " filenames must be terminated with the newline character\n" +#~ " --files0[=FILE] like --files but use the null character as terminator" +#~ msgstr "" +#~ " --no-sparse ne krei maldensajn dosierojn dum malkunpremiÄo\n" +#~ " -S, --suffix=.SUF uzi la sufikson '.SUF' ĉe kunpremataj dosieroj\n" +#~ " --files[=DOSIERO]\n" +#~ " legi dosiernomojn traktotajn el DOSIERO; se DOSIERO estas\n" +#~ " forlasita, dosiernomoj estas legataj el la ĉefenigujo;\n" +#~ " dosiernomojn devas finigi novlinia signo\n" +#~ " --files0[=DOSIERO]\n" +#~ " kiel --files sed uzi la nulan signon por finigi" + +#~ msgid "" +#~ " -F, --format=FMT file format to encode or decode; possible values are\n" +#~ " 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'\n" +#~ " -C, --check=CHECK integrity check type: 'none' (use with caution),\n" +#~ " 'crc32', 'crc64' (default), or 'sha256'" +#~ msgstr "" +#~ "h -F, --format=FMT dosierformato kodota aÅ­ malkodata; validaj valoroj estas\n" +#~ " 'auto' (apriora), 'xz', 'lzma', 'lzip' kaj 'raw'\n" +#~ " -C, --check=KONT tipo de integra kontrolo: 'none' (estu atentema),\n" +#~ " 'crc32', 'crc64' (apriora) aÅ­ 'sha256'" + +#, no-c-format +#~ msgid "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " --memlimit-mt-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " set memory usage limit for compression, decompression,\n" +#~ " threaded decompression, or all of these; LIMIT is in\n" +#~ " bytes, % of RAM, or 0 for defaults" +#~ msgstr "" +#~ " --memlimit-compress=LIMIGO\n" +#~ " --memlimit-decompress=LIMIGO\n" +#~ " --memlimit-mt-decompress=LIMIGO\n" +#~ " -M, --memlimit=LIMO\n" +#~ " agordi memoruzadon por kunpremo, malkunpremo,\n" +#~ " kunfadena kunpmero aÅ­ ĉiuj el tiuj; LIMIGO estas\n" +#~ " laÅ­ bajtoj, % da ĉefmemoro, aÅ­ 0 por aprioraĵoj" + +#~ msgid "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n" +#~ " --lzma2[=OPTS] more of the following options (valid values; default):\n" +#~ " preset=PRE reset options to a preset (0-9[e])\n" +#~ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM number of literal context bits (0-4; 3)\n" +#~ " lp=NUM number of literal position bits (0-4; 0)\n" +#~ " pb=NUM number of position bits (0-4; 2)\n" +#~ " mode=MODE compression mode (fast, normal; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM maximum search depth; 0=automatic (default)" +#~ msgstr "" +#~ "\n" +#~ " --lzma1[=ELEKTOJ] LZMA1 aÅ­ LZMA2; OPTS estas listo de nul aÅ­ pliaj\n" +#~ " --lzma2[=ELEKTOJ] de la jenaj elektoj (validaj valoroj; apriora),\n" +#~ " apartigataj de komoj:\n" +#~ " preset=ANT restarigi agordon al antaÅ­agordaĵon (0-9[e])\n" +#~ " dict=NOM vortara grando (4 kilobajtoj - 1536\n" +#~ " megabajtoj; 8 megabajtoj)\n" +#~ " lc=NOM nombro da laÅ­vortaj kuntekstaj bitoj\n" +#~ " (0-4; 3)\n" +#~ " lp=NOM nombro da laÅ­vortaj poziciaj bitoj (0-4; 0)\n" +#~ " pb=NOM nombro da poziciaj bitoj (0-4; 2)\n" +#~ " mode=REÄœI kunprema reÄimo (fast, normal; normal)\n" +#~ " nice=NOM bona longo de kongruaĵo (2-273; 64)\n" +#~ " mf=NOMO kongruaĵa trovilo (hc3, hc4, bt2, bt3, bt4;\n" +#~ " bt4)\n" +#~ " depth=NUM maksimuma profundo de serĉo; 0=aÅ­tomata\n" +#~ " (apriore)" + +#~ msgid "" +#~ "\n" +#~ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~ " --arm[=OPTS] ARM BCJ filter\n" +#~ " --armthumb[=OPTS] ARM-Thumb BCJ filter\n" +#~ " --arm64[=OPTS] ARM64 BCJ filter\n" +#~ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~ " --sparc[=OPTS] SPARC BCJ filter\n" +#~ " --riscv[=OPTS] RISC-V BCJ filter\n" +#~ " Valid OPTS for all BCJ filters:\n" +#~ " start=NUM start offset for conversions (default=0)" +#~ msgstr "" +#~ "\n" +#~ " --x86[=ELEKTOJ] x86-BCJ-filtrilo (32-bita kaj 64-bita)\n" +#~ " --arm[=ELEKTOJ] ARM-BCJ-filtrilo\n" +#~ " --armthumb[=ELEKTOJ]\n" +#~ " ARM-Thumb-BCJ-filtrilo\n" +#~ " --arm64[=OPTS] ARM64-BCJ-filtrilo\n" +#~ " --powerpc[=ELEKTOJ] PowerPC-BCJ-filtrilo (nur pezkomenca)\n" +#~ " --ia64[=ELEKTOJ] IA-64 (Itanium)-BCJ-filtrilo\n" +#~ " --sparc[=ELEKTOJ] SPARC-BCJ-filtrilo\n" +#~ " --riscv[=ELEKTOJ] RISC-V_BCJ-filtrilo\n" +#~ " Validaj ELEKTOJ por ĉiuj BCJ-filters:\n" +#~ " start=NOMBRO komenca deÅovo por konvertoj (apriore 0)" + +#~ msgid "" +#~ "\n" +#~ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" +#~ " dist=NUM distance between bytes being subtracted\n" +#~ " from each other (1-256; 1)" +#~ msgstr "" +#~ "\n" +#~ " --delta[=ELEKTOJ] Delta filtriloj; validaj valoroj:\n" +#~ " dist=NOMBRO distanco inter bajtoj subtrahataj de unu\n" +#~ " la alia (1-256; 1)" + +#~ msgid "" +#~ " -q, --quiet suppress warnings; specify twice to suppress errors too\n" +#~ " -v, --verbose be verbose; specify twice for even more verbose" +#~ msgstr "" +#~ " -q, --quiet silentigi avertojn; uzu dufoje por ankaÅ­ silentigi erarojn\n" +#~ " -v, --verbose eligi superfluajn informojn; uzu dufoje por pliigi la\n" +#~ " superfluecon" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help montri la mallongan helpon (listigas nur la bazajn\n" +#~ " elektojn)\n" +#~ " -H, --long-help montri la longan helpon kaj finiÄi" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help montri ĉi tiun mallongan helpon kaj finiÄi\n" +#~ " -H, --long-help montri la longan helpon (listigas ankaÅ­ la altnivelajn\n" +#~ " elektojn)" + +#~ msgid "Failed to enable the sandbox" +#~ msgstr "Malsukcesis aktivigi la sablujon" diff --git a/cpp/third_party/xz-5.8.3/po/es.gmo b/cpp/third_party/xz-5.8.3/po/es.gmo new file mode 100644 index 0000000000000000000000000000000000000000..abc29a1e5981a0eb6fb800342a0bfa8ad1dbfa84 GIT binary patch literal 29244 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, 2022, 2023, 2024, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.8.0-pre1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-05-14 14:23-0600\n" +"Last-Translator: Cristian Othón Martínez Vera \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Argumento inválido para --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Demasiados argumentos para --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "En --block-list, falta el tamaño de bloque después del número de cadena de filtros '%c:'" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 solo se puede usar como el último elemento en --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Tipo de formato de fichero desconocido" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: No se admite el tipo de verificación de integridad" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Solo se puede especificar un fichero con '--files' o '--files0'." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "La variable de ambiente %s contiene demasiados argumentos" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Se desactivó el soporte para compresión en el momento de compilación" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Se desactivó el soporte para descompresión en el momento de compilación" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "No se admite la compresión de ficheros lzip (.lz)" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list se descarta a menos que se comprima con el formato .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Con --format=raw, se requiere --suffix=.SUF a menos que se escriba a la salida estándar" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "El número máximo de filtros es cuatro" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Error en la opción --filters%s=FILTROS:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "El límite de uso de memoria es demasiado bajo para la configuración de filtros dada." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "la cadena de filtros %u es usada por --block-list pero no se especifica con --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "No se recomienda un modo predeterminado en modo crudo." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "El número exacto de las opciones predeterminadas puede variar entre versiones del software." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "El formato .lzma solamente admite el filtro LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "No se puede usar LZMA1 con el formato .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "La cadena de filtros %u es incompatible con --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Se cambia al modo de un solo hilo debido a --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Opciones sin soporte en la cadena de filtros %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Se usan hasta % hilos." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "No se admiten las opciones de cadena de filtros o de filtro" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "La descompresión necesitará %s MiB de memoria." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Se reduce el número de hilos de %s a %s para no exceder el límite de uso de memoria de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Se reduce el número de hilos de %s a uno. Aún se está excediendo el límite automático de uso de memoria de %s MiB. Se requieren %s MiB de memoria. Continúa de cualquier manera." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Se ajusta al modo de un solo hilo para no exceder el límite de uso de memoria de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Se ajusta el tamaño del diccionario LZMA%c de %s MiB a %s MiB para no exceder el límite de uso de memoria de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Se ajusta el tamaño del diccionario LZMA%c para --filters%u de %s MiB a %s MiB para no exceder el límite de uso de memoria de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Error al cambiar a la cadena de filtros %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Error al crear una tubería: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: falló poll(): %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Al parecer se movió el fichero, no se borra" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: No se puede borrar: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: No se puede establecer el propietario del fichero: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: No se puede establecer el grupo del fichero: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: No se pueden establecer los permisos del fichero: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Falló al sincronizar el fichero: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Falló al sincronizar el directorio del fichero: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Error al obtener la opciones de estado de fichero de la entrada estándar: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Es un enlace simbólico, se salta" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Es un directorio, se salta" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: No es un fichero regular, se salta" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: El fichero tiene el bit setuid o setgid activo, se salta" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: El fichero tiene el bit sticky activo, se salta" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: El fichero de entrada tiene más de un enlace duro, se salta" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Nombre de fichero vacío, se salta" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Error al restaurar las opciones de estado en la entrada estándar: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Error al obtener las opciones de estado de fichero de la entrada estándar: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Falló al abrir el directorio: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: El destino no es un fichero regular" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Error al restaurar la opción O_APPEND a la salida estándar: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Falló al cerrar el fichero: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Falló la búsqueda al tratar de crear un fichero disperso: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Error de lectura: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Error al buscar en el fichero: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Fin de fichero inesperado" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Error de escritura: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Desactivado" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Cantidad total de memoria física (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Número de hilos de procesador:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Compresión" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Descompresión:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Descompresión multihilos:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Por omisión para -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Información de hardware:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Límites de uso de memoria:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Flujos:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Bloques:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Tamaño comprimido:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Tamaño sin comprimir:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Tasa:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Verificación:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Relleno de flujo:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Memoria requerida:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Tamaños en cabeceras:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Número de ficheros:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Flujo" + +#: src/xz/list.c +msgid "Block" +msgstr "Bloque" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Bloques" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "DesplComp" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "DesplDescomp" + +#: src/xz/list.c +msgid "CompSize" +msgstr "TamComp" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "TamDescomp" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "TamTotal" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Tasa" + +#: src/xz/list.c +msgid "Check" +msgstr "Verif" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "ValVerif" + +#: src/xz/list.c +msgid "Padding" +msgstr "Relleno" + +#: src/xz/list.c +msgid "Header" +msgstr "Cabecera" + +#: src/xz/list.c +msgid "Flags" +msgstr "Opciones" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "UsoMem" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtros" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Ninguno" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Descon-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Descon-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Descon-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Descon-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Descon-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Descon-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Descon-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Descon-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Descon-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Descon-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Descon-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Descon-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: El fichero está vacío" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Demasiado pequeño para ser un fichero .xz válido" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Flujos Bloques Comprimido Sin-Comprimir Tasa Verif Nombre-Fichero" + +#: src/xz/list.c +msgid "Yes" +msgstr "Sí" + +#: src/xz/list.c +msgid "No" +msgstr "No" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Versión mínima de Herramientas XZ:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s fichero\n" +msgstr[1] "%s ficheros\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Totales:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list solo funciona con ficheros .xz (--format=xz o --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Pruebe 'lzmainfo' con ficheros .lzma." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list no admite leer de la entrada estándar" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Error al leer nombres de fichero: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Fin de entrada inesperada al leer nombres de fichero" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Se encontraron caracteres nulos al leer nombres de ficheros. ¿Tal vez quería usar '--files0' en lugar de '--files'?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Aún no se admite la compresión y descompresión con --robot." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "No se pueden leer datos de la entrada estándar cuando se leen nombres de fichero de la entrada estándar" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Error interno (bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "No se pueden establecer los manejadores de señales" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "No hay revisión de integridad; no se verifica la integridad del fichero" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "No se admite el tipo de revisión de integridad; no se verifica la integridad del fichero" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Se alcanzó el límite de uso de memoria" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "No se reconoce el formato del fichero" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Opciones sin soporte" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Los datos comprimidos están corruptos" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Fin de entrada inesperado" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "Se requieren %s MiB de memoria. Se desactiva el limitador." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "Se requieren %s MiB de memoria. El límite es %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Cadena de filtro: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Pruebe '%s --help' para obtener más información." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Error al mostrar el texto de ayuda (código de error %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Uso: %s [OPCIÓN]... [FICHERO]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Comprime o descomprime FICHEROs en el formato .xz." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Los argumentos obligatorios para las opciones largas también son obligatorios para las opciones cortas." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Modo de operación:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "fuerza la compresión" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "fuerza la descompresión" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "prueba la integridad del fichero comprimido" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "muestra la información acerca de los ficheros .xz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Modificadores de operación:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "conserva (no borra) los ficheros de entrada" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "fuerza la sobreescritura del fichero de salida y (des)comprime enlaces" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "escribe a la salida estándar y no borra los ficheros de entrada" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "no sincroniza el fichero de salida con el dispositivo de almacenamiento antes de borrar el fichero de entrada" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "solo descomprime el primer flujo, y descarta silenciosamente los posibles datos de entrada restantes" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "no crea archivos temporales al descomprimir" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "usa el sufijo '.SUF' para los ficheros comprimidos" + +#: src/xz/message.c +msgid "FILE" +msgstr "FICHERO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "lee los nombres de fichero a procesar del FICHERO; si se omite el FICHERO, los nombres de fichero se leen de la entrada estándar; los nombres de fichero deber de terminar con el carácter de línea nueva" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "como --files pero usa el carácter nulo como terminador" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Opciones básicas de compresión y formato de fichero:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMATO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "formato de fichero para codificar o decodificar; los valores posibles son 'auto' (por defecto), 'xz', 'lzma', 'lzip', y 'raw'" + +#: src/xz/message.c +msgid "NAME" +msgstr "NOMBRE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "tipo de verificación de integridad: 'none' (usar con cuidado), 'crc32', 'crc64' (por defecto), o 'sha256'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "no hace la verificación de integridad al descomprimir" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "valor predefinido de compresión; por defecto es 6. ¡Considere el compresor *y* el uso de memoria del compresor antes de usar 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "trata de mejorar la razón de compresión usando más tiempo de procesamiento; no afecta los requisitos de memoria del descompresor" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "NÚM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "usa como máximo NÚM hilos; por defecto es 0, el cual usa tantos hilos como hayan núcleos de procesador" + +#: src/xz/message.c +msgid "SIZE" +msgstr "TAMAÑO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "inicia un nuevo bloque .xz después de cada TAMAÑO bytes de entrada; use esta opción para establecer el tamaño de bloque para la compresión con hilos" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOQUES" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "inicia un nuevo bloque .xz después de cada intervalo dado, separado por comas, de datos sin comprimir; opcionalmente, especifica un número de cadena de filtros (0-9) a continuación de ':' antes del tamaño de los datos sin comprimir" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "al comprimir, si pasaron más de NÚM milisegundos desde el último descarte y la lectura de más entrada produciría un bloqueo, todos los datos pendientes son descartados" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "LÃMITE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "define el límite de uso de memoria para compresión, descompresión, descompresión con hilos, o todos los anteriores; el LÃMITE es en bytes, % de RAM, o 0 para valores por defecto" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "si la configuración de compresión excede el límite de uso de memoria, muestra un error en lugar de ajustar los valores hacia abajo" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Cadena de filtros personal para compresión (alternativa a usar valores predefinidos):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTROS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "define la cadena de filtros usando la sintaxis de la cadena de filtros liblzma; use --filters-help para obtener más información" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "define cadenas de filtros adicionales usando la sintaxis de cadena de filtros liblzma para usar con --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "muestra más información acerca de la sintaxis de cadenas de filtros liblzma y termina" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "OPCS" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 o LZMA2: OPCS es una lista separada por comas de cero o más de las siguientes opciones (valores válidos; por defecto):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "PRE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "cambia las opciones al valor predefinido" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "tamaño de diccionario" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "número de bits de contexto literal" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "número de bits de posición literal" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "número de bits de posición" + +#: src/xz/message.c +msgid "MODE" +msgstr "MODO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "modo de descompresión" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "longitud aceptada de una coincidencia" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "buscador de coincidencias" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "profundidad máxima de búsqueda; 0=automática (por defecto)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "filtro BCJ de x86 (32-bit y 64-bit)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "filtro BCJ de ARM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "filtro BCJ de ARM-Thumb" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "filtro BCJ de ARM64" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "filtro BCJ de PowerPC (sólo big endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "filtro BCJ de IA-64 (Itanium)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "filtro BCJ de Sparc" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "filtro BCJ de RISC-V" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "OPCS válidas para todos los filtros BCJ:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "desplazamiento de inicio para las conversiones (por defecto=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Delta de filtro; OPCS válidas (valores válidos; por defecto):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "distancia entre bytes que se restan unos de otros" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Otras opciones:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "suprime los avisos; especificar dos veces para suprimir también los errores" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "descriptivo; especificar dos veces para ser aún más descriptivo" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "los avisos no afectan el estado de la salida" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "usa mensajes analizables por máquina (útil para scripts)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "muestra la cantidad total de RAM y los límites de uso de memoria activos, y termina" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "muestra la ayuda corta (sólo muestra las opciones básicas)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "muestra esta ayuda larga y termina" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "muestra esta ayuda corta y termina" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "muestra la ayuda larga (también muestra las opciones avanzadas)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "muestra el número de versión y termina" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Sin FICHEROs, o cuando el FICHERO es -, lee la entrada estándar." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"Reporte errores a <%s> (en inglés o finlandés).\n" +"Reporte errores de traducción al español a ." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "Sitio web de %s: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ESTA ES UNA VERSIÓN EN DESARROLLO Y NO ESTà LISTA PARA USO EN PRODUCCIÓN." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Las cadenas de filtros se definen usando las opciones --filters=FILTROS o --filters1=FILTROS ... --filters9=FILTROS. Cada filtro en la cadena se puede separar con espacios o '--'. Alternativamente, se puede especificar un valor predeterminado %s en lugar de una cadena de filtro." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Los filtros admitidos y sus opciones son:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Las opciones deben ser pares 'nombre=valor' separadas por comas" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Nombre de opción inválido" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Valor de opción inválido" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "No se admite el valor predefinido LZMA1/LZMA2: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "La suma de lc y lp no debe exceder 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: El nombre de fichero tiene un sufijo desconocido, se salta" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: El fichero ya tiene un sufijo '%s', se salta" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Sufijo de nombre de fichero inválido" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "El valor no es un entero decimal no-negativo" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Sufijo multiplicador inválido" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Los sufijos válidos son 'KiB' (2^10), 'MiB' (2^20), y 'GiB' (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "El valor de la opción '%s' debe estar en el intervalo [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "No se pueden leer datos comprimidos de una terminal" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "No se pueden escribir datos comprimidos a una terminal" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Uso: %s [--help] [--version] [FICHERO]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Muestra información almacenada en la cabecera del fichero .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "El fichero es demasiado pequeño para ser un fichero .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "No es un fichero .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Falló la escritura a la salida estándar" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Error desconocido" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Opción sin soporte" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Opción sin soporte en el valor predefinido" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Nombre de opción inválido" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "El valor de la opción no puede estar vacío" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Valor fuera de intervalo" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Esta opción no admite ningún sufijo multiplicador" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Sufijo multiplicador inválido (KiB, MiB, o GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Nombre de filtro desconocido" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Este filtro no se puede usar en el formato .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Falló el alojamiento de memoria" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "No se permite una cadena vacía, pruebe con '6' si se requiere un valor por defecto" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "El número máximo de filtros es cuatro" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Falta el nombre del filtro" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Cadena de filtro inválida (¿falta 'lzma2' al final?)" diff --git a/cpp/third_party/xz-5.8.3/po/fi.gmo b/cpp/third_party/xz-5.8.3/po/fi.gmo new file mode 100644 index 0000000000000000000000000000000000000000..a85048858951e44183a4dee5428cb335f7406742 GIT binary patch literal 28225 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 F{{x3j6, 2019, 2020, 2022, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-01-29 21:57+0200\n" +"Last-Translator: Lauri Nurmi \n" +"Language-Team: Finnish \n" +"Language: fi\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" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.5\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Virheellinen argumentti valitsimelle --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Liian monta argumenttia valitsimelle --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "Valitsimen --block-list yhteydessä lohkon koko puuttuu suodinketjun numeron '%c:' jälkeen" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 kelpaa vain viimeiseksi alkioksi valitsimen --block-list kanssa" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Tuntematon tiedostomuototyyppi" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Eheystarkistuksen tyyppiä ei tueta" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Vain yksi tiedosto voidaan antaa valitsimille â€--files†ja â€--files0â€." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Ympäristömuuttuja %s sisältää liian monta argumenttia" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Tiivistämistuki on poistettu käytöstä käännösaikana" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Purkutuki on poistettu käytöstä käännösaikana" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Lzip-tiedostojen (.lz) tiivistämistä ei tueta" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list jätetään huomiotta, ellei olla tiivistämässä .xz-muotoon" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "--format=raw vaatii, että --suffix=.PÄÄTE on annettu, ellei kirjoiteta vakiotulosteeseen" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Suodattimien enimmäismäärä on neljä" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Virhe --filters%s=SUOTIMET-asetuksessa:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Muistinkäytön raja on liian matala valituille suotimille." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "--block-list käyttää suodinketjua %u, jota ei ole määritelty --filters%u=:lla" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Esiasetusten käyttö raw-tilassa ei ole suositeltavaa." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Esiasetusten tarkat asetukset saattavat vaihdella ohjelmistoversioiden välillä." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr ".lzma-muoto tukee vain LZMA1-suodinta" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1:tä ei voi käyttää .xz-muodon kanssa" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Suodinketju %u on yhteensopimaton valitsimen --flush-timeout kanssa" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Vaihdetaan yksisäikeiseen tilaan valitsimen --flush-timeout vuoksi" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Ei-tuettuja asetuksia suodinketjussa %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Käytetään enintään % säiettä." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Ei-tuetut suodinketjun tai suotimen asetukset" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Purkaminen vaatii %s MiB muistia." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Pudotettiin säikeiden määrä %s säikeestä %s:een, jottei ylitettäisi %s MiB:n rajaa muistinkäytölle" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Pudotettiin säikeiden määrä %s säikeestä yhteen. Automaattinen %s MiB:n raja muistinkäytölle ylittyy silti. Vaaditaan %s MiB muistia. Jatketaan kaikesta huolimatta." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Siirrytään yhden säikeen tilaan, jottei ylitettäisi %s MiB:n rajaa muistinkäytölle" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Pudotettiin LZMA%c-sanaston koko %s MiB:stä %s MiB:hen, jottei ylitettäisi %s MiB:n rajaa muistinkäytölle" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Pudotettiin LZMA%c-sanaston koko --filter%u:lle %s MiB:stä %s MiB:hen, jottei ylitettäisi %s MiB:n rajaa muistinkäytölle" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Virhe vaihdettaessa suodinketjuun %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Virhe putkea luodessa: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll()-kutsu epäonnistui: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Tiedosto on nähtävästi siirretty, ei poisteta" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Ei voi poistaa: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Tiedoston omistajaa ei voi asettaa: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Tiedoston ryhmää ei voi asettaa: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Tiedoston oikeuksia ei voi asettaa: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Tiedoston synkronointi epäonnistui: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Tiedoston hakemiston synkronointi epäonnistui: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Virhe tiedoston tilalippujen noutamisessa vakiosyötteelle: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: On symbolinen linkki, ohitetaan" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: On hakemisto, ohitetaan" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Ei ole tavallinen tiedosto, ohitetaan" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Tiedostolla on setuid- tai setgid-bitti, ohitetaan" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Tiedostolla on sticky-bitti, ohitetaan" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Syötetiedostoon on yli yksi kova linkki, ohitetaan" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Tyhjä tiedostonimi, ohitetaan" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Virhe tilalippujen palauttamisessa vakiosyötteelle: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Virhe tiedoston tilalippujen noutamisessa vakiotulosteelle: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Hakemiston avaaminen epäonnistui: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: Kohde ei ole tavallinen tiedosto" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Virhe O_APPEND-lipun palauttamisessa vakiosyötteelle: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Tiedoston sulkeminen epäonnistui: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Siirtyminen epäonnistui yritettäessä luoda hajanaista tiedostoa: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Lukuvirhe: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Virhe tiedostossa siirtymisessä: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Odottamaton tiedoston loppu" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Kirjoitusvirhe: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Pois käytöstä" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Fyysisen muistin kokonaismäärä (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Suoritinsäikeiden määrä:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Tiivistys:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Purku:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Monisäikeinen purku:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "-T0:n oletusarvo:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Laitteiston tiedot:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Muistinkäytön rajat:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Virrat:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Lohkot:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Tiivistetty koko:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Tiivistämätön koko:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Suhde:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Tarkistus:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Virran tasaus:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Tarvittava muisti:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Koot otsakkeissa:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Tiedostojen määrä:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Virta" + +#: src/xz/list.c +msgid "Block" +msgstr "Lohko" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Lohkot" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "TiivSiirr." + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "Tv:tönSiirr." + +#: src/xz/list.c +msgid "CompSize" +msgstr "TiivKoko" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "Tv:tönKoko" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "Yht.Koko" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Suhde" + +#: src/xz/list.c +msgid "Check" +msgstr "Tark." + +#: src/xz/list.c +msgid "CheckVal" +msgstr "Tark.arvo" + +#: src/xz/list.c +msgid "Padding" +msgstr "Tasaus" + +#: src/xz/list.c +msgid "Header" +msgstr "Otsake" + +#: src/xz/list.c +msgid "Flags" +msgstr "Liput" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "Muist.käyt." + +#: src/xz/list.c +msgid "Filters" +msgstr "Suodattimet" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Ei mitään" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Tuntematon-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Tuntematon-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Tuntematon-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Tuntematon-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Tuntematon-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Tuntematon-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Tuntematon-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Tuntematon-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Tuntematon-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Tuntematon-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Tuntematon-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Tuntematon-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Tiedosto on tyhjä" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Liian pieni kelvolliseksi .xz-tiedostoksi" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Virrat Lohkot Tiivist. Tiivistämätön Suhde Tark. Tiedostonimi" + +#: src/xz/list.c +msgid "Yes" +msgstr "Kyllä" + +#: src/xz/list.c +msgid "No" +msgstr "Ei" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "XZ Utilsin vähimmäisversio:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s tiedosto\n" +msgstr[1] "%s tiedostoa\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Yhteensä:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list toimii vain .xz-tiedostoille (--format=xz tai --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Kokeile â€lzmainfoâ€-komento .lzma-tiedostoille." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list ei tue lukemista vakiosyötteestä" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Virhe luettaessa tiedostonimiä: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Odottamaton syötteen loppu tiedostonimiä luettaessa" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Nul-merkki kohdattiin tiedostonimiä lukiessa; oliko tarkoitus antaa valitsin â€--files0†eikä â€--filesâ€?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Tiivistys ja purku --robot -valitsimen kanssa eivät ole vielä tuettuja." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Dataa ei voi lukea vakiosyötteestä kun tiedostonimiä luetaan vakiosyötteestä" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Sisäinen virhe (ohjelmistovika)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Signaalinkäsittelimiä ei voi muodostaa" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Ei eheystarkastusta; ei varmenneta tiedoston eheyttä" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Ei-tuettu eheystarkastuksen tyyppi; ei varmenneta tiedoston eheyttä" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Muistinkäytön raja saavutettu" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Tiedostomuotoa ei tunnistettu" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Ei-tuetut asetukset" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Tiivistetty data on turmeltunut" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Odottamaton syötteen loppu" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB muistia vaaditaan. Rajoitin on poistettu käytöstä." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB muistia vaaditaan. Raja on %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Suodinketju: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Komento â€%s --help†antaa lisää tietoa." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Virhe tulostettaessa ohjetekstiä (virhekoodi %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Käyttö: %s [VALITSIN]... [TIEDOSTO]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Tiivistä tai pura .xz-muotoisia TIEDOSTOja." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Pitkien valitsinten pakolliset argumentit ovat pakollisia myös lyhyille." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr " Toimintatila:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "pakota tiivistys" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "pakota purku" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "testaa tiivistetyn tiedoston eheys" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "näytä tietoa .xz-tiedostoista" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Toimintomääreet:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "säilytä syötetiedostot (älä poista)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "pakota tulostiedostojen ylikirjoitus ja pura/tiivistä linkit" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "kirjoita vakiotulosteeseen äläkä poista syötetiedostoja" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "älä synkronoi tulostiedostoa tallennuslaitteelle ennen syötetiedoston poistamista" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "pura vain ensimmäinen virta, ja ohita hiljaisesti mahdollinen jäljellä oleva syötedata" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "älä luo hajanaisia tiedostoja purettaessa" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".PÄÄTE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "käytä â€.PÄÄTEâ€-päätettä tiivistetyille tiedostoille" + +#: src/xz/message.c +msgid "FILE" +msgstr "TIED" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "lue käsiteltävät tiedostonimet TIEDostosta; jos TIED jätetään antamatta, tiedostonimet luetaan vakiosyötteestä; tiedostonimet on päätettävä rivinvaihtomerkillä" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "kuten --files mutta käytä päättämiseen nul-merkkiä" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Tiedostomuodon ja tiivistyksen perusasetukset:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "MUOTO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "tuotettava tai luettava tiedostomuoto; vaihtoehdot ovat â€auto†(oletus), â€xzâ€, â€lzmaâ€, â€lzip†ja â€rawâ€" + +#: src/xz/message.c +msgid "NAME" +msgstr "NIMI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "eheystarkastuksen tyyppi: â€none†(käytä varoen), â€crc32â€, â€crc64†(oletus) tai â€sha256â€" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "älä suorita eheystarkastusta purettaessa" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "tiivistyksen esiasetus; oletus on 6; ota tiivistyksen *ja* purun muistinkäyttö huomioon ennen arvojen 7–9 käyttämistä!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "yritä parantaa tiivistyssuhdetta käyttämällä enemmän suoritinaikaa; ei vaikuta purkimen muistivaatimuksiin" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "MÄÄRÄ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "käytä enintään MÄÄRÄä säiettä; oletus on 0, jolloin käytetään suoritinytimien määrän verran säikeitä" + +#: src/xz/message.c +msgid "SIZE" +msgstr "KOKO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "aloita uusi .xz-lohko aina KOKO syötetavun jälkeen; käytä tätä säikeistetyn tiivistyksen lohkokoon asettamiseen" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "LOHKOT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "aloita uusi .xz-lohko pilkuin erotettujen tiivistämättömän datan välien jälkeen; vaihtoehtoisesti anna suodatinketjun numeron (0–9) ja sen jälkeen â€:†ennen tiivistämättömän datan kokoa" + +# to block: salpautua? kuulostaako hyvältä? +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "jos tiivistettäessä on kulunut yli MÄÄRÄ ms edellisestä huuhtomisesta ja syötteen lukemisen jatkaminen salpautuisi, kaikki odottava data huuhdellaan" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "RAJA" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "aseta muistinkäytön raja tiivistykselle, purkamiselle, säikeistetylle purkamisella tai näille kaikille; RAJA on tavuja, %-osuus RAM-muistista tai 0 oletusarvoille" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "jos tiivistysasetukset ylittävät muistinkäytön rajan, anna virhe äläkä pudota asetuksia alaspäin" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Mukautettu suodinketju tiivistykselle (vaihtoehto esiasetuksille):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "SUOTIMET" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "aseta suodinketju käyttäen libzma:n suodinsyntaksia; lisätietoja valitsimella --filters-help" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "aseta lisäsuodinketjuja käyttäen libzma:n suodinsyntaksia --block-list:in kanssa käytettäväksi" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "näytä lisätietoa liblzma:n suodinsyntaksista ja poistu" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "ASET" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 tai LZMA2; ASET on pilkuilla erotettu lista nollasta tai useammasta seuraavasta asetuksesta (kelvolliset arvot; oletus):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "ESI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "palauta asetukset esiasetukseen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "sanaston koko" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "literaalien kontekstibittien määrä" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "literaalien sijaintibittien määrä" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "sijaintibittien määrä" + +#: src/xz/message.c +msgid "MODE" +msgstr "TILA" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "tiivistystila" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "täsmäävyyden kiva pituus" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "täsmäävyydenetsin" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "enimmäishakusyvyys; 0=automaattinen (oletus)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ -suodin (32- ja 64-bittinen)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ -suodin" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BJC -suodin" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ -suodin" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ -suodin (vain big endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (Itanium) BCJ -suodin" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ -suodin" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ -suodin" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "Kelvolliset ASETukset kaikille BJC-suotimille:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "muunnosten aloitussiirtymä (oletus=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Delta-suodin; kelvolliset ASETukset (kelvolliset arvot; oletus):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "toisistaan vähennettävien tavujen välinen etäisyys" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Muut asetukset:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "vaienna varoitukset; kahdesti antamalla myös virheet" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "ole lavea; kahdesti antamalla vieläkin laveampi" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "älkööt varoitukset vaikuttako paluuarvoon" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "käytä koneluettavia viestejä (sopii skripteihin)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "näytä RAM-muistin kokonaismäärä sekä parhaillaan vallitsevat muistinkäytön rajat, ja poistu" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "näytä lyhyt ohje (kertoo vain perusasetukset)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "näytä tämä pitkä ohje ja poistu" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "näytä tämä lyhyt ohje ja poistu" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "näytä pitkä ohje (kertoo myös lisäasetukset)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "näytä versionumero ja poistu" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Jos TIEDOSTOa ei ole annettu, tai se on -, luetaan vakiosyötettä." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Ilmoita ohjelmistovioista (suomeksi) osoitteeseen <%s>." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "%s -kotisivu: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "TÄMÄ ON KEHITYSVERSIO, JOTA EI OLE TARKOITETTU TUOTANTOKÄYTTÖÖN." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Suodinketjut asetetaan käyttämällä valitsinta --filters=SUOTIMET tai --filters1=SUOTIMET ... --filters9=SUOTIMET. Kukin ketjun suodin voidaan erottaa välilyönneillä tai â€--â€:lla. Vaihtoehtoisesti suodinketjun sijaan voidaan antaa esiasetus %s." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Tuetut suotimet ja niiden asetukset ovat:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Valitsinten on oltava pilkuilla eroteltuja â€nimi=arvoâ€-pareja" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Virheellinen asetuksen nimi" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Virheellinen asetuksen arvo" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Ei-tuettu LZMA1/LZMA2-esiasetus: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "lc:n ja lp:n summa ei saa olla yli 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Tiedostonimen pääte on tuntematon, ohitetaan" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Tiedostolla on jo â€%sâ€-pääte, ohitetaan" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Virheellinen tiedostonimen pääte" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Arvo ei ole ei ole epänegatiivinen kymmenkantainen kokonaisluku" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Tuntematon kerroin" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Kelvolliset kertoimet ovat â€KiB†(2¹â°), â€MiB†(2²â°) ja â€GiB†(2³â°)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Valitsimen â€%s†arvon on oltava välillä [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Tiivistettyä dataa ei voi lukea päätteestä" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Tiivistettyä dataa ei voi kirjoittaa päätteeseen" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Käyttö: %s [--help] [--version] [TIEDOSTO]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Näytä .lzma-tiedosto-otsakkeeseen tallennettu tieto." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Liian pieni kelvolliseksi .xz-tiedostoksi" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Ei .lzma-tiedosto" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Vakiotulosteeseen kirjoitus epäonnistui" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Tuntematon virhe" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Ei-tuettu esiasetus" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Ei-tuettu lippu esiasetuksessa" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Tuntematon asetuksen nimi" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Valitsimen arvo ei voi olla tyhjä" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Arvo sallitun välin ulkopuolella" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Tämä asetus ei tue kertoimia" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Virheellinen kerroin (KiB, MiB tai GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Tuntematon suotimen nimi" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Tätä suodinta ei voi käyttää .xz-muodon kanssa" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Muistinvaraus epäonnistui" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Tyhjä merkkijono ei ole sallittu, kokeile arvoa â€6â€, jos oletusarvoa tarvitaan" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Suodattimien enimmäismäärä on neljä" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Suotimen nimi puuttuu" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Virheellinen suodinketju (puuttuuko â€lzma2†lopusta?)" diff --git a/cpp/third_party/xz-5.8.3/po/fr.gmo b/cpp/third_party/xz-5.8.3/po/fr.gmo new file mode 100644 index 0000000000000000000000000000000000000000..6b7b53ba2690a5f140cc4cb05be88841004f103f GIT binary patch literal 10232 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, 2011-2014. +# Stéphane Aulery , 2019-2023. +# +msgid "" +msgstr "" +"Project-Id-Version: xz-5.4.4-pre1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2023-12-19 04:12+0100\n" +"Last-Translator: Stéphane Aulery \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s : argument de l'option --block-list invalide" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s : trop d'arguments pour l'option --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 peut seulement être utilisé en dernier élément de --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s : Format de fichier inconnu" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s : Type de vérification d'intégrité inconnu" + +#: src/xz/args.c +#, fuzzy +#| msgid "Only one file can be specified with `--files' or `--files0'." +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Un seul fichier peut être spécifié avec `--files' ou `--files0'." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, fuzzy, c-format +#| msgid "%s: " +msgid "%s: %s" +msgstr "%s : " + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "La variable d'environnement %s contient trop d'arguments" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Le support de la compression à était désactivé lors de la compilaton" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Le support de la décompression a été désactivé lors de la compilation" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "" + +#: src/xz/args.c +#, fuzzy +#| msgid "%s: With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "%s : Avec --format=raw, --suffix=.SUF est nécessaire sauf lors de l'écriture vers stdout" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Le nombre maximal de filtres est quatre" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "La limite d'utilisation mémoire est trop basse pour la configuration de filtres donnée." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Utiliser un préréglage en mode `raw' est déconseillé." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Le détail des préréglages peut varier entre différentes versions du logiciel." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Le format .lzma ne prend en charge que le filtre LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "Le filtre LZMA1 ne peut être utilisé avec le format .xz" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "The filter chain is incompatible with --flush-timeout" +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "La Chaine de filtre est incompatible avec --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Bascule en mode mono-processus à cause de --flush-timeout" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Unsupported options" +msgid "Unsupported options in filter chain %u" +msgstr "Options non prises en charge" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Jusqu'à % threads seront utilisés." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Enchaînement ou options de filtres non pris en charge" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "La décompression nécessitera %s MiB de mémoire." + +#: src/xz/coder.c +#, fuzzy, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Nombre de threads réduit de %s à %s pour ne pas dépasser la limite d'utilisation mémoire de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "" + +#: src/xz/coder.c +#, fuzzy, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Nombre de threads réduit de %s à %s pour ne pas dépasser la limite d'utilisation mémoire de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Taille du dictionnaire LZMA%c réduite de %s MiB à %s MiB pour ne pas dépasser la limite d'utilisation mémoire de %s MiB" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Taille du dictionnaire LZMA%c réduite de %s MiB à %s MiB pour ne pas dépasser la limite d'utilisation mémoire de %s MiB" + +#: src/xz/coder.c +#, fuzzy, c-format +#| msgid "Error creating a pipe: %s" +msgid "Error changing to filter chain %u: %s" +msgstr "Impossible de créer un tube anonyme (pipe) : %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Impossible de créer un tube anonyme (pipe) : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s : L'appel à la fonction poll() a échoué : %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s : Le fichier a apparemment été déplacé, suppression annulée" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s : Impossible de supprimer : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s : Impossible de modifier le propriétaire du fichier : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s : Impossible de modifier le groupe propriétaire du fichier : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s : Impossible de modifier les permissions du fichier : %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s : Impossible de fermer le fichier : %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s : Impossible de fermer le fichier : %s" + +# Note from translator on "file status flags". +# The following entry is kept un-translated on purpose. It is difficult to +# translate and should only happen in exceptional circumstances which means +# that translating would: +# - lose some of the meaning +# - make it more difficult to look up in search engines; it might happen one in +# a million times, if we dilute the error message in 20 languages, it will be +# almost impossible to find an explanation and support for the error. +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Echec de la lecture du drapeau d'état du fichier depuis la sortie standard : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s est un lien symbolique : ignoré" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s est un répertoire : ignoré" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s n'est pas un fichier régulier : ignoré" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s : Le fichier possède les bits `setuid' ou `setgid' : ignoré" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s : Le fichier possède le bit `sticky' : ignoré" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s : Le fichier d'entrée a plus d'un lien matériel : ignoré" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Nom de fichier vide, ignoré" + +# See note from translator above titled "file status flags". +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Erreur de restauration du drapeau d'état de l'entrée standard : %s" + +# See note from translator above titled "file status flags". +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Erreur de lecture du drapeau d'état du fichier depuis la sortie standard : %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s : Impossible de fermer le fichier : %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%s n'est pas un fichier régulier : ignoré" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Impossible de rétablir le drapeau O_APPEND sur la sortie standard : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s : Impossible de fermer le fichier : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s : Impossible de se déplacer dans le fichier pour créer un 'sparse file' : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s : Erreur d'écriture : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s : Impossible de se déplacer dans le fichier : %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s : Fin de fichier inattendue" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s : Erreur d'écriture : %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Désactivé" + +#: src/xz/hardware.c +#, fuzzy +msgid "Amount of physical memory (RAM):" +msgstr "Quantité totale de mémoire physique (RAM) : " + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "" + +#: src/xz/hardware.c +#, fuzzy +msgid "Multi-threaded decompression:" +msgstr "Limite d'utilisation pour la décompression : " + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "" + +#: src/xz/hardware.c +#, fuzzy +msgid "Memory usage limits:" +msgstr "Limite d'utilisation mémoire atteinte" + +#: src/xz/list.c +msgid "Streams:" +msgstr "" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "" + +#: src/xz/list.c +#, fuzzy +msgid "Compressed size:" +msgstr " Taille données avec compression : %s\n" + +#: src/xz/list.c +#, fuzzy +msgid "Uncompressed size:" +msgstr " Taille données sans compression : %s\n" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "" + +#: src/xz/list.c +msgid "Check:" +msgstr "" + +#: src/xz/list.c +#, fuzzy +msgid "Stream Padding:" +msgstr " Octets de rembourrage du flux : %s\n" + +#: src/xz/list.c +#, fuzzy +msgid "Memory needed:" +msgstr " Mémoire nécessaire : %s MiB\n" + +#: src/xz/list.c +#, fuzzy +msgid "Sizes in headers:" +msgstr " Tailles stockées dans l'en-tête : %s\n" + +#: src/xz/list.c +#, fuzzy +msgid "Number of files:" +msgstr " Nombre de fichiers : %s\n" + +#: src/xz/list.c +msgid "Stream" +msgstr "" + +#: src/xz/list.c +msgid "Block" +msgstr "" + +#: src/xz/list.c +msgid "Blocks" +msgstr "" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "" + +#: src/xz/list.c +msgid "CompSize" +msgstr "" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "" + +#: src/xz/list.c +#, fuzzy +msgid "TotalSize" +msgstr "Totaux :" + +#: src/xz/list.c +msgid "Ratio" +msgstr "" + +#: src/xz/list.c +msgid "Check" +msgstr "" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "" + +#: src/xz/list.c +msgid "Padding" +msgstr "" + +#: src/xz/list.c +msgid "Header" +msgstr "" + +#: src/xz/list.c +msgid "Flags" +msgstr "" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "" + +#: src/xz/list.c +msgid "Filters" +msgstr "" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Aucune" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Inconnue-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Inconnue-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Inconnue-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Inconnue-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Inconnue-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Inconnue-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Inconnue-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Inconnue-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Inconnue-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Inconnue-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Inconnue-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Inconnue-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s : Le fichier est vide" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s : Trop petit pour être un fichier xz valide." + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Flux Blocs Compressé Décompressé Ratio Vérif. Nom de fichier" + +#: src/xz/list.c +msgid "Yes" +msgstr "Oui" + +#: src/xz/list.c +msgid "No" +msgstr "Non" + +#: src/xz/list.c +#, fuzzy +#| msgid " Minimum XZ Utils version: %s\n" +msgid "Minimum XZ Utils version:" +msgstr " Version minimale de XZ Utils : %s\n" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s fichier\n" +msgstr[1] "%s fichiers\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Totaux :" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list ne marche que sur les fichiers .xz (--format=xz ou --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "" + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list est incompatible avec la lecture sur l'entrée standard" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s : Erreur lors de la lecture des noms de fichiers : %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s : Fin des données inattendue lors de la lecture des noms de fichiers" + +#: src/xz/main.c +#, fuzzy, c-format +#| msgid "%s: Null character found when reading filenames; maybe you meant to use `--files0' instead of `--files'?" +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s : Caractère NULL détecté lors de la lecture des noms de fichiers ; peut-être pensiez-vous à `--files0' plutot qu'a `--files' ?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "La compression et la décompression ne marchent pas encore avec --robot." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Impossible de lire à la fois les données et les noms de fichiers depuis l'entrée standard" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s : " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Erreur interne (bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Impossible d'installer le gestionnaire de signaux" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Pas de données de vérification d'intégrité ; vérification non effectuée" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Méthode de vérification d'intégrité non prise en charge ; vérification non effectuée" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Limite d'utilisation mémoire atteinte" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Format de fichier inconnu" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Options non prises en charge" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Les données compressées sont corrompues" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Fin des données inattendue " + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB de mémoire sont nécessaires. La limite est désactivée." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB de mémoire sont nécessaires, la limite étant %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s : Enchaînement de filtres : %s\n" + +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "Try `%s --help' for more information." +msgid "Try '%s --help' for more information." +msgstr "Éxécutez `%s --help' pour obtenir davantage d'informations." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "Usage: %s [OPTION]... [FILE]...\n" +#| "Compress or decompress FILEs in the .xz format.\n" +#| "\n" +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" +"Utilisation : %s [OPTION]... [FICHIER]...\n" +"Compresse ou decompresse FICHIER(s) au format .xz.\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "" +"Les arguments obligatoires pour les options longues le sont aussi pour les\n" +"options courtes.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr " Mode d'opération :\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +msgid "force compression" +msgstr "Limite d'utilisation pour la décompression : " + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +msgid "force decompression" +msgstr "Limite d'utilisation pour la décompression : " + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +" Modificateurs :\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "Impossible d'écrire vers la sortie standard" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --single-stream decompress only the first stream, and silently\n" +#| " ignore possible remaining input data" +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" +" --single-stream décompresser uniquement le premier flux et ignorer\n" +" silencieusement les données éventuellement restantes" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Basic file format and compression options:\n" +msgid "Basic file format and compression options:" +msgstr "" +"\n" +" Options basiques de format de fichier et de compression :\n" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --ignore-check don't verify the integrity check when decompressing" +msgid "don't verify the integrity check when decompressing" +msgstr "" +" --ignore-check ne pas vérifier l'intégrité des données lors de\n" +" la décompression" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -0 ... -9 compression preset; default is 6; take compressor *and*\n" +#| " decompressor memory usage into account before using 7-9!" +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" +" -0 ... -9 préréglage de compression : 6 par défaut ; pensez à\n" +" l'utilisation mémoire du compresseur *et* du décompresseur\n" +" avant d'utiliser 7, 8 ou 9 !" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -e, --extreme try to improve compression ratio by using more CPU time;\n" +#| " does not affect decompressor memory requirements" +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" +" -e, --extreme essayer d'améliorer la compression en utilisant davantage\n" +" de temps processeur ;\n" +" n'affecte pas les besoins mémoire du décompresseur" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -T, --threads=NUM use at most NUM threads; the default is 1; set to 0\n" +#| " to use as many threads as there are processor cores" +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" +" -T, --threads=NB créer au plus NB fils de compression (1 par défault) ; la\n" +" valeur 0 est spéciale et équivaut au nombre de processeurs\n" +" de la machine" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-size=SIZE\n" +#| " start a new .xz block after every SIZE bytes of input;\n" +#| " use this to set the block size for threaded compression" +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" +" --block-size=TAILLE\n" +" débuter un bloc XZ après chaque TAILLE octets de données\n" +" d'entrée ; ce réglage sert pour la compression paralléle" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-list=SIZES\n" +#| " start a new .xz block after the given comma-separated\n" +#| " intervals of uncompressed data" +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" +" --block-list=TAILLES\n" +" débuter des blocs XZ après les TAILLES octets de données\n" +" spécifiées avec des virgules pour séparateur" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --flush-timeout=TIMEOUT\n" +#| " when compressing, if more than TIMEOUT milliseconds has\n" +#| " passed since the previous flush and reading more input\n" +#| " would block, all pending data is flushed out" +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" +" --flush-timeout=TIMEOUT\n" +" pendant la compression, si plus de TIMEOUT ms ont passées\n" +" depuis le dernier flush et que la lecture est bloquée,\n" +" toutes les données en attente sont écrites" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --no-adjust if compression settings exceed the memory usage limit,\n" +#| " give an error instead of adjusting the settings downwards" +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" +" --no-adjust si les réglages de compression dépassent la limite\n" +" d'utilisation mémoire, renvoyer une erreur plutôt que de\n" +" diminuer les réglages" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Custom filter chain for compression (alternative for using presets):" +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" +"\n" +" Chaîne de filtres de compression personnalisée (en lieu des préréglages) :" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "compression mode" +msgstr " Mode d'opération :\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +" Autres options :\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -Q, --no-warn make warnings not affect the exit status" +msgid "make warnings not affect the exit status" +msgstr " -Q, --no-warn les avertissements ne modifient pas le code de sortie" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr "" +" --robot utiliser des messages lisibles par un programme\n" +" (utile pour les scripts)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --info-memory display the total amount of RAM and the currently active\n" +#| " memory usage limits, and exit" +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" +" --info-memory afficher la quantité totale de RAM ainsi que la limite\n" +" actuelle d'utilisation mémoire puis quitter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version afficher le numéro de version puis quitter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"Sans FILE ou quand FILE est -, lire l'entrée standard.\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"Signaler les bogues à <%s> (en anglais ou en finnois).\n" +"Signaler les bogues de traduction à .\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "Page du projet %s : <%s>\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "CECI EST UNE VERSION DE DEVELOPPEMENT QUI NE DOIT PAS ÊTRE UTILISEE EN PRODUCTION." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "The supported filters and their options are:" +msgstr "Enchaînement ou options de filtres non pris en charge" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be `name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s: Les options doivent être des paires `nom=valeur' séparées par des virgules" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s : Nom d'option invalide" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s : Valeur d'option invalide" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Préréglage LZMA1/LZMA2 non reconnu : %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "La somme de lc et lp ne doit pas dépasser 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s : Le fichier a un suffixe inconnu, ignoré" + +#: src/xz/suffix.c +#, fuzzy, c-format +#| msgid "%s: File already has `%s' suffix, skipping" +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s : Le fichier a déjà le suffixe '%s', ignoré" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Suffixe de nom de fichier invalide" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%s : La valeur n'est pas un entier décimal non négatif" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s : Suffixe multiplicateur invalide" + +#: src/xz/util.c +#, fuzzy +#| msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)." +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Les suffixes valides sont 'KiB' (2^10), 'MiB' (2^20) et 'GiB' (2^30)." + +#: src/xz/util.c +#, fuzzy, c-format +#| msgid "Value of the option `%s' must be in the range [%, %]" +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "La valeur de l'option '%s' doit être inclue entre % et %" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Les données compressées ne peuvent pas être lues depuis un terminal" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Les données compressées ne peuvent pas être écrites dans un terminal" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "%s: Too small to be a valid .xz file" +msgid "File is too small to be a .lzma file" +msgstr "%s : Trop petit pour être un fichier xz valide." + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Impossible d'écrire vers la sortie standard" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Erreur inconnue" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "Options non prises en charge" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "Enchaînement ou options de filtres non pris en charge" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s : Nom d'option invalide" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s : Suffixe multiplicateur invalide" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s : Format de fichier inconnu" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "Le filtre LZMA1 ne peut être utilisé avec le format .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "Le nombre maximal de filtres est quatre" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -z, --compress force compression\n" +#~ " -d, --decompress force decompression\n" +#~ " -t, --test test compressed file integrity\n" +#~ " -l, --list list information about .xz files" +#~ msgstr "" +#~ " -z, --compress forcer le mode compression\n" +#~ " -d, --decompress forcer le mode décompression\n" +#~ " -t, --test tester l'intégrité du fichier compressé\n" +#~ " -l, --list lister les informations sur les fichiers .xz" + +#~ msgid "" +#~ " -k, --keep keep (don't delete) input files\n" +#~ " -f, --force force overwrite of output file and (de)compress links\n" +#~ " -c, --stdout write to standard output and don't delete input files" +#~ msgstr "" +#~ " -k, --keep ne pas supprimer les fichiers d'entrée\n" +#~ " -f, --force forcer l'écrasement éventuel du fichier de sortie et\n" +#~ " (dé)compresser les liens symboliques\n" +#~ " -c, --stdout écrire sur la sortie standard et ne pas supprimer les\n" +#~ " fichiers d'entrée" + +#, fuzzy +#~| msgid "" +#~| " --no-sparse do not create sparse files when decompressing\n" +#~| " -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n" +#~| " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~| " omitted, filenames are read from the standard input;\n" +#~| " filenames must be terminated with the newline character\n" +#~| " --files0[=FILE] like --files but use the null character as terminator" +#~ msgid "" +#~ " --no-sparse do not create sparse files when decompressing\n" +#~ " -S, --suffix=.SUF use the suffix '.SUF' on compressed files\n" +#~ " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~ " omitted, filenames are read from the standard input;\n" +#~ " filenames must be terminated with the newline character\n" +#~ " --files0[=FILE] like --files but use the null character as terminator" +#~ msgstr "" +#~ " --no-sparse ne pas créer de 'sparse file' lors de la décompression\n" +#~ " -S, --suffix=.SUF utiliser le suffixe `.SUF' pour les fichiers compressés\n" +#~ " --files[=FILE] lire les fichiers sur lesquels opérer depuis FILE ; si\n" +#~ " FILE est omis, ceux-ci sont lus depuis l'entrée standard\n" +#~ " et doivent être suivis d'un caractère retour à la ligne\n" +#~ " --files0[=FILE] comme --files mais avec un caractère null comme séparateur" + +#, fuzzy +#~ msgid "" +#~ " -F, --format=FMT file format to encode or decode; possible values are\n" +#~ " 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'\n" +#~ " -C, --check=CHECK integrity check type: 'none' (use with caution),\n" +#~ " 'crc32', 'crc64' (default), or 'sha256'" +#~ msgstr "" +#~ " -F, --format=FMT format du fichier à encoder ou décoder ; sont acceptés :\n" +#~ " `auto' (par défaut), `xz', `lzma' et `raw'\n" +#~ " -C, --check=CHECK type de vérification d'intégrité : `none' (à utiliser avec\n" +#~ " précaution), `crc32', `crc64' (par défaut) ou `sha256'" + +#, fuzzy, no-c-format +#~ msgid "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " --memlimit-mt-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " set memory usage limit for compression, decompression,\n" +#~ " threaded decompression, or all of these; LIMIT is in\n" +#~ " bytes, % of RAM, or 0 for defaults" +#~ msgstr "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " règle la limite d'utilisation mémoire pour la compression,\n" +#~ " décompression ou les deux ; LIMIT est en octets,\n" +#~ " pourcentage de RAM, ou 0 pour la valeur par défaut" + +#~ msgid "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n" +#~ " --lzma2[=OPTS] more of the following options (valid values; default):\n" +#~ " preset=PRE reset options to a preset (0-9[e])\n" +#~ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM number of literal context bits (0-4; 3)\n" +#~ " lp=NUM number of literal position bits (0-4; 0)\n" +#~ " pb=NUM number of position bits (0-4; 2)\n" +#~ " mode=MODE compression mode (fast, normal; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM maximum search depth; 0=automatic (default)" +#~ msgstr "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1/2 ; OPTS est une liste d'options parmi les suivantes\n" +#~ " --lzma2[=OPTS] (entre parenthèses : valeurs valides et par défaut) :\n" +#~ " preset=PRE remettre les options à un préréglage (0-9[e])\n" +#~ " dict=NUM taille dictionnaire (4KiB - 1536MiB ; 8MiB)\n" +#~ " lc=NUM nombre de 'literal context bits' (0-4 ; 3)\n" +#~ " lp=NUM nombre de 'literal position bits' (0-4 ; 0)\n" +#~ " pb=NUM nombre de 'position bits' (0-4 ; 2)\n" +#~ " mode=MODE mode de compression (fast, normal ; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME 'match finder' (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM profondeur de recherche maximale ;\n" +#~ " 0=automatique (par défaut)" + +#, fuzzy +#~ msgid "" +#~ "\n" +#~ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~ " --arm[=OPTS] ARM BCJ filter\n" +#~ " --armthumb[=OPTS] ARM-Thumb BCJ filter\n" +#~ " --arm64[=OPTS] ARM64 BCJ filter\n" +#~ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~ " --sparc[=OPTS] SPARC BCJ filter\n" +#~ " --riscv[=OPTS] RISC-V BCJ filter\n" +#~ " Valid OPTS for all BCJ filters:\n" +#~ " start=NUM start offset for conversions (default=0)" +#~ msgstr "" +#~ "\n" +#~ " --x86[=OPTS] filtre BCJ x86 (32-bit et 64-bit)\n" +#~ " --powerpc[=OPTS] filtre BCJ PowerPC ('big endian' uniquement)\n" +#~ " --ia64[=OPTS] filtre BCJ IA-64 (Itanium)\n" +#~ " --arm[=OPTS] filtre BCJ ARM ('little endian' uniquement)\n" +#~ " --armthumb[=OPTS] filtre BCJ ARM-Thumb ('little endian' uniquement)\n" +#~ " --sparc[=OPTS] filtre BCJ SPARC\n" +#~ " OPTS valides pour tous les filtres BCJ :\n" +#~ " start=NUM position de début de la conversion (défaut=0)" + +#~ msgid "" +#~ "\n" +#~ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" +#~ " dist=NUM distance between bytes being subtracted\n" +#~ " from each other (1-256; 1)" +#~ msgstr "" +#~ "\n" +#~ " --delta[=OPTS] Filtre delta ; OPTS valides (vals. valides ; par défaut) :\n" +#~ " dist=NUM distance entre les octets soustraits les\n" +#~ " uns aux autres (1-256 ; 1)" + +#~ msgid "" +#~ " -q, --quiet suppress warnings; specify twice to suppress errors too\n" +#~ " -v, --verbose be verbose; specify twice for even more verbose" +#~ msgstr "" +#~ " -q, --quiet masquer les avertissements ; spécifier deux fois pour\n" +#~ " aussi masquer les erreurs\n" +#~ " -v, --verbose être bavard ; spécifier deux fois pour l'être davantage" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help afficher l'aide courte (ne liste que les options de base)\n" +#~ " -H, --long-help afficher l'aide longue (ceci) puis quitter" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help afficher l'aide courte (ceci) puis quitter\n" +#~ " -H, --long-help afficher l'aide longue (liste aussi les options avancées)" + +#~ msgid "Failed to enable the sandbox" +#~ msgstr "Echec de l'activation de la sandboxe" + +#~ msgid "The selected match finder requires at least nice=%" +#~ msgstr "Le `match finder' choisi nécessite au moins nice=%" + +#~ msgid "Sandbox is disabled due to incompatible command line arguments" +#~ msgstr "La sandbox est désactivée car elle est incompatible avec les arguments passés" + +#~ msgid "Sandbox was successfully enabled" +#~ msgstr "La sandboxe a été activée avec succès" + +#~ msgid "Memory usage limit for compression: " +#~ msgstr "Limite d'utilisation pour la compression : " + +#~ msgid " Streams: %s\n" +#~ msgstr " Flux : %s\n" + +#~ msgid " Blocks: %s\n" +#~ msgstr " Blocs : %s\n" + +#~ msgid " Ratio: %s\n" +#~ msgstr " Ratio : %s\n" + +#~ msgid " Check: %s\n" +#~ msgstr " Vérification : %s\n" + +#~ msgid "" +#~ " Streams:\n" +#~ " Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding" +#~ msgstr "" +#~ " Flux :\n" +#~ " Flux Blocs PositionComp PositionDécomp TailleComp TailleDécomp Ratio Vérif. Bourrage" + +#~ msgid "" +#~ " Blocks:\n" +#~ " Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check" +#~ msgstr "" +#~ " Blocs :\n" +#~ " Flux Bloc PositionComp PositionDécomp TailleTot TailleDécomp Ratio Vérif." + +#~ msgid " CheckVal %*s Header Flags CompSize MemUsage Filters" +#~ msgstr " ValVérif %*sEn-tête Drapeaux TailleComp UtilMém Filtres" + +#~ msgid "Error setting O_NONBLOCK on standard input: %s" +#~ msgstr "Impossible d'établir le drapeau O_NONBLOCK sur la sortie standard : %s" + +#~ msgid "Error setting O_NONBLOCK on standard output: %s" +#~ msgstr "Impossible d'activer le drapeau O_NONBLOCK sur la sortie standard : %s" diff --git a/cpp/third_party/xz-5.8.3/po/hr.gmo b/cpp/third_party/xz-5.8.3/po/hr.gmo new file mode 100644 index 0000000000000000000000000000000000000000..e43f132de575467c6f0c3d2d39a85405f382dd91 GIT binary patch literal 28799 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 bM}6KM9303jcn+bjGL-iA, 2020-2025. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: xz 5.8.0-pre1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-03-26 21:00-0700\n" +"Last-Translator: Božidar Putanec \n" +"Language-Team: Croatian \n" +"Language: hr\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" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: vim9.1\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: nevaljani argument za --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: PreviÅ¡e argumenata za --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "Uz '--block-list' nedostaje veliÄina bloka iza broja lanca filtra '%c:'" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "za '--block-list' može se koristiti '0' samo kao posljednji element" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Nepoznata vrsta formata datoteke" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Nepodržani naÄin (tip) provjere integriteta" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Samo jedna datoteka može biti specificirana s '--files' ili '--files0'." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Varijabla okruženja '%s' sadrži previÅ¡e argumenata" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "PodrÅ¡ka za kompresiju bila je onemogućena tijekom kompilacije" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "PodrÅ¡ka za dekompresiju bila je onemogućena tijekom kompilacije" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Kompresija LZIP datoteka (.lz) nije podržana" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "'--block-list' je zanemaren (vrijedi samo za komprimiranje u .xz format)" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Uz opciju '--format=raw', '--suffix=.EXT' je nužan (osim ako ne piÅ¡e na standardni izlaz)" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Maksimalni broj filtara je Äetiri" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "GreÅ¡ka u opciji '--filters%s=FILTRI':" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Za danu postavku filtara treba viÅ¡e memorije (granica upotrebe memorije je preniska)" + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "lanac filtra %u koristi se za '--block-list', ali nije naveden s '--filters%u='" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Ne preporuÄuje se koristiti poÄetne (preset) postavke u sirovom naÄinu rada." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "ToÄne opcije poÄetnih (preset) postavki mogu se razlikovati ovisno od verzije do verzije softvera." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Samo LZMA1 filtar podržava format .lzma" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "Ne može se koristi LZMA1 s .xz formatom" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Lanac filtra %u nije kompatibilan s '--flush-timeout'" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Prelazimo na naÄin rada s jednom dretvom zbog '--flush-timeout'" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Nepodržane opcije u lancu filtra %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Koristimo do % dretvi." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Nepodržani lanac filtara ili opcija filtara" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Za dekompresiju će trebati %s MiB memorije." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Smanjen je broj dretvi od %s na %s da ne prekoraÄi granicu upotrebe memorije od %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Smanjen je broj od %s na jednu dretvu, ali granica od %s MiB automatske upotrebe memorije joÅ¡ uvijek je prekoraÄena. Potrebno je %s MiB memorije. Ipak nastavljamo dalje." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Prelazimo na naÄin rada s jednom dretvom da ne prekoraÄimo granicu upotrebe memorije od %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "VeliÄina LZMA%c rjeÄnika prilagoÄ‘ena je od %s na %s da se ne prekoraÄi granica upotrebe memorije od %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "VeliÄina LZMA%c rjeÄnika prilagoÄ‘ena je za '--filters%u' od %s na %s da ne prekoraÄi granicu upotrebe memorije od %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "GreÅ¡ka pri prebacivanju na lanac filtra %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "GreÅ¡ka pri stvaranju cijevi: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() nije uspjela: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Izgleda da je datoteka premjeÅ¡tena -- nije izbrisana" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "Brisanje %s nije moguće: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Nije moguće promijeniti vlasnika datoteke: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Nije moguće promijeniti grupu datoteke: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Nije moguće postaviti prava dostupa datoteci: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Nije uspjelo sinkronizirati datoteku: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Nije uspjelo sinkronizirati direktorij datoteke: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "GreÅ¡ka pri pokuÅ¡aju dobivanja oznaka statusa datoteke iz standardnog ulaza: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: To je simboliÄna poveznica -- preskoÄeno" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: To je direktorij -- preskoÄeno" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: To nije regularna datoteka -- preskoÄeno" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Datoteka ima postavljen SETUID- ili SETGID bit -- preskoÄeno" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Datoteka ima postavljen ljepljivi bit -- preskoÄeno" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Ulazna datoteka ima viÅ¡e od jednog tvrdog linka -- preskoÄeno" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Prazna datoteka -- preskoÄeno" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "GreÅ¡ka pri vraćanju statusnih flags na standardni ulaz: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "GreÅ¡ka pri dobivanju oznaka statusa datoteke iz standardnog izlaza: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Nije uspjelo otvoriti direktorij: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: OdrediÅ¡te nije obiÄna datoteka" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "GreÅ¡ka pri vraćanju 'O_APPEND' oznaka na standardni izlaz: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Nije uspjelo zatvoriti datoteku: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: 'Seeking' (traženje) nije uspjelo pri pokuÅ¡aju stvaranja raÅ¡trkane datoteke: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: GreÅ¡ka pri Äitanju: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: GreÅ¡ka pri 'seeking' (traženju) datoteke: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: NeoÄekivani kraj datoteke" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: GreÅ¡ka pri pisanju: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Onemogućeno" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "KoliÄina fiziÄke memorije (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Broj dretvi procesora:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Kompresija:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Dekompresija:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Dekompresija s viÅ¡e dretvi:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Zadano za -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Informacije o hardveru:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Granica za koriÅ¡tenje memorije:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Tokovi:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blokovi:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Komprimirana veliÄina:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Dekomprimirana veliÄina:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Omjer:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Kontrola:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Dopuna toka:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Potrebna memorija:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "VeliÄine u zaglavljima:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "KoliÄina datoteka:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Tok" + +#: src/xz/list.c +msgid "Block" +msgstr "Blok" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blokovi" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "KomprOdmak" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "DekomprOdmak" + +#: src/xz/list.c +msgid "CompSize" +msgstr "KomprVeliÄina" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "DekomprVeliÄina" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "TotalVeliÄina" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Omjer" + +#: src/xz/list.c +msgid "Check" +msgstr "Kontrola" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "KontrVrijedn" + +#: src/xz/list.c +msgid "Padding" +msgstr "Dopuna" + +#: src/xz/list.c +msgid "Header" +msgstr "Zaglavlje" + +#: src/xz/list.c +msgid "Flags" +msgstr "Flags" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "MemUpotreba" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtri" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Nijedan" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Nepoznat-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Nepoznat-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Nepoznat-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Nepoznat-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Nepoznat-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Nepoznat-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Nepoznat-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Nepoznat-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Nepoznat-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Nepoznat-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Nepoznat-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Nepoznat-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Datoteka je prazna" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Datoteka je premala da bude valjana .xz datoteka" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr " Tok Blok Komprimirano Dekomprimir Omjer Kontr Datoteka" + +#: src/xz/list.c +msgid "Yes" +msgstr "Da" + +#: src/xz/list.c +msgid "No" +msgstr "Ne" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Minimalna verzija programa XZ:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s datoteka\n" +msgstr[1] "%s datoteke\n" +msgstr[2] "%s datoteka\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Ukupno:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "'--list' radi samo sa .xz datoteke (--format=xz ili --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "PokuÅ¡ajte s ‘lzmainfo’ s .lzma datotekama." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "'--list' ne podržava Äitanje iz standardnog izlaza" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: GreÅ¡ka pri Äitanju datoteka: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: NeoÄekivani kraj ulaznih podataka tijekom Äitanja imena datoteka" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Prazni NULA-znak pronaÄ‘en pri Äitanju imena datoteka; možda ste mislili koristiti '--files0' umjesto '--files'?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Komprimiranje i dekomprimiranje s '--robot' joÅ¡ nije podržano." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Nije moguće Äitati podatke iz standardnog ulaza dok se Äitaju imena datoteka iz standardnog ulaza" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Interna greÅ¡ka (bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Nije moguće uspostaviti rukovatelje signala" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Nema provjere integriteta -- ne provjeravamo integritet datoteke" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Nepodržani tip provjere integriteta -- ne provjeravamo integritet datoteke" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Dostignuta je granica za upotrebu memorije" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Format datoteke nije prepoznat" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Nepodržane opcije" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Komprimirani podaci su oÅ¡tećeni" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "NeoÄekivani kraj ulaznih podataka" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s Potrebno je MiB memorije. OgraniÄenja su onemogućena." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s Potrebno je MiB memorije. OgraniÄenje je %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Lanac filtara: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "PokuÅ¡ajte s '%s --help’ za pomoć i viÅ¡e informacija." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "GreÅ¡ka prilikom ispisa teksta pomoći (kod greÅ¡ke %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Uporaba: %s [OPCIJA...][DATOTEKA...]\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Komprimira ili dekomprimira DATOTEKE u .xz formatu." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Obvezni argumenti za duge opcije, obvezni su i za kratke opcije." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "NaÄin rada:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "prisilna kompresija" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "prisilna dekompresija" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "provjera integriteta komprimirane datoteke" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "prikaz informacija o .xz datotekama" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Modifikatori naÄina rada:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "sprema ulazne datoteke (ne brisati ih)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "prisilno piÅ¡e preko izlazne datoteke i (de)komprimira linkove" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "ispiÅ¡e na standardni izlaz i zadrži ulazne datoteke" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "ne sinkronizira izlaznu datoteku s ureÄ‘ajem za pohranu podataka dok ne izbriÅ¡e ulaznu datoteku" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "dekomprimira samo prvi tok i tiho ignorira moguće preostale ulazne podatke" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "ne stvara rasprÅ¡ene datoteke kad komprimira" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".EXT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "koristi sufiks '.EXT' na komprimiranim datotekama" + +#: src/xz/message.c +msgid "FILE" +msgstr "DATOTEKA" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "imena datoteka koje treba obraditi Äita iz DATOTEKA; ako DATOTEKA nije navedena, imena datoteka Äita iz standardnog ulaza; svako ime datoteke mora zavrÅ¡iti sa znakom novog retka (newline)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "kao '--files', ali s NULA-znakom (null character, Unicode U+0000) kao zavrÅ¡etak imena" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Osnovni format datoteke i opcije za kompresiju:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMAT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "format datoteke za kodiranje ili dekodiranje; moguće vrijednosti su 'auto' (zadano), 'xz', 'lzma', 'lzip' i 'raw'" + +#: src/xz/message.c +msgid "NAME" +msgstr "IME" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "vrsta provjere integriteta: 'none' (koristite s oprezom), 'crc32', 'crc64' (zadano) ili 'sha256'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "ne verificira provjeru integriteta pri dekompresiji" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "poÄetna postavka kompresije (zadano je 6); razmotrite upotrebu memorije za komprimiranje *i* dekomprimiranje prije upotrebe 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "pokuÅ¡a poboljÅ¡ati omjer kompresije koristeći viÅ¡e vremena procesora (CPU); ne utjeÄe na potrebnu memoriju za dekompresiju" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "BROJ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "koristi maksimalno ovaj BROJ dretvi; zadano je 0, Å¡to znaÄi da koristi toliko dretvi, koliko procesor ima jezgri" + +#: src/xz/message.c +msgid "SIZE" +msgstr "VELIÄŒINA" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "zapoÄne novi .xz blok nakon svakih toliko (\"VELIÄŒINA) bajtova ulaznih bajtova; to koristite da postavite veliÄinu bloka za kompresiju s nekoliko dretvi (tokova)" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOKOVI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "zapoÄne novi .xz block nakon te veliÄina (BLOKOVI) nekomprimiranih podataka odvojenih zarezima; opcionalno, navedite lance filtra broj (0-9) iza kojeg slijedi ':' a prije veliÄine nekomprimiranih podataka" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "ako se pri komprimiranju potroÅ¡i viÅ¡e od NUM milisekundi od prethodnog pražnjenja, a daljnje Äitanje bi blokiralo ulaz, isprazni sve podatke na Äekanju" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "OGRANIÄŒENJE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "postavi ograniÄenje na koliÄinu memorije za kompresiju, dekompresiju, dekompresiju s dretvama, ili za sve to; OGRANIÄŒENJE je u bajtovima, % od RAM-a, ili 0 za zadano" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "ako dane postavke kompresije prekoraÄe ograniÄenje upotrebe memorije, zavrÅ¡i s greÅ¡kom umjesto da prilagodi postavke shodno ograniÄenju memorije" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "PrilagoÄ‘eni lanac filtra za kompresiju (alternativa koriÅ¡tenju poÄetnih postavki):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTRI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "postavi lanac filtra koristeći liblzma filtar string sintaksu; upotrebite '--filters-help' za viÅ¡e informacija" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "postavite dodatne lance filtra koristeći liblzma filtar sintaksu s '--block-list'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "pokaže viÅ¡e informacija za liblzma filtar sintaksu" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "OPCIJE" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 ili LZMA2; OPCIJE je lista od nula ili viÅ¡e, zarezom odvojenih opcija (valjane vrijednosti; zadano):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "PoÄP" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "vrati opcije na poÄetne postavke" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "veliÄina rjeÄnika" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "broj kontekstnih bitova po bajtu" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "broj pozicijskih bitova po bajtu" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "broj pozicijskih bitova" + +#: src/xz/message.c +msgid "MODE" +msgstr "NAÄŒIN" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "naÄin kompresije" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "lijepa duljina podudaranja" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "tražilica podudaranja" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "maksimalna dubina traženja; 0=automatic (zadano)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ filtar (32-bit and 64-bit)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ filtar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BCJ filtar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ filtar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ filtar (samo veliki endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (Itanium) BCJ filtar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ filtar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ filtar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "Valid OPTS za sve BCJ filtre:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "poÄetni pomak za konverzije (zadano=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Delta filtar; valjane OPCIJE (valjane vrijednosti; zadano:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "razmak izmeÄ‘u bajtova koji se oduzimaju jedan od drugog" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Ostale opcije:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "potisne upozorenja; navedite dva puta da potisnete i pogreÅ¡ke" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "objaÅ¡njava Å¡to radi; navedite dva put za joÅ¡ viÅ¡e informacija" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "upozorenja nemaju utjecaja na izlazni status" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "koristite poruke za raÄunalnu obradu (korisno za skripte)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "pokaže ukupnu koliÄinu RAM-a i trenutno aktivna ograniÄenja koriÅ¡tenja memorije, pa iziÄ‘e" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "ispiÅ¡e kratku pomoć (popis osnovnih opcija)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "ispiÅ¡e ovu opÅ¡irnu pomoć i iziÄ‘e" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "ispiÅ¡e ovu kratku pomoć i iziÄ‘e" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "ispiÅ¡e opÅ¡irnu pomoć (takoÄ‘er i popis naprednih opcija)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "pokaže informacije o inaÄici" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Ako DATOTEKA nije navedena ili je '-' (crtica), Äita standardni ulaz." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"GreÅ¡ke prijavite na <%s> (na engleskom ili finskom).\n" +"Prijavite greÅ¡ke u prijevodu na ." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "%s matiÄna mrežna stranica: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "OVO JE RAZVOJNA INAÄŒICA I NIJE NAMIJENJENA ZA PROIZVODNJU." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Lanci filtara postavljaju se pomoću '--filters=FILTERS' ili '--filters1=FILTERS ... --filters9=FILTERS' opcije. Svaki filter u lancu može biti odvojen s razmakom ili s '--' (dvije crtice). Alternativno, poÄetna postavka %s može biti navedena umjesto lanca filtra." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Podržani filtri i njihove opcije su:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Opcije moraju biti parovi 'name=value' odvojeni zarezima" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Nevaljano ime opcije" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Nevaljana vrijednost opcije" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Nepodržana LZMA1/LZMA2 poÄetna postavka: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Zbroj lc i lp ne smije biti veći od 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Ime datoteke nema poznatu ekstenziju, preskaÄemo" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Datoteka već ima '%s' ekstenziju, preskaÄemo" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Nevaljana ekstenzija u imenu datoteke" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Vrijednost nije nula ili pozitivni dekadski cijeli broj" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Nevaljani sufiks-množitelj" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Valjani sufiks-množitelji su 'KiB' (2^10), 'MiB' (2^20), i 'GiB' (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Vrijednost opcije '%s' mora biti u rasponu [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Nije moguće Äitati komprimirane podatke iz terminala" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Nije moguće pisati komprimirane podatke na terminal" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Uporaba: %s [--help] [--version] [DATOTEKA...]\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Pokaže informacije pohranjene u zaglavlju datoteke .lzma." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Datoteka je premala da bude .lzma datoteka" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "To nije .lzma datoteka" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Pisanje na standardni izlaz nije uspjelo" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Nepoznata greÅ¡ka" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Nepodržane poÄetne opcije" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Nepodržani flag u poÄetnoj opciji" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Nevaljano ime opcije" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Vrijednost opcije ne može biti prazna" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Vrijednost je izvan granica" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Ova opcija ne podržava upotrebu sufiks-množitelja" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Nevaljani sufiks-množitelj (KiB, MiB, or GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Nepoznato ime filtra" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Ovaj filtar ne može se koristi u .xz formatu" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Dodjela memorije nije uspjela" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Prazan string nije dopuÅ¡ten, pokuÅ¡ajte s '6' ako je potrebna zadana vrijednost" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Maksimalni broj filtara je Äetiri" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Nema imena filtra" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Nevaljani lanac filtra (nema 'lzma2’ na kraju)?" diff --git a/cpp/third_party/xz-5.8.3/po/hu.gmo b/cpp/third_party/xz-5.8.3/po/hu.gmo new file mode 100644 index 0000000000000000000000000000000000000000..800f812947af292c8cb65964565ad13ef4ed75e7 GIT binary patch literal 15949 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, 2019, 2022, 2024. +msgid "" +msgstr "" +"Project-Id-Version: xz 5.6.0-pre2\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2024-02-17 18:35+0100\n" +"Last-Translator: Meskó Balázs \n" +"Language-Team: Hungarian \n" +"Language: hu\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" +"plural-forms: nplurals=2; plural=(n != 1);\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.4\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Érvénytelen argumentum a --block-list kapcsolóhoz" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Túl sok argumentum a --block-list kapcsolóhoz" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "A --block-list kapcsolónál hiányzik a blokkméret a(z) „%c:†szűrÅ‘láncszám után" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "A 0 csak utolsó elemként használható a --block-list kapcsolónál" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Ismeretlen fájlformátumtípus" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Nem támogatott integritás-ellenÅ‘rzési típus" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Csak egy fájl adható meg a „--files†vagy „--files0†kapcsolóknál." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "A(z) %s környezeti változó túl sok argumentumot tartalmaz" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "A tömörítési támogatás ki lett kapcsolva fordítási idÅ‘ben" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "A kibontási támogatás ki lett kapcsolva fordítási idÅ‘ben" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Az lzip-fájlok (.lz) tömörítése nem támogatott" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "A --block-list kapcsoló csak .xz formátum esetén van figyelembe véve" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "A --format=raw esetén a --suffix=.SUF szükséges, hacsak nem a szabványosra kimenetre ír" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "A szűrÅ‘k legnagyobb száma négy" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Hiba a --filters%s=SZŰRÅK kapcsolóban:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "A memóriahasználat túl alacsony a megadott szűrÅ‘beállításokhoz." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "A --block-list használja a(z) %u. szűrÅ‘láncot, de az nincs megadva a --filters%u= kapcsolóval" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Az elÅ‘beállítások használata nyers módban nem javasolt." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Az elÅ‘beállítások pontos beállításai különbözhetnek a szoftververziók között." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Az .lzma formátum csak az LZMA1 szűrÅ‘t támogatja" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "Az LZMA1 nem használható az .xz formátummal" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "A(z) %u. szűrÅ‘lánc nem kompatibilis a --flush-timeout kapcsolóval" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Egyszálú módra váltás a --flush-timeout kapcsoló miatt" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Nem támogatott kapcsolók a(z) %u szűrÅ‘láncban" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Legfeljebb % szál használata." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Nem támogatott szűrÅ‘lánc vagy szűrÅ‘kapcsolók" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "A kibontáshoz %s MiB memória szükséges." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "A szálak számának csökkentése errÅ‘l: %s, erre: %s, hogy ne lépje túl a(z) %s MiB-os korlátot" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "A szálak számának csökkentése errÅ‘l: %s, egyre. A(z) %s MiB-os automatikus memóriahasználati korlát így is túl lett lépve. %s MiB memória szükséges. Ennek ellenére folytatás mindenképpen." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Egyszálú módra váltás, hogy ne lépje túl a(z) %s MiB-os memóriahasználati korlátot" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Az LZMA%c szótár méretének módosítása errÅ‘l: %s MiB, erre: %s MiB, hogy ne lépje túl a(z) %s MiB-os korlátot" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "A --filters%2$u szűrÅ‘höz tartozó LZMA%1$c szótár méretének módosítása %3$s MiB-ról %4$s MiB-ra, hogy ne lépje túl a(z) %5$s MiB-os korlátot" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Hiba a(z) %u. szűrÅ‘lánc létrehozásakor: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Hiba a csÅ‘vezeték létrehozásakor: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() sikertelen: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Úgy tűnik, hogy a fájl át lett helyezve, nincs eltávolítás" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Nem távolítható el: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: A fájl tulajdonosa nem adható meg: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: A fájl csoportja nem adható meg: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: A fájl jogosultságai nem adhatók meg: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: A fájl lezárása sikertelen: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: A fájl lezárása sikertelen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Hiba a fájl állapotjelzÅ‘inek lekérdezésekor a szabványos bemenetrÅ‘l: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Szimbolikus link, kihagyás" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Könyvtár, kihagyás" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Nem szabályos fájl, kihagyás" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: A fájlon setuid vagy setgid bit van beállítva, kihagyás" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: A fájlon sticky bit van beállítva, kihagyás" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: A bemeneti fájlhoz több mint egy hard link tartozik, kihagyás" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Üres fájlnév, kihagyás" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Hiba a fájl állapotjelzÅ‘inek visszaállításakor a szabványos bemenetre: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Hiba a fájl állapotjelzÅ‘inek lekérdezésekor a szabványos kimenetrÅ‘l: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s: A fájl lezárása sikertelen: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%s: Nem szabályos fájl, kihagyás" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Hiba az O_APPEND visszaállításakor a szabványos kimenetre: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: A fájl lezárása sikertelen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: A pozícionálás sikertelen a ritka fájl létrehozásának kísérletekor: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Olvasási hiba: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Hiba a fájlban pozícionáláskor: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Váratlan fájlvég" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Ãrási hiba: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Letiltva" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Fizikai memória (RAM) mennyisége:" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Processzorszálak száma:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Tömörítés:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Kibontás:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Többszálás kibontás:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "A -T0 alapértelmezése:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "HardverjellemzÅ‘k:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Memóriahasználat korlátja:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Adatfolyamok:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blokkok:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Tömörített méret:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Kibontott méret:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Arány:" + +#: src/xz/list.c +msgid "Check:" +msgstr "EllenÅ‘rzés:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Adatfolyam kerete:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Szükséges memória:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Méretek a fejlécekben:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Fájlok száma:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Adatfolyam" + +#: src/xz/list.c +msgid "Block" +msgstr "Blokk" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blokkok" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "Tömörített eltolás" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "Kibontott eltolás" + +#: src/xz/list.c +msgid "CompSize" +msgstr "Tömörített méret" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "Kibontott méret" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "Teljes méret" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Arány" + +#: src/xz/list.c +msgid "Check" +msgstr "EllenÅ‘rzés" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "EllenÅ‘rzőérték" + +#: src/xz/list.c +msgid "Padding" +msgstr "Keret" + +#: src/xz/list.c +msgid "Header" +msgstr "Fejléc" + +#: src/xz/list.c +msgid "Flags" +msgstr "JelzÅ‘k" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "Memóriahasználat" + +#: src/xz/list.c +msgid "Filters" +msgstr "SzűrÅ‘k" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Nincs" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Névtelen-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Névtelen-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Névtelen-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Névtelen-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Névtelen-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Névtelen-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Névtelen-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Névtelen-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Névtelen-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Névtelen-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Névtelen-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Névtelen-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: A fájl üres" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Túl kicsi, hogy érvényes .xz fájl legyen" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Folyam Blokkok Tömörített Kibontott Arány EllenÅ‘rzés Fájlnév" + +#: src/xz/list.c +msgid "Yes" +msgstr "Igen" + +#: src/xz/list.c +msgid "No" +msgstr "Nem" + +#: src/xz/list.c +#, fuzzy +#| msgid " Minimum XZ Utils version: %s\n" +msgid "Minimum XZ Utils version:" +msgstr " Legkisebb XZ Utils verzió: %s\n" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s fájl\n" +msgstr[1] "%s fájl\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Összesen:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "A --list csak .xz fájlokkal működik (--format=xz vagy --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Az „lzmainfo†kipróbálása az .lzma fájlok esetén." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "A --list nem támogatja a szabványos bemenetrÅ‘l beolvasást" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Hiba a fájlnevek olvasásakor: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: A bemenet váratlanul véget ért a fájlnevek olvasásakor" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Null karakter található a fájlnevek olvasásakor; talán a „--files0†kapcsolóra gondolt a „--files†helyett?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "A tömörítés és kibontás még nem támogatott a --robot kapcsolóval." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Az adatok nem olvashatók be a szabványos bemenetrÅ‘l a fájlnevek olvasásakor" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "BelsÅ‘ hiba (bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "A szignálkezelÅ‘k nem hozhatók létre" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Nincs integritás-ellenÅ‘rzés; a fájl épsége nem lesz ellenÅ‘rizve" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Nem támogatott integritás-ellenÅ‘rzési típus; a fájl épsége nem lesz ellenÅ‘rizve" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Memóriahasználat korlátja elérve" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "A fájlformátum nem felismert" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Nem támogatott kapcsolók" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "A tömörített adatok megsérültek" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "A bemenet váratlanul véget ért" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB memória szükséges. A korlátozás letiltva." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB memória szükséges. A korlát %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: SzűrÅ‘lánc: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "További információkért adja ki a következÅ‘ parancsot: „%s --helpâ€." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "Usage: %s [OPTION]... [FILE]...\n" +#| "Compress or decompress FILEs in the .xz format.\n" +#| "\n" +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" +"Használat: %s [KAPCSOLÓ]... [FÃJL]...\n" +".xz formátumú FÃJLok tömörítése vagy kibontása.\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "A hosszú kapcsolók kötelezÅ‘ argumentumai a rövid kapcsolók esetén is kötelezÅ‘k.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr " Működési mód:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force compression" +msgstr "Kibontás:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force decompression" +msgstr "Kibontás:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +" Műveleti módosítók:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "A szabványos kimenetre írás sikertelen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --single-stream decompress only the first stream, and silently\n" +#| " ignore possible remaining input data" +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" +" --single-stream csak az elsÅ‘ adatfolyam kibontása, és a\n" +" lehetséges hátralévÅ‘ bemeneti adatok mellÅ‘zése" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Basic file format and compression options:\n" +msgid "Basic file format and compression options:" +msgstr "" +"\n" +" AlapvetÅ‘ fájlformátum és tömörítési beállítások:\n" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --ignore-check don't verify the integrity check when decompressing" +msgid "don't verify the integrity check when decompressing" +msgstr " --ignore-check kibontáskor ne ellenÅ‘rizze az épséget" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -0 ... -9 compression preset; default is 6; take compressor *and*\n" +#| " decompressor memory usage into account before using 7-9!" +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" +" -0 ... -9 tömörítési elÅ‘beállítás; alapértelmezett a 6;\n" +" a 7-9 használata elÅ‘tt vegye figyelembe a tömörítÅ‘\n" +" *és* kibontó memóriahasználatát!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -e, --extreme try to improve compression ratio by using more CPU time;\n" +#| " does not affect decompressor memory requirements" +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" +" -e, --extreme a tömörítési arány javítási kísérlete több CPU-idÅ‘\n" +" használatával; nincs hatással a kibontó memóriaigényére" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -T, --threads=NUM use at most NUM threads; the default is 0 which uses\n" +#| " as many threads as there are processor cores" +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" +" -T, --threads=SZÃM legfeljebb ennyi szál használata; alapértelmezett a 0,\n" +" amely annyi szálat használ, amennyi processzormag áll\n" +" rendelkezésre" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-size=SIZE\n" +#| " start a new .xz block after every SIZE bytes of input;\n" +#| " use this to set the block size for threaded compression" +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" +" --block-size=MÉRET\n" +" új .xz blokk indítása minden MÉRETnyi bájt bemenet után;\n" +" a többszálas tömörítés blokkméretének megadásához" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-list=BLOCKS\n" +#| " start a new .xz block after the given comma-separated\n" +#| " intervals of uncompressed data; optionally, specify a\n" +#| " filter chain number (0-9) followed by a ':' before the\n" +#| " uncompressed data size" +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" +" --block-list=BLOKKOK\n" +" új .xz blokk indítása a vesszÅ‘kkel felsorolva megadott\n" +" méretű tömörítetlen adatszakaszok után; a tömörítetlen\n" +" adatok mérete elÅ‘tt egy szűrÅ‘láncszám (0-9) is megadható\n" +" egy „:†karakter közbeiktatásával" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --flush-timeout=TIMEOUT\n" +#| " when compressing, if more than TIMEOUT milliseconds has\n" +#| " passed since the previous flush and reading more input\n" +#| " would block, all pending data is flushed out" +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" +" --flush-timeout=IDÅTÚLLÉPÉS\n" +" tömörítéskor, ha több mint IDÅTÚLLÉPÉS ezredmásodperc\n" +" telt el az elÅ‘zÅ‘ kiírástól, és a bemenetolvasás\n" +" blokkolna, akkor minden adat ki lesz írva" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --no-adjust if compression settings exceed the memory usage limit,\n" +#| " give an error instead of adjusting the settings downwards" +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" +" --no-adjust ha a tömörítési beállítások túllépik a memóriahasználati\n" +" korlátot, akkor hibát fog adni a beállítások lefelé\n" +" állítása helyett" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Custom filter chain for compression (alternative for using presets):" +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" +"\n" +" Egyéni szűrÅ‘lánc a tömörítéshez (alternatíva az elÅ‘beállításokra):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " --filters=FILTERS set the filter chain using the liblzma filter string\n" +#| " syntax; use --filters-help for more information" +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" +"\n" +" --filters=SZŰRÅK a szűrÅ‘lánc beállítása liblzma szűrÅ‘formátummal;\n" +" további információkért lásd a --filters-help kapcsolót" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters1=FILTERS ... --filters9=FILTERS\n" +#| " set additional filter chains using the liblzma filter\n" +#| " string syntax to use with --block-list" +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" +" --filters1=SZŰRÅK ... --filters9=SZŰRÅK\n" +" további szűrÅ‘láncok beállítása liblzma formátummal a\n" +" --block-list kapcsolóhoz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters-help display more information about the liblzma filter string\n" +#| " syntax and exit." +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" +" --filters-help további információk megjelenítése a libzma\n" +" szűrÅ‘formátumról, majd kilépés." + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Number of processor threads:" +msgid "number of position bits" +msgstr "Processzorszálak száma:" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "compression mode" +msgstr "Kibontás:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +" Egyéb kapcsolók:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -Q, --no-warn make warnings not affect the exit status" +msgid "make warnings not affect the exit status" +msgstr "" +" -Q, --no-warn a figyelmeztetések nem befolyásolják a kilépési\n" +" állapotkódot" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr "" +" --robot géppel értelmezhetÅ‘ üzenetek használata\n" +" (parancsfájlok esetén hasznos)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --info-memory display the total amount of RAM and the currently active\n" +#| " memory usage limits, and exit" +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" +" --info-memory az összes RAM mennyiségének és a jelenlegi\n" +" memóriahasználati korlátok megjelenítése, és kilépés" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version a verziószám kiírása és kilépés" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"FÃJL nélkül, vagy ha a FÃJL -, olvasás a szabványos bemenetrÅ‘l.\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Ide jelentse a hibákat: <%s> (angolul vagy finnül).\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "%s honlap: <%s>\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "EZ EGY FEJLESZTÅI VÃLTOZAT, NEM ÉLES HASZNÃLATRA SZÃNT." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "" +#| "Filter chains are set using the --filters=FILTERS or\n" +#| "--filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain\n" +#| "can be separated by spaces or '--'. Alternatively a preset <0-9>[e] can be\n" +#| "specified instead of a filter chain.\n" +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" +"A szűrÅ‘láncokat a --filters=SZŰRÅK vagy a\n" +"--filters1=SZŰRÅK ... --filters9=SZŰRÅK kapcsolókkal lehet megadni. A láncban\n" +"szereplÅ‘ egyes szűrÅ‘ket szóközökkel vagy „--†karakterekkel kell elválasztani.\n" +"Illetve egy <0-9>[e] elÅ‘beállítás is megadható szűrÅ‘lánc helyett.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "A támogatott szűrÅ‘k és azok kapcsolói a következÅ‘k:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be 'name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s: A kapcsolóknak vesszÅ‘kkel elválasztott „név=érték†pároknak kell lenniük" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Érvénytelen kapcsolónév" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s: Érvénytelen kapcsolóérték" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Nem támogatott LZMA1/LZMA2 elÅ‘beállítás: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Az lc és lp összege nem haladhatja meg a 4-et" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: A fájlnév utótagja ismeretlen, kihagyás" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: A fájlnak már van „%s†utótagja, kihagyás" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Érvénytelen fájlnév utótag" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%s: Az érték nem nemnegatív decimális egész szám" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Érvénytelen szorzó utótag" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Az érvényes utótagok: „KiB†(2^10), „MiB†(2^20) és „GiB†(2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "A(z) „%s†kapcsoló értékének a(z) [%, %] tartományban kell lennie" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "A tömörített adatokat nem lehet beolvasni a terminálból" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "A tömörített adatokat nem lehet kiírni a terminálba" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" +"Használat: %s [--help] [--version] [FÃJL]…\n" +"Az .lzma fájl fejlécében tárolt információk megjelenítése" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Show information stored in the .lzma file header." +msgstr "" +"Használat: %s [--help] [--version] [FÃJL]…\n" +"Az .lzma fájl fejlécében tárolt információk megjelenítése" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "A fájl túl kicsi, hogy érvényes .lzma fájl legyen" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Nem .lzma fájl" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "A szabványos kimenetre írás sikertelen" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Ismeretlen hiba" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "Nem támogatott kapcsolók" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "Nem támogatott szűrÅ‘lánc vagy szűrÅ‘kapcsolók" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s: Érvénytelen kapcsolónév" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s: Érvénytelen szorzó utótag" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s: Ismeretlen fájlformátumtípus" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "Az LZMA1 nem használható az .xz formátummal" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "A szűrÅ‘k legnagyobb száma négy" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -z, --compress force compression\n" +#~ " -d, --decompress force decompression\n" +#~ " -t, --test test compressed file integrity\n" +#~ " -l, --list list information about .xz files" +#~ msgstr "" +#~ " -z, --compress kényszerített tömörítés\n" +#~ " -d, --decompress kényszerített kibontás\n" +#~ " -t, --test tömörített fájl épségének tesztelése\n" +#~ " -l, --list információk kiírása az .xz fájlokról" + +#~ msgid "" +#~ " -k, --keep keep (don't delete) input files\n" +#~ " -f, --force force overwrite of output file and (de)compress links\n" +#~ " -c, --stdout write to standard output and don't delete input files" +#~ msgstr "" +#~ " -k, --keep bemeneti fájlok megtartása (ne törölje)\n" +#~ " -f, --force kimeneti fájl kényszerített felülírása,\n" +#~ " és a linkek tömörítése/kibontása\n" +#~ " -c, --stdout írás a szabványos kimenetre írás, és nem törli a\n" +#~ " bemeneti fájlokat" + +#~ msgid "" +#~ " --no-sparse do not create sparse files when decompressing\n" +#~ " -S, --suffix=.SUF use the suffix '.SUF' on compressed files\n" +#~ " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~ " omitted, filenames are read from the standard input;\n" +#~ " filenames must be terminated with the newline character\n" +#~ " --files0[=FILE] like --files but use the null character as terminator" +#~ msgstr "" +#~ " --no-sparse ne hozzon létre ritka fájlokat kibontáskor\n" +#~ " -S, --suffix=.SUF a „.SUF†utótag használata a tömörített fájlokon\n" +#~ " --files[=FÃJL] fájlnevek beolvasása a FÃJLból; ha a FÃJL nincs\n" +#~ " megadva, akkor a fájlnevek a szabványos bemenetrÅ‘l\n" +#~ " lesznek beolvasva; a fájlneveket újsor karakterrel\n" +#~ " kell zárni\n" +#~ " --files0[=FÃJL] mint a --files, de a null karaktert használja\n" +#~ " használja elválasztóként" + +#~ msgid "" +#~ " -F, --format=FMT file format to encode or decode; possible values are\n" +#~ " 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'\n" +#~ " -C, --check=CHECK integrity check type: 'none' (use with caution),\n" +#~ " 'crc32', 'crc64' (default), or 'sha256'" +#~ msgstr "" +#~ " -F, --format=FMT a kódoláshoz vagy dekódoláshoz használt fájlformátum;\n" +#~ " lehetséges értékek „auto†(alapértelmezett), „xzâ€,\n" +#~ " „lzmaâ€, „lzip†és „rawâ€\n" +#~ " -C, --check=ELL integritás-ellenÅ‘rzés típusa: „none†(óvatosan használja),\n" +#~ " „crc32â€, „crc64†(alapértelmezett) vagy „sha256â€" + +#, no-c-format +#~ msgid "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " --memlimit-mt-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " set memory usage limit for compression, decompression,\n" +#~ " threaded decompression, or all of these; LIMIT is in\n" +#~ " bytes, % of RAM, or 0 for defaults" +#~ msgstr "" +#~ " --memlimit-compress=KORLÃT\n" +#~ " --memlimit-decompress=KORLÃT\n" +#~ " --memlimit-mt-decompress=KORLÃT\n" +#~ " -M, --memlimit=KORLÃT\n" +#~ " a memóriahasználati korlát megadása tömörítéshez,\n" +#~ " kibontáshoz, többszálú kibontású vagy mindháromhoz; a\n" +#~ " KORLÃT bájtokban van megadva, a RAM %-ában, vagy 0 az\n" +#~ " alapértelmezéshez" + +#~ msgid "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n" +#~ " --lzma2[=OPTS] more of the following options (valid values; default):\n" +#~ " preset=PRE reset options to a preset (0-9[e])\n" +#~ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM number of literal context bits (0-4; 3)\n" +#~ " lp=NUM number of literal position bits (0-4; 0)\n" +#~ " pb=NUM number of position bits (0-4; 2)\n" +#~ " mode=MODE compression mode (fast, normal; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM maximum search depth; 0=automatic (default)" +#~ msgstr "" +#~ "\n" +#~ " --lzma1[=KAPCS] LZMA1 vagy LZMA2; a KAPCS nulla vagy több vesszÅ‘vel\n" +#~ " --lzma2[=KAPCS] elválasztott kapcsoló az alábbiak közül\n" +#~ " (érvényes érték; alapértelmezett):\n" +#~ " preset=ELÅ visszaállítás egy elÅ‘beállításra (0-9[e])\n" +#~ " dict=SZÃM szótárméret (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=SZÃM literál környezeti bitek száma (0-4; 3)\n" +#~ " lp=SZÃM literál pozícióbitek száma (0-4; 0)\n" +#~ " pb=SZÃM pozícióbitek száma (0-4; 2)\n" +#~ " mode=MÓD tömörítési mód (fast, normal; normal)\n" +#~ " nice=SZÃM az egyezés „nice†hossza (2-273; 64)\n" +#~ " mf=NÉV egyezéskeresÅ‘ (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=SZÃM legnagyobb keresési mélység; 0=automatikus\n" +#~ " (alapértelmezett)" + +#~ msgid "" +#~ "\n" +#~ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~ " --arm[=OPTS] ARM BCJ filter\n" +#~ " --armthumb[=OPTS] ARM-Thumb BCJ filter\n" +#~ " --arm64[=OPTS] ARM64 BCJ filter\n" +#~ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~ " --sparc[=OPTS] SPARC BCJ filter\n" +#~ " --riscv[=OPTS] RISC-V BCJ filter\n" +#~ " Valid OPTS for all BCJ filters:\n" +#~ " start=NUM start offset for conversions (default=0)" +#~ msgstr "" +#~ "\n" +#~ " --x86[=KAPCS] x86 BCJ szűrÅ‘ (32 bites és 64 bites)\n" +#~ " --arm[=KAPCS] ARM BCJ szűrÅ‘\n" +#~ " --armthumb[=KAPCS] ARM-Thumb BCJ szűrÅ‘\n" +#~ " --arm64[=KAPCS] ARM64 BCJ szűrÅ‘\n" +#~ " --powerpc[=KAPCS] PowerPC BCJ szűrÅ‘ (csak big endian esetén)\n" +#~ " --ia64[=KAPCS] IA-64 (Itanium) BCJ szűrÅ‘\n" +#~ " --sparc[=KAPCS] SPARC BCJ szűrÅ‘\n" +#~ " --riscv[=KAPCS] RISC-V BCJ szűrÅ‘\n" +#~ " Érvényes KAPCS az összes BCJ szűrÅ‘höz:\n" +#~ " start=SZÃM kezdési eltolás az átalakításokhoz\n" +#~ " (alapértelmezett=0)" + +#~ msgid "" +#~ "\n" +#~ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" +#~ " dist=NUM distance between bytes being subtracted\n" +#~ " from each other (1-256; 1)" +#~ msgstr "" +#~ "\n" +#~ " --delta[=OPTS] Delta szűrÅ‘; érvényes KAPCSOLÓK\n" +#~ " (érvényes értékek; alapértelmezett default):\n" +#~ " dist=SZÃM az egymásból kivont bájtok közti\n" +#~ " távolság (1-256; 1)" + +#~ msgid "" +#~ " -q, --quiet suppress warnings; specify twice to suppress errors too\n" +#~ " -v, --verbose be verbose; specify twice for even more verbose" +#~ msgstr "" +#~ " -q, --quiet figyelmeztetések elrejtése; adja meg kétszer, hogy a\n" +#~ " hibákat is elrejtse\n" +#~ " -v, --verbose legyen bÅ‘beszédű; adja meg kétszer, hogy még bÅ‘beszédűbb\n" +#~ " legyen" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help a rövid súgó megjelenítése (csak az alapvetÅ‘ kapcsolók)\n" +#~ " -H, --long-help ezen hosszú súgó megjelenítése, és kilépés" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help ezen rövid súgó megjelenítése, és kilépés\n" +#~ " -H, --long-help a hosszú súgó megjelenítése (speciális kapcsolókhoz)" + +#~ msgid "Failed to enable the sandbox" +#~ msgstr "A homokozó engedélyezése sikertelen" + +#, c-format +#~ msgid "The selected match finder requires at least nice=%" +#~ msgstr "A kiválasztott egyezéskeresÅ‘höz legalább nice=% szükséges" + +#~ msgid "Sandbox is disabled due to incompatible command line arguments" +#~ msgstr "A homokozó ki lett kapcsolva a nem kompatibilis parancssori argumentumok miatt" + +#~ msgid "Sandbox was successfully enabled" +#~ msgstr "A homokozó sikeresen engedélyezve" + +#~ msgid "Memory usage limit for compression: " +#~ msgstr "Memóriahasználat korlátja tömörítéskor: " + +#~ msgid " Streams: %s\n" +#~ msgstr " Adatfolyamok: %s\n" + +#~ msgid " Blocks: %s\n" +#~ msgstr " Blokkok: %s\n" + +#~ msgid " Ratio: %s\n" +#~ msgstr " Arány: %s\n" + +#~ msgid " Check: %s\n" +#~ msgstr " EllenÅ‘rzés: %s\n" + +#~ msgid "" +#~ " Streams:\n" +#~ " Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding" +#~ msgstr "" +#~ " Adatfolyamok:\n" +#~ " Folyam Blokkok TömEltolás KibEltolás TömMéret KibMéret Arány EllenÅ‘rzés Keret" + +#~ msgid "" +#~ " Blocks:\n" +#~ " Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check" +#~ msgstr "" +#~ " Blokkok:\n" +#~ " Folyam Blokkok TömEltolás KibEltolás TömMéret KibMéret Arány EllenÅ‘rzés" + +#~ msgid " CheckVal %*s Header Flags CompSize MemUsage Filters" +#~ msgstr " ÉrtékEll %*s Fejléc JelzÅ‘k TömMéret MemHasználat SzűrÅ‘k" diff --git a/cpp/third_party/xz-5.8.3/po/insert-header.sed b/cpp/third_party/xz-5.8.3/po/insert-header.sed new file mode 100644 index 000000000..f9534e7ed --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/insert-header.sed @@ -0,0 +1,31 @@ +# Sed script that inserts the file called HEADER before the header entry. +# +# Copyright (C) 2001 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 file is offered as-is, without any warranty. +# +# Written by Bruno Haible , 2001. +# +# At each occurrence of a line starting with "msgid ", we execute the following +# commands. At the first occurrence, insert the file. At the following +# occurrences, do nothing. The distinction between the first and the following +# occurrences is achieved by looking at the hold space. +/^msgid /{ +x +# Test if the hold space is empty. +s/m/m/ +ta +# Yes it was empty. First occurrence. Read the file. +r HEADER +# Output the file's contents by reading the next line. But don't lose the +# current line while doing this. +g +N +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/cpp/third_party/xz-5.8.3/po/it.gmo b/cpp/third_party/xz-5.8.3/po/it.gmo new file mode 100644 index 0000000000000000000000000000000000000000..910262b2de06b4c77e38677c2e3ec7b1ed62681b GIT binary patch literal 28688 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/it.po b/cpp/third_party/xz-5.8.3/po/it.po new file mode 100644 index 000000000..a8cce1559 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/it.po @@ -0,0 +1,1270 @@ +# SPDX-License-Identifier: 0BSD +# +# Italian translation for xz +# This file is published under the BSD Zero Clause License. +# Gruppo traduzione italiano di Ubuntu-it , 2009, 2010 +# Lorenzo De Liso , 2010. +# Milo Casagrande , 2009, 2010, 2011, 2014, 2019. +# Luca Vercelli 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.8.0-pre1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-03-10 11:31+0000\n" +"Last-Translator: Luca Vercelli \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Launchpad-Export-Date: 2010-08-16 19:16+0000\n" +"X-Generator: Poedit 2.2.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: argomento non valido per --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: troppi argomenti per --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "In --block-list, la dimensione del blocco è mancante, dopo il numero di catena di filtri \"%c:\"" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 può essere usato solo come ultimo elemento in --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: tipo di formato del file sconosciuto" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: tipo di controllo integrità non supportato" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Solo un file può essere specificato con \"--files\" o \"--files0\"." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "La variabile d'ambiente %s contiene troppi argomenti" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Il supporto alla compressione è stato disabilitato in fase di compilazione" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Il supporto alla decompressione è stato disabilitato in fase di compilazione" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "La compressione di file lzip (.lz) non è supportata" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list viene ignorato a meno che si stia comprimendo in formato .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Con --format=raw è richiesto --suffix=.SUF a meno che non si scriva sullo standard output" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Il numero massimo di filtri è quattro" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Errore nell'opzione --filters%s=FILTRI:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Il limite dell'uso della memoria è troppo basso per l'impostazione del filtro dato." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "catena di filtri %u usata da --block-list ma non specificata con --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Non è consigliato usare un preset nella modalità raw." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Le opzioni esatte per i preset possono variare tra le versioni del software." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Il formato .lzma supporta solo il filtro LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 non può essere usato con il formato .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "La catena di filtri %u non è compatibile con --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Passaggio a modalità singolo thread poiché viene usato --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Opzioni non supportate nella catena di filtri %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Vengono usati fino a % thread." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Catena di filtri od opzioni del filtro non supportata" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "La decompressione necessita di %s MiB di memoria." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Ridotto il numero di thread da %s a %s per non eccedere il limite di utilizzo della memoria di %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Ridotto il numero di thread da %s a uno. Il limite automatico di uso di memoria di %s MiB è ancora superato. Necessari %s MiB di memoria. Si procede comunque." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Si è commutato alla modalità a thread singola per non eccedere il limite di utilizzo della memoria di %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Regolata la dimensione del dizionario LZMA%c da %s MiB a %s MiB per non superare il limite dell'uso della memoria di %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Regolata la dimensione del dizionario LZMA%c per --filters%u da %s MiB a %s MiB per non superare il limite dell'uso della memoria di %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Errore nel concatenare alla catena di filtri %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Errore nel creare una pipe: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() non riuscita: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: sembra che il file sia stato spostato, non viene rimosso" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: impossibile rimuovere: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: impossibile impostare il proprietario del file: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: impossibile impostare il gruppo del file: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: impossibile impostare i permessi del file: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: sincronizzazione del file non riuscita: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: sincronizzazione della cartella del file non riuscita: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Errore nel recuperare le flag di stato del file dallo standard input: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: è un collegamento simbolico, viene saltato" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: è una cartella, viene saltata" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: non è un file regolare, viene saltato" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: il file ha il bit setuid o setgid impostato, viene saltato" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: il file ha lo sticky bit impostato, viene saltato" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: il file di input ha più di un collegamento fisico, viene saltato" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Nome file vuoto, viene saltato" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Errore nel ripristinare le flag di stato sullo standard input: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Errore nel recuperare le flag di stato del file dallo standard output: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: apertura della cartella non riuscita: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: la destinazione non è un file regolare" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Errore nel ripristinare la flag O_APPEND sullo standard output: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: chiusura del file non riuscita: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: posizionamento non riuscito nel tentativo di creare un file sparso: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: errore di lettura: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: errore nel cercare nel file: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: fine del file inaspettata" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: errore di scrittura: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Disabilitata" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Quantità di memoria fisica (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Numero di thread del processore:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Compressione:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Decompressione:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Decompressione multi-thread:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Valori predefiniti per -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Informazioni hardware:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Limiti di utilizzo della memoria:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Stream:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blocchi:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Dimensione compressa:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Dimensione non compressa:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Rapporto:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Controllo:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Padding dello stream:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Memoria necessaria:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Dim. negli header:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Numero di file:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Stream" + +#: src/xz/list.c +msgid "Block" +msgstr "Blocco" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blocchi" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "" + +#: src/xz/list.c +msgid "CompSize" +msgstr "" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "TotalSize" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Rapporto" + +#: src/xz/list.c +msgid "Check" +msgstr "Controllo" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "" + +#: src/xz/list.c +msgid "Padding" +msgstr "Padding" + +#: src/xz/list.c +msgid "Header" +msgstr "Header" + +#: src/xz/list.c +msgid "Flags" +msgstr "Flag" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtri" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Nessuno" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Sconosc2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Sconosc3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Sconosc5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Sconosc6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Sconosc7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Sconosc8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Sconosc9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Sconosc11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Sconosc12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Sconosc13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Sconosc14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Sconosc15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: il file è vuoto" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: troppo piccolo per essere un file .xz valido" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr " Strm Blocc. Compresso Estratto Rapp. Contr Nome file" + +#: src/xz/list.c +msgid "Yes" +msgstr "Sì" + +#: src/xz/list.c +msgid "No" +msgstr "No" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Versione \"XZ Utils\" minima:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s file\n" +msgstr[1] "%s file\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Totali:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list funziona solamente con file .xz (--format=xz o --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Provare \"lzmainfo\" con i file .lzma." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list non è in grado di leggere dallo standard input" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: errore nel leggere i nomi dei file: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: fine dell'input durante la lettura dei nomi dei file non attesa" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: trovato carattere null durante la lettura dei nomi dei file; forse si intendeva usare \"--files0\" invece di \"--files\"?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "La compressione e la decompressione con --robot non sono ancora supportate." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Impossibile leggere i dati dallo standard input durante la lettura dei nomi dei file dallo standard input" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Errore interno (bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Impossibile stabilire i gestori dei segnali" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Nessun controllo d'integrità; l'integrità del file non viene verificata" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Tipo di controllo di integrità non supportato; l'integrità del file non viene verificata" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Limite di utilizzo della memoria raggiunto" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Formato di file non riconosciuto" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Opzioni non supportate" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "I dati compressi sono danneggiati" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Fine dell'input non attesa" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB di memoria sono richiesti. Il limite è disabilitato." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB di memoria sono richiesti. Il limite è %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: catena di filtri: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Provare \"%s --help\" per maggiori informazioni." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Errore nello stampare il testo di aiuto (codice di errore %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Utilizzo: %s [OPZIONE]... [FILE]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Comprime o decomprime i FILE nel formato .xz." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Gli argomenti obbligatori per le opzioni lunghe sono obbligatori anche per quelle brevi." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Modalità di operazione:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "forza compressione" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "forza decompressione" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "testa l'integrità del file compresso" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "elenca informazioni sui file .xz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Modificatori di operazioni:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "conserva (non eliminare) i file input" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "forza la sovrascrittura del file output e dei link (de)compressi" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "scrivere sullo standard output e non eliminare i file input" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "non sincronizzare il file output sul supporto di memoria prima di rimuovere il file input" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "decomprime solamente il primo stream e ignora silenziosamente eventuali rimanenti dati di input" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "non creare file sparsi durante la decompressione" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "usare il suffisso \".SUF\" sui file compressi" + +#: src/xz/message.c +msgid "FILE" +msgstr "FILE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "legge da FILE i nomi dei file da processare; se FILE viene omesso, i nomi dei file vengono letti dallo standard input; i nomi dei file devono essere terminati da un carattere \"a capo\"" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "come --files ma usa il carattere null come terminatore" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Formato file di base e opzioni di compressione:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMATO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "formato di file per codificare o decodificare; i valori possibili sono \"auto\" (il predefinito), \"xz\", \"lzma\", \"lzip\" e \"raw\"" + +#: src/xz/message.c +msgid "NAME" +msgstr "NOME" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "tipo di controllo di integrità: \"none\" (usare con cautela), \"crc32\", \"crc64\" (predefinito), oppure \"sha256\"" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "non verifica il codice di integrità quando decomprime" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "preset di compressione; predefinito è 6; prendere in considerazione l'utilizzo di memoria per comprimere *e* decomprimere prima di usare 7-9" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "tenta di migliorare il rapporto di compressione utilizzando più tempo di CPU; non cambia i requisiti di memoria in fase di decompressione" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "NUM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "Usa al massimo NUM thread: il valore predefinito è 0, che usa tanti thread quanti core la CPU ha a disposizione" + +#: src/xz/message.c +msgid "SIZE" +msgstr "DIM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "avvia un nuovo blocco .xz dopo ogni DIM byte di input; usare questo per impostare la dimensione del blocco durante la compressione con thread" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOCCHI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "inizia un nuovo blocco .xz dopo gli intervalli indicati (separati da virgole) di dati non compressi; opzionalmente, specifica il numero di una catena di filtri (0-9) seguito da \":\" prima della dimensione dei dati non compressi" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "durante la compressione, se sono passati più di NUM millisecondi dal flush precedente e la lettura di ulteriore input risulterebbe bloccata, viene eseguito il flush di tutti i dati pendenti" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "LIMITE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "imposta il limite di utilizzo memoria per compressione, decompressione, decompressione con thread, oppure tutte quante; LIMITE è in byte, % di RAM, oppure 0 per i valori predefiniti" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "se le impostazioni di compressione eccedono il limite di utilizzo della memoria, lancia un errore invece di utilizzare valori più piccoli" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Catena di filtri personalizzati per la compressione (alternative per l'utilizzo di preset):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTRI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "imposta la catena di filtri usando la sintassi delle stringhe di filtri liblzma; usare --filters-help per avere più informazioni" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "imposta catene di filtri addizionali usando la sintassi delle stringhe di filtri liblzma da usare con --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "mostra più informazioni sulla sintassi della stringa del filtro liblzma ed esce" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "OPZIONI" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "LZMA1 or LZMA2; OPZ is a comma-separated list of zero or more of the following options (valid values; default):" +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 o LZMA2; OPZIONI è una lista separata da virgole di zero o più delle seguenti opzioni (valori validi; predefinito):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "PRESET" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "reimposta le opzioni a un preset" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "Dimensione del dizionario" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "numero di bit di contesto per carattere" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "numero di bit di posizione per carattere" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "numero di bit di posizione" + +#: src/xz/message.c +msgid "MODE" +msgstr "MODALITÀ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "modalità di compressione" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "lunghezza ragionevole di una corrispondenza" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "cercatore di corrispondenze" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "massima profondità di ricerca; 0=automatico (predefinito)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "filtro BCJ x86 (32-bit e 64-bit)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "filtro BCJ ARM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "filtro BCJ ARM-Thumb" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "filtro BCJ ARM64" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "filtro BCJ PowerPC (solo big-endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "filtro BCJ IA-64 (Itanium)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "filtro BCJ SPARC" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "filtro BCJ RISC-V" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "OPZIONI valide per tutti i filtri BCJ:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "offset iniziale per le conversioni (predefinito=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Filtro delta; OPZIONI valide (valori validi; predefiniti):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "distanza tra i byte sottratti l'uno dall'altro" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Altre opzioni:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "sopprime gli avvertimenti; specificare due volte per sopprimere anche gli errori" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "prolisso; specificare due volte per ancora più prolisso" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "gli avvertimenti non influenzano lo stato d'uscita" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "usa messaggi analizzabili (utile per gli script)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "visualizza la quantità totale di RAM e il limite attuale attivo di utilizzo della memoria ed esce" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "mostra l'aiuto breve (elenca solo le opzioni base)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "mostra l'aiuto esteso ed esce" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "mostra l'aiuto breve ed esce" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "mostra l'aiuto esteso (elenca anche le opzioni avanzate)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "visualizza il numero di versione ed esce" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Senza FILE, o quando FILE è -, legge lo standard input." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Segnalare i bug a <%s> (in inglese o finlandese). Segnalare i bug di traduzione a ." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "Homepage di %s: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "*Questa è una versione di sviluppo non adatta per utilizzi in produzione.*" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Le catene di filtri sono impostate usando le opzioni --filters=FILTRI oppure --filters1=FILTRI... --filters9=FILTRI. Ogni filtro nella catena può essere separato da spazi o da \"--\". In alternativa si può specificare un preset %s al posto di una catena di filtri." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "I filtri supportati e le loro opzioni sono:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Le opzioni devono essere coppie \"nome=valore\" separate da virgole" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: nome opzione non valido" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "valore dell'opzione non valido" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Preset LZMA/LZMA2 non supportato: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "La somma di lc e lp non deve superare 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: il nome del file ha un suffisso sconosciuto, viene saltato" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: il file ha il suffisso \"%s\", viene saltato" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: suffisso del nome del file non valido" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Il valore non è un numero intero decimale non-negativo" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: suffisso del moltiplicatore non valido" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "I suffissi validi sono \"KiB\" (2^10), \"MiB\" (2^20), e \"GiB\" (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Il valore dell'opzione \"%s\" deve essere nell'intervallo [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "I dati compressi non possono essere letti da un terminale" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "I dati compressi non possono essere scritti su un terminale" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Utilizzo: %s [--help] [--version] [FILE]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Mostra le informazioni immagazzinate nella header del file .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Il file è troppo piccolo per essere un file .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Non è un file .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Scrittura sullo standard output non riuscita" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Errore sconosciuto" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Preset non supportato" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Flag nel preset non supportato" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Nome di opzione non valido" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Il valore dell'opzione non può essere vuoto" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Valore fuori scala" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Questa opzione non supporta alcun suffisso moltiplicatore" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Suffisso del moltiplicatore non valido (KiB, MiB, o GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Nome di filtro non valido" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Questo filtro non può essere usato nel formato .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Allocazione di memoria fallita" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Stringa vuota non ammessa, provare '6' se è necessario un valore predefinito" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Il numero massimo di filtri è quattro" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Nome del filtro mancante" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Catena di filtro non valida (manca \"lzma2\" al fondo?)" diff --git a/cpp/third_party/xz-5.8.3/po/ka.gmo b/cpp/third_party/xz-5.8.3/po/ka.gmo new file mode 100644 index 0000000000000000000000000000000000000000..a3573a11d7bcc32d044bdb43765e9d39a1cde8a1 GIT binary patch literal 46526 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 -+!3C4&Og9-%xY1NE$6B?{;a26j-8^=d9{&@ z;s!X|Pj zN`HAgtEtq$!Y|BbM%f&qfI%TgB9YSyP7<7^7(iS=LgujeXhBm98V1{z^gEK}mIbL( zzNt%#rNxYR$4nUC9*u#F1aO131;nb7@!`5;AcsDViL?h!K@j?QM>I|_v=^)arQk&5 zel9b#iP{OWyVJKf#3DI2ljY1}i@`fW5Zp{Zr0BPY5E5fzFy4`q&Qe{01Uwkh-@{+BVTaM?cuDh2;<>477?2}mJ%gD^a%xvkIqagl;XnMJSfOp*{bA> zIX3^Ua!^`DGddXH1=CKTZNAh{tPfkp#i8@twvRTC672yc7OP+nmCg_=`6XiCfpsYX zbWEL4moN%GU3|WAbn4EJ? zjtyP~JS)#=#xsj4s?<<-tl8PT!zQk6k)oZ~vx-WrM@pBe{aub?{kOaQYuUU?!vRyF z3{pZjIvds~*SjHcCw|J7QimTinNP|^TfvX{Hivb`F`Up%$iz_R8Xe%sR9hB?>`fR% zOJVgnJiTFqqDL+ubK?K>DT?c$G&_E9;JVuV`OmydWsC}x!wQI}(9MmJ--IANnG>aV z?TePsO3bjkiy-fDkgUtZo{E1siT?!&Jv9Q~IF}sywlpnKJVx{lSo`8A-Oi>yAw}O@ z@8zzGOQ-h4RtwI>jxQ53BY|qJw|5lkG6D5y#zq88vDZX&WTu;0bR6scA5x*`s6H$T z-!}@M%A`v}E0#ucW+6AzZG{eOmc{=@6;eI3%;0KB#FhjOLd0vdbQQ@$i zQK@U$r^8N!!ZH01tngqkq`b9fwnXgt&sqHk#Q&((r&HhWSu$3{zRk)~v0jhhXHK{5~|A1jHFMKsvga z);{ZE|Ah=HaFCG!C!%FUI4-lW4Y`T@ouCEP7lD{0Ee0(KQJ7vCk0gU+Mx$O$G}(Db zsYGwMG9*%VLOMQ>mVbHuLu?NkI6A)*?;>Ucc&Cd=A$bT104~g)K4#F;H4hod3#4O^ z1?pr~6bXtN*R%QY(1B}-Tp|&ICouleq9h=OddqI^6^LnbH$i%$^L-2JIOg4pwHb%K zsO^Uv%9Wgc8Ns&n2wSwg>ye!Y_9+aQf^nh3DBR0=@9>;LIe@)L=e}d+JNk|*>biMZ zJHK1OZ1o#xb$xpxbP_C`%yWbVauyL#mJMO#M1>9D%>aWj7M~_$`jsaXBG`brT1ZHX zy|0SP>>w-cZCAiJeV|z{DcsrTq->2#`Pz@RTvmlfpz#F zz5c(vgW|hu8`F;|I}uBXSh4D%eNber4W3gFr*Ld zF?#W#FHI->+_y)iu=TOxFwTPki;@W_id`|qeA|;bG7js1ZiiC9WZPGv*Xw*er?mAj zE<6~F@1g|sonSkp8!n{GZx|#Z@}dd?nIh+wz)5ZfN3`~zSmBcI9YLL*Y)QgX3kLxl z%}7F&w-T}qO~}c>d=qiv54Hx;hESe5+*zTQ^o4^BiSf#|j55Jowq~w2JDFn+>;Jju zPXHET5@^hC;8#WdOWvw z4#hYf;V@^AAp7BqK|_0f2xHK&dDP8C)>fVZfz)ma%OA!-8{P>Inu~o#@4mz`-vyNI z5lT{+*$Gq}qeL6DOd8)fKXniKKv0~abXy29*K!-|p`Yg%&ID4x(NRurOpTbiWMRX= zFuPxSCB{41m<44&CE$cX@kWLVM~)Z=a_S&dIzb|nQcn2sWX_8wMleZLs%(MSWW~)E z%{scl?mrn8h*Ru(pvPp3<9A!8a0SER&AaY$dWc3V(t%$Yg?(%Ra}oKWPUCSjl$f<+|^$oXk-}qLu|gPB=uP zv*v{_1^XA?=FT1H6jwcHWg79TC_{*B3(@XexSb})1_iXVru07w1%F!Qh+7y@=N z65&!9q7>=QIYDAIQCZnx2^q&AiR~YfaZOP`+w$}y`<%i(l0^oJ^nbvpFM`j>CY$H5 zS!J4r|JFU?->nI02SH@AWGXp5k|0m+T=@%gG8{WAUQpDYh@Mm_g_1L**bvhc1DeSU z8Dvf7sX91(q5kmi8N_oHH^$=;q8b zk;t~kvbG20!(-Omtq6mJQJy@Yp%Bw0lMqr+V5sB-7y&I)M=s74?DTPlRIDVDifb6q zh#FgH6u{ACdInYRq&t*8)VJzbCE?-mZj+76rQrsPqV8Z z@3v12DW>fpc`1nV-;v5@b%Mnh zn)#mwrsRnP9WK4hz)AyM_|q(okw*>|YkR-gPK95f3Nu9211uHSjxT$&h+`xsRxzEu z5+6<%;+c$52PRhDa%k46d5z$v5?x#LNNxy9Q8D}$1x9! zuC?I(E>`0>Gs(Yr330lPmcC`FZyMvS(3;uB*LUcC0c+xOq{9tTMr}~-xRP*DHb4}g zIh;Yn?-oKO$_}Enyy}PI4QXs*!ieJ4Cz68~9mU!v1I{p=m^-s zfp_N7Luuhsl?Nf*2L(D5hqO8&6>c=MqTnmjQ;3~lC%`1Kni&Wud(0nn4xD4@Ss_3W zrAWTDL0SkQ14czAi(w}z-p_)(izYHLN?`>%$}WSsW~9XqUmHR7eBVT~dl+?s4U`gq z*hMbY6gZqf|04A7WTvBmnUKg#SpEsN5L*^CI%VnHc!Vj!=R$Zm1|UFe3|cUqOx5+< zZF7ku5#o2U*n$A(4#a4W6OWLBu!3P;RdZX;TNKjF94KR+Fb`3(q)CG649eUqbD_IJ zr6D5_@-EKkQ$V_mdaN9hk&+?kc6{S3tc6t&3<_Q1*&{v64`hyYeTOLd!RnYv<|2g9 z$^)$k2!d9Gg0v2ooRd#zQEU|EQ?I<4>A(NzZ-88TebY^jhf`|FYqbj0v9jr^`YI6k!zE zLE7=)azS4wwBRuL-hOlDp-=Px9X1+L!JQelr2Qo=7{ON*pozxJwvEDqgqx$ljOokT zgC#(ptk=%M;^c)O^0TN`Bl7Dr-#z^($DS0iD07$xG2u~aHV4`;0}69l*u#BXm%Fhh z@*ELKujZXBZnTo9+0!5fGvb4jC^|o$n9s7eWYcnB$$?22-wB4CYn2!}bVD>>=KJKC z2_R~C_FI0YT>9@)P7a9*S6}265&EW~49+hWDiKBqpWZ@3p#cenA<)Bx*1RGttnRwv zO0gi|oN|k(g;_}zUAq#(ooQBuCR_lC?5V-sxoq|vy**`5>pM-TV=6ccV{!ArP=chx z2_rn4yyC)HI2=;;p)7oYeG?;~3x!UY1T#~UcJQ~Ur3crR#0q=V z|JA1>XHAW1D=HVJXHCtV#R?h)_0v@Bek47wSXXmD$SkrufT^%|AQ5IOVv{VK?3kCW>ST5gS?&)9Jh4>KV0?5RXO3JL z;597Kn~(*IK`|jG=R_=PC&*Ryd0_y84EtGLKLB%7L@yu+IcddvjHoHb z$PkvWc}J3cXk!a1;$^kmp0Wj;aVHX$OGL3Imn#aRk>8nxbV$zkM)+cR{7qEtEavtX zzlPdxH&JL`W>oB%(4xFH`WDSgL@XpQb<+0?EzB`!1O~)OvOzIc<}o=!fnLVIt?&*; zl3|0jFadpqZ|yKFz$D%~*-$OGOhR6ULqKkTsoBuVJX&#z?pb?6IdbkZ-F%3aC_sNE zgTgk_T>ugNV(eV`_2aSqT37dNJ+E);`Tbh^lI=^i@AM1$(R@L_#tZv3UPR;E9K`zh za+kTg{4=)w7MSoq-4{%4j^B&CNV6P9gcz<0N}BtJ${>$NiVs61*m#-7A_`b2cS5)k zHBh63tDFuZSiW(I)&J2G?F5t%w!d-8pBYMczFILz{y84+X8>srCoDxmNlP*x<`{@G z%+?82Eyj%doc8pQ^X1KZoZ3_V`-NV%Pr?Y{y8sInK-+92)e16K2-kB;lZsHjpdn+= zk{G^RH{h3ydu-t!HC_m{!CS5)5J_J)fbiUaj7D@N#&(#QceF)slE*n9cVL4~xX$lz zLO9GXY(9x4$rT$?)b!kT@QR@>I|r^|yH~a+BKDdTx(LdY@<(El-rxLz1AXx19acx; zI!o{%1YBZn<}9IwT)jIiuV>O7LIeKOUx?h|4nm6|q1?rYYb0}a^=x1cr8ji_QuGa_ zUy4RWIVHWJ>$jqV-l&I7Fh36B+!CUhVv%XNTCnvwn$T?#v{gi3WY#<`I)NIiDv1O^ zWus;RsNwmHXFlghglCut+hfT*K`1&)mo%3_g~{^>+!cSA3MN(zCUM!92SbNzn71A# zd8qp*uKynqDEr~;6X`Bz4N|VyC3k|s{Rrm}|EVMXuUY+$Ikz2d*W!l380zag*kP7` zj+=qe(0GG0M)}=Vj!{Fr5C(J*@b2KGPfV1+T!^fk-}EXb0*ciBhX0iSmRXgSG>eews`-R1>(6 z+!~V&?t~T;j@74JZ}Oo`h&8U~{{bO}B&8E3z5CJJqxU62AcjD(*uQe&d{lS`kt}H> z+FueqiFFl0^5UV)f(ZwgYcpiY9R(092ZAaCZh!%cJ~DNZOvUmIML~ptjLMe-t?af) z|KWYs9%+S3urpdmXCPoGMTnT&<&b`EogYbOIL#-nCRVSkn@VGttiXVbt&BAoghuo^ z&f!h4>5YB3=ig30MQ4y$u=!i;8`(Iw~wj zHZhQADy?>inAlccIH6W_STV~$!Z3-JNHEDPl`rN<2}{owzv6C_v7Q(s9}yWwiLr=Q z0tU46Pjma{Q~p!M*|Lb2Alb>Mxn%enxw^!$`{2tAw4^)ovifw>iU*}15=1jw5IXS* z+_Y=#%4qswmwytXf}xpNGH^n-O%~Z(PAWAXiz6q=%s1yU~xe9(&UVz z&4_k6JLM9?y#gZ#1am)dnUDK`z9~o#_QHuu0A@WhHK5`wfC}Wor!@YM7lv2>k&pt~ z3lJ*)TZoDffHLzX&fI_z1NpK)pGPNt=i?yj!uwGOulcw* zT1jO*-N`~*I(rQ%J4J@f2S&r%1C|kiodu2_5nu*U2wlRLL5y(zaj6ZpXG7CL;8K!B zS~jB`6frT&o2;0OaDuw_@sOhp`3OgN773p-w7Af!D4FoJGskj_e#F(Cs52O^zqVB9p2DV&&;d6Erab=P>+*S+#TKZ{!Qk<#b`M}1V= zSKml$pjnw$7LXvO0N9Mt`;Nc)7R+)4^@LAkkD#2{^_Vd1n+J+i)}ARYNS&TQrUM_s z8M-oQuD``6*Ue3aEX$WWP=;d&wzF_hBQCmj7d9w^XvK4!bomETFh>oZoDT(Y5EAwh z#}Uq7bLr;J__Bd?d&4!pXM)3*&(3ouhx`70m@IzLDyB^+>AjUA5adQa`vWpre87*` zw6=)TThDXmMFcuskdPe-980AE?I0xEch&!8dP<@{O3?M#gV3@gVDDO)eL)l&^wd>}_zf*}O7A3oDeTnm{2mv&}6^!nK2* zcdWo=S7Gv4h{(;D1i|D`8oKUH2xug+!O_ZMFqd(>M^vOPGD-2_)Y)#vi6i7*dYpvi2` zV;s)M4C8o)#s)IX_S8qr?*~ECCdQHo34Lr&-R0cDh46?iJu$_J3j<>_%jy4XcRieR zjlu`0pU3Z^HPGeiZvV-rAcFh-Zh}QX*pj@52cruX2qtKVtC@)htuvmbrJ#-8u)U+*qIKoj=kc`3rlcJQEcP@48bI{`|EKNM&8{RRYJOulw9v2Mk zWcoqMrev(ok0pb5dnGr9We3^d$5f01N!2OVUCtN?7v2$4Weu7Zn&C{MH76A%#46~4 z(DXqd>Qvqr=QCsoQ|ny`glK^Qie}q}o^7Zm1*ga2ubsbzB#6ymPCw!!3Su&c zcSd0tP9QDWgCv~Ls7N{yHH~DLvjr_}fi9+W_v%U$Vjw*;6cFK^bJa-t1few#9Ms`U zoBXM=%+*Ucabp;JG+iOxtqC&6{0rv62{41YjAYJIF3hKibIVO!XGJU1dqJ-5i8-qw z&%mo3(6I^4s23Q_{0=QNi06q-adMoY3^s#BDaJGP6=V!V3`QX|{5zqK;l-w@98Qcb zhdeXO@viKNH-h0$yd{CLOPCxUcUjn!E10?D7ujqp6kfMU@QB?JT?Nyg2q`Kxr3Si= zB+>O5TNOw{ME(wjLBV4x#q%l?rj&nul?l#9rssOYPnDpLQn@gSU?k}Tb07oLF#tB_ zq<@lm#p#>d5IUjIjB73!UAP2YC@fPEOR!b(FQ?XEUQP z1d)$!2Y}OBS<4{nj4#V-dvx?Xrnb?1GY7G*)UveY8#VDZS^97t!*7?{q1p-WxWB%7nb znM5o(SQuT{D43J>KyPVAig_{9gBiN2xc<^%Mj6w00tH4u0i&66K_4N^o_9#v?6O?( z)Q}LPGq*gQQ8`bv8<^<8;a!o!HKWSW08fPpbPx%@bKOZY_ml%YYQ|W^H_^xtq6AkS zb&ixmp4>6;!0?4G34e1jTO70YSn;g`7q&5?!6CDERzEDTHg5=JE@gp>;kFZUMS+nX zLC~}qVrvHT(hFr)BSsek920P{o;Gi+;84PoG%-W=3-5&i&=}QGfI*xeWevNDY53M|JRLoq9gG7ic%H0LrHTpVfyr`H+F1wD`R zJM}R{1d72Qr4fx8u`_fPj8z#-v>d&GJip<;AL`X2|H*+=b94N=n6e&phiS0-J2rD z(HGP;A;`lx%57UY;E}-Msqml!eUdc`J6a?s*Y0C13gM&Re%f5OLp=nWGB=1jQ&*blI)M+jwIJqrrP08wd-%o z`tMrnzh4Zc+26(HFG8z}KPoy|<*S7JVd(3V?vO{O-l#`aJc6Woo^XlP`SK}Ub|Im{ U0C`y7J)QRs=Ks*wB!h1M8x~jUzyJUM literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/ka.po b/cpp/third_party/xz-5.8.3/po/ka.po new file mode 100644 index 000000000..748bf695a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/ka.po @@ -0,0 +1,1264 @@ +# SPDX-License-Identifier: 0BSD +# +# xz translation to Georgian. +# This file is published under the BSD Zero Clause License. +# Temuri Doghonadze , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-03-02 06:03+0100\n" +"Last-Translator: Temuri Doghonadze \n" +"Language-Team: Georgian <(nothing)>\n" +"Language: ka\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" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.5\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: --block-list -ის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ áƒáƒ áƒ’უმენტი" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: --block-list -ის მეტისმეტáƒáƒ“ ბევრი áƒáƒ áƒ’უმენტი" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "პáƒáƒ áƒáƒ›áƒ”ტრი --block-list ფილტრის ჯáƒáƒ­áƒ•ის ნáƒáƒ›áƒ áƒ˜áƒ¡ '%c' შემდეგ ბლáƒáƒ™áƒ˜áƒ¡ ზáƒáƒ›áƒ áƒáƒ™áƒšáƒ˜áƒ" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "ნული --block-list -ის მხáƒáƒšáƒáƒ“ ბáƒáƒšáƒ ელემენტი შეიძლებრიყáƒáƒ¡" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ ფáƒáƒ áƒ›áƒáƒ¢áƒ˜áƒ¡ უცნáƒáƒ‘ი ტიპი" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: სიმრთელის შემáƒáƒ¬áƒ›áƒ”ბის მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელი ტიპი" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "'--files' áƒáƒœ '--files0' -თáƒáƒœ ერთáƒáƒ“, მხáƒáƒšáƒáƒ“, ერთი ფáƒáƒ˜áƒšáƒ˜áƒ¡ მითითებრშეიძლებáƒ." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "გáƒáƒ áƒ”მáƒáƒ¡ ცვლáƒáƒ“ი %s მეტისმეტáƒáƒ“ ბევრ áƒáƒ áƒ’უმენტს შეიცáƒáƒ•ს" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "შეკუმშვის მხáƒáƒ áƒ“áƒáƒ­áƒ”რრგáƒáƒ›áƒáƒ áƒ—ულირáƒáƒ’ების დრáƒáƒ¡" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "გáƒáƒ¨áƒšáƒ˜áƒ¡ მხáƒáƒ áƒ“áƒáƒ­áƒ”რრგáƒáƒ›áƒáƒ áƒ—ულირáƒáƒ’ების დრáƒáƒ¡" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "შეკუმშვრlzip (.lz) ფáƒáƒ˜áƒšáƒ”ბისთვის მხáƒáƒ áƒ“áƒáƒ­áƒ”რილი áƒáƒ áƒáƒ" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "პáƒáƒ áƒáƒ›áƒ”ტრი --block-list გáƒáƒ›áƒáƒ¢áƒáƒ•ებულირიმ შემთხვევის გáƒáƒ áƒ“áƒ, თუ .xz ფáƒáƒ áƒ›áƒáƒ¢áƒ¡ იყენებთ" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "--format=raw -თáƒáƒœ ერთáƒáƒ“ --suffix=.SUF -ის მითითებრáƒáƒ£áƒªáƒ˜áƒšáƒ”ბელიáƒ, თუ stdout-ზე áƒáƒ  წერთ" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "ფილტრების მáƒáƒ¥áƒ¡áƒ˜áƒ›áƒáƒšáƒ£áƒ áƒ˜ რáƒáƒáƒ“ენáƒáƒ‘რáƒáƒ—ხის ტáƒáƒšáƒ˜áƒ" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Error პáƒáƒ áƒáƒ›áƒ”ტრში --filters%s=FILTERS:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "მითითებული ფილტრის გáƒáƒ›áƒáƒ¡áƒáƒ§áƒ”ნებლáƒáƒ“ მეხსიერების გáƒáƒ›áƒáƒ§áƒ”ნების ლიმიტი მეტისმეტáƒáƒ“ დáƒáƒ‘áƒáƒšáƒ˜áƒ." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "ფილტრების ჯáƒáƒ­áƒ•ი %u გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნებრპáƒáƒ áƒáƒ›áƒ”ტრით --block-list, მáƒáƒ’რáƒáƒ› áƒáƒ áƒáƒ მითითებული პáƒáƒ áƒáƒ›áƒ”ტრით --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "პრესეტის დáƒáƒ£áƒ›áƒ£áƒ¨áƒáƒ•ებელ რეჟიმში გáƒáƒ›áƒáƒ§áƒ”ნებრრეკáƒáƒ›áƒ”ნდებული áƒáƒ áƒáƒ." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "პრესეტების ზუსტი პáƒáƒ áƒáƒ›áƒ”ტრები ვერსიებს შáƒáƒ áƒ˜áƒ¡ იცვლებáƒ." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr ".lzma ფáƒáƒ áƒ›áƒáƒ¢áƒ¡ მხáƒáƒšáƒáƒ“ LZMA1 ფილტრს მხáƒáƒ áƒ“áƒáƒ­áƒ”რრგáƒáƒáƒ©áƒœáƒ˜áƒ" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1-ის გáƒáƒ›áƒáƒ§áƒ”ნებრ.შეუძლებელირxz ფáƒáƒ áƒ›áƒáƒ¢áƒ˜áƒ—" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "ფილტრების ჯáƒáƒ­áƒ•ი %u შეუთáƒáƒ•სებელირპáƒáƒ áƒáƒ›áƒ”ტრთáƒáƒœ --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "ერთნáƒáƒ™áƒáƒ“იáƒáƒœ რეჟიმზე გáƒáƒ“áƒáƒ áƒ—ვრ--flush-timeout -ის გáƒáƒ›áƒ" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელი პáƒáƒ áƒáƒ›áƒ”ტრები ფილტრის ჯáƒáƒ­áƒ•ში %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნებრმáƒáƒ¥áƒ¡áƒ˜áƒ›áƒ£áƒ› % ნáƒáƒ™áƒáƒ“ი." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელი ფილტრების ჯáƒáƒ­áƒ•ი áƒáƒœ ფილტრის პáƒáƒ áƒáƒ›áƒ”ტრები" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "გáƒáƒ¨áƒšáƒ˜áƒ¡áƒ—ვის სáƒáƒ­áƒ˜áƒ áƒáƒ %s მიბ მეხსიერებáƒ." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "ნáƒáƒ™áƒáƒ“ების რáƒáƒáƒ“ენáƒáƒ‘რშემცირდრ%s-დáƒáƒœ %s-ზე, რáƒáƒ› áƒáƒ  გáƒáƒ“áƒáƒ•áƒáƒªáƒ˜áƒšáƒ მეხსიერების შეზღუდვáƒáƒ¡ %s მიბ" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "ნáƒáƒ™áƒáƒ“ების რáƒáƒáƒ“ენáƒáƒ‘რშემცირდრ%s-დáƒáƒœ ერთáƒáƒ›áƒ“ე. áƒáƒ•ტáƒáƒ›áƒáƒ¢áƒ£áƒ áƒ˜ მეხსიერების გáƒáƒ›áƒáƒ§áƒ”ნების შეზღუდვრ%s მბ-ზე გáƒáƒ“áƒáƒªáƒ˜áƒšáƒ”ბულიáƒ. სáƒáƒ­áƒ˜áƒ áƒáƒ %s მიბ მეხსიერებáƒ. მáƒáƒ˜áƒœáƒª გáƒáƒ•áƒáƒ’რძელებ." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "გáƒáƒ“áƒáƒ•ერთე ერთნáƒáƒ™áƒáƒ“იáƒáƒœ რეჟიმში, რáƒáƒ› áƒáƒ  გáƒáƒ“áƒáƒ•áƒáƒªáƒ˜áƒšáƒ მეხსიერების ზღვáƒáƒ áƒ¡ %s მიბ" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "LZMA%c-ის ლექსიკáƒáƒœáƒ˜áƒ¡ ზáƒáƒ›áƒ შესწáƒáƒ áƒ“რ%s მიბ-დáƒáƒœ %s მიბ-ზე, რáƒáƒ› áƒáƒ  გáƒáƒ“áƒáƒ•áƒáƒ­áƒáƒ áƒ‘რმეხსიერების ლიმიტს, რáƒáƒ›áƒ”ლიც %s მიბ-ის ტáƒáƒšáƒ˜áƒ" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "LZMA%c-ის ლექსიკáƒáƒœáƒ˜áƒ¡ ზáƒáƒ›áƒ შესწáƒáƒ áƒ“რ--filters%u-სთვის %s მიბ-დáƒáƒœ %s მიბ-ზე, რáƒáƒ› áƒáƒ  გáƒáƒ“áƒáƒ•áƒáƒ­áƒáƒ áƒ‘რმეხსიერების ლიმიტს, რáƒáƒ›áƒ”ლიც %s მიბ-ის ტáƒáƒšáƒ˜áƒ" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "ფილტრების ჯáƒáƒ­áƒ•ზე %u შეცვლის შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "ფáƒáƒ˜áƒ¤áƒ˜áƒ¡ შექმნის შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() -ის შეცდáƒáƒ›áƒ: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: რáƒáƒ’áƒáƒ áƒª ჩáƒáƒœáƒ¡, ფáƒáƒ˜áƒšáƒ˜ გáƒáƒ“áƒáƒ¢áƒáƒœáƒ˜áƒšáƒ˜áƒ. áƒáƒ  წáƒáƒ•შლი" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: წáƒáƒ¨áƒšáƒ შეუძლებელიáƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ მფლáƒáƒ‘ელის დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ ჯგუფის დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ წვდáƒáƒ›áƒ”ბის დáƒáƒ§áƒ”ნების შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ სინქრáƒáƒœáƒ˜áƒ–áƒáƒªáƒ˜áƒ˜áƒ¡ შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის სინქრáƒáƒœáƒ˜áƒ–áƒáƒªáƒ˜áƒ˜áƒ¡ შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ სტáƒáƒ¢áƒ£áƒ¡áƒ˜áƒ¡ áƒáƒšáƒ›áƒ”ბი მიღების შეცდáƒáƒ›áƒ სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ შეყვáƒáƒœáƒ˜áƒ“áƒáƒœ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: სიმბმულიáƒ. გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ეáƒ, გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: ჩვეულებრივი ფáƒáƒ˜áƒšáƒ˜ áƒáƒ áƒáƒ. გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: ფáƒáƒ˜áƒšáƒ¡ setuid áƒáƒœ setgit ბიტი áƒáƒ¥áƒ•ს დáƒáƒ§áƒ”ნებული. გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: ფáƒáƒ˜áƒšáƒ¡ წებáƒáƒ•áƒáƒœáƒ˜ ბიტი áƒáƒ¥áƒ•ს. გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: შეყვáƒáƒœáƒ˜áƒš ფáƒáƒ˜áƒšáƒ¡ ერთზე მეტი მყáƒáƒ áƒ˜ ბმული გáƒáƒáƒ©áƒœáƒ˜áƒ. გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "ცáƒáƒ áƒ˜áƒ”ლი ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლი. გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "სტáƒáƒ¢áƒ£áƒ¡áƒ˜áƒ¡ áƒáƒšáƒ›áƒ”ბის áƒáƒ¦áƒ“გენის შეცდáƒáƒ›áƒ სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒš შეყვáƒáƒœáƒáƒ–ე: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ სტáƒáƒ¢áƒ£áƒ¡áƒ˜áƒ¡ áƒáƒšáƒ›áƒ”ბის მიღების შეცდáƒáƒ›áƒ სტáƒáƒœáƒ áƒáƒ áƒ¢áƒ£áƒšáƒ˜ გáƒáƒ›áƒáƒ¢áƒáƒœáƒ˜áƒ“áƒáƒœ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: სáƒáƒ¥áƒáƒ¦áƒáƒšáƒ“ის გáƒáƒ®áƒ¡áƒœáƒ˜áƒ¡ შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: სáƒáƒ›áƒ˜áƒ–ნე ჩვეულებრივი ფáƒáƒ˜áƒšáƒ˜ áƒáƒ áƒáƒ" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "O_APPEND áƒáƒšáƒ›áƒ˜áƒ¡ áƒáƒ¦áƒ“გენის შეცდáƒáƒ›áƒ სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒš გáƒáƒ›áƒáƒ¢áƒáƒœáƒáƒ–ე: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ დáƒáƒ®áƒ£áƒ áƒ•ის შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: გáƒáƒ“áƒáƒ®áƒ•ევის შეცდáƒáƒ›áƒ დáƒáƒ›áƒáƒ¢áƒ”ბითი ფáƒáƒ˜áƒšáƒ˜áƒ¡ შექმნის მცდელáƒáƒ‘ისáƒáƒ¡: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: წáƒáƒ™áƒ˜áƒ—ხვის შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ გáƒáƒ“áƒáƒ®áƒ•ევის შეცდáƒáƒ›áƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ მáƒáƒ£áƒšáƒáƒ“ნელი დáƒáƒ¡áƒáƒ¡áƒ áƒ£áƒšáƒ˜" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: ჩáƒáƒ¬áƒ”რის შეცდáƒáƒ›áƒ: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "გáƒáƒ›áƒáƒ áƒ—ულიáƒ" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "ფიზიკური მეხსიერების (RAM) რáƒáƒáƒ“ენáƒáƒ‘áƒ:" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "პრáƒáƒªáƒ”სáƒáƒ áƒ˜áƒ¡ ნáƒáƒ™áƒáƒ“ების რáƒáƒáƒ“ენáƒáƒ‘áƒ:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "შეკუმშვáƒ:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "გáƒáƒ¨áƒšáƒ:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "მრáƒáƒ•áƒáƒšáƒœáƒáƒ™áƒáƒ“იáƒáƒœáƒ˜ გáƒáƒ¨áƒšáƒ:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "ნáƒáƒ’ულისხმევი პáƒáƒ áƒáƒ›áƒ”ტრისთვის -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ áƒáƒžáƒáƒ áƒáƒ¢áƒ£áƒ áƒ˜áƒ¡ შესáƒáƒ®áƒ”ბ:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "მეხსიერების გáƒáƒ›áƒáƒ§áƒ”ნების შეზღუდვები:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "ნáƒáƒ™áƒáƒ“ები:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "ბლáƒáƒ™áƒ”ბი:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "შეკუმშული ზáƒáƒ›áƒ:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "შეუკუმშáƒáƒ•ი ზáƒáƒ›áƒ:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "პრáƒáƒžáƒáƒ áƒªáƒ˜áƒ”ბი:" + +#: src/xz/list.c +msgid "Check:" +msgstr "შემáƒáƒ¬áƒ›áƒ”ბáƒ:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "ნáƒáƒ™áƒáƒ“ის შევსებáƒ:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "სáƒáƒ­áƒ˜áƒ áƒáƒ მეხსიერებáƒ:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "ზáƒáƒ›áƒ თáƒáƒ•სáƒáƒ áƒ—ებში:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "ფáƒáƒ˜áƒšáƒ”ბის რáƒáƒáƒ“ენáƒáƒ‘áƒ:" + +#: src/xz/list.c +msgid "Stream" +msgstr "ნáƒáƒ™áƒáƒ“ი" + +#: src/xz/list.c +msgid "Block" +msgstr "ბლáƒáƒ™áƒ˜" + +#: src/xz/list.c +msgid "Blocks" +msgstr "ბლáƒáƒ™áƒ”ბი" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "შეკუმშწáƒáƒœáƒáƒªáƒ•ლ" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "შეუკუმშწáƒáƒœáƒáƒªáƒ•ლ" + +#: src/xz/list.c +msgid "CompSize" +msgstr "შეკუმშზáƒáƒ›áƒ" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "შეუკუმშზáƒáƒ›áƒ" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "ზáƒáƒ›áƒáƒ¡áƒ£áƒš" + +#: src/xz/list.c +msgid "Ratio" +msgstr "პრáƒáƒžáƒáƒ áƒªáƒ˜áƒ”ბი" + +#: src/xz/list.c +msgid "Check" +msgstr "შემáƒáƒ¬áƒ›áƒ”ბáƒ" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "მნიშვნშემáƒáƒ¬áƒ›" + +#: src/xz/list.c +msgid "Padding" +msgstr "შევსებáƒ" + +#: src/xz/list.c +msgid "Header" +msgstr "ზედრკáƒáƒšáƒáƒœáƒ¢áƒ˜áƒ¢áƒ£áƒšáƒ˜" + +#: src/xz/list.c +msgid "Flags" +msgstr "დრáƒáƒ¨áƒ”ბი" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "მეხსგáƒáƒ›áƒáƒ§" + +#: src/xz/list.c +msgid "Filters" +msgstr "ფილტრები" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "áƒáƒ áƒáƒ¤áƒ”რი" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "უცნáƒáƒ‘ი-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "უცნáƒáƒ‘ი-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "უცნáƒáƒ‘ი-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "უცნáƒáƒ‘ი-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "უცნáƒáƒ‘ი-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "უცნáƒáƒ‘ი-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "უცნáƒáƒ‘ი-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "უცნáƒáƒ‘ი-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "უცნáƒáƒ‘ი-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "უცნáƒáƒ‘ი-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "უცნáƒáƒ‘ი-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "უცნáƒáƒ‘ი-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜ ცáƒáƒ áƒ˜áƒ”ლიáƒ" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: მეტისმეტáƒáƒ“ პáƒáƒ¢áƒáƒ áƒáƒ, რáƒáƒ› სწáƒáƒ  .xz ფáƒáƒ˜áƒšáƒ¡ წáƒáƒ áƒ›áƒáƒáƒ“გენდეს" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "ნáƒáƒ™áƒáƒ“ები ბლáƒáƒ™áƒ”ბი შეკუმშული შეუკუმშáƒáƒ•ი ფáƒáƒ áƒ“áƒáƒ‘რშემáƒáƒ¬áƒ›áƒ”ბრფáƒáƒ˜áƒšáƒ¡ სáƒáƒ®áƒ”ლი" + +#: src/xz/list.c +msgid "Yes" +msgstr "დიáƒáƒ®" + +#: src/xz/list.c +msgid "No" +msgstr "áƒáƒ áƒ" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "მინიმáƒáƒšáƒ£áƒ áƒ˜ XZ Utils ვერსიáƒ:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s ფáƒáƒ˜áƒšáƒ˜\n" +msgstr[1] "%s ფáƒáƒ˜áƒšáƒ˜\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "ჯáƒáƒ›áƒ”ბი:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list მხáƒáƒšáƒáƒ“ .xz ფáƒáƒ˜áƒšáƒ”ბზე მუშáƒáƒáƒ‘ს (--format=xz áƒáƒœ --format=auto (áƒáƒ•ტáƒáƒ›áƒáƒ¢áƒ£áƒ áƒ˜))" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "სცáƒáƒ“ეთ 'lzmainfo' .lzma ფáƒáƒ˜áƒšáƒ”ბისთვის." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list -ს სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ შეყვáƒáƒœáƒ˜áƒ“áƒáƒœ წáƒáƒ™áƒ˜áƒ—ხვის მხáƒáƒ áƒ“áƒáƒ­áƒ”რრáƒáƒ  გáƒáƒáƒ©áƒœáƒ˜áƒ" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლების წáƒáƒ™áƒ˜áƒ—ხვის შეცდáƒáƒ›áƒ: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: შეყვáƒáƒœáƒ˜áƒ¡ მáƒáƒ£áƒšáƒáƒ“ნელი დáƒáƒ¡áƒáƒ¡áƒ áƒ£áƒšáƒ˜ ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლების კითხვისáƒáƒ¡" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლების კითხვისრáƒáƒ¦áƒ›áƒáƒ©áƒ”ნილირნულáƒáƒ•áƒáƒœáƒ˜ სიმბáƒáƒšáƒ. შეიძლებáƒ, '--files'-ის მáƒáƒ’იერ '--files0'-ის გáƒáƒ›áƒáƒ§áƒ”ნებრგნებáƒáƒ•დáƒáƒ—?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "--robot -áƒáƒœ ერთáƒáƒ“ შეკუმშვრდრგáƒáƒ¨áƒšáƒ ჯერჯერáƒáƒ‘ით მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელიáƒ." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "მáƒáƒœáƒáƒªáƒ”მების სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ შეყვáƒáƒœáƒ˜áƒ“áƒáƒœ წáƒáƒ™áƒ˜áƒ—ხვრმáƒáƒ¨áƒ˜áƒœ, რáƒáƒªáƒ ფáƒáƒ˜áƒšáƒ”ბის სáƒáƒ®áƒ”ლებიც სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ შეყვáƒáƒœáƒ˜áƒ“áƒáƒœ იკითხებáƒ, შეუძლებელიáƒ" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "შიდრშეცდáƒáƒ›áƒ (პრáƒáƒ’რáƒáƒ›áƒ გáƒáƒ¡áƒáƒ›áƒáƒ áƒ—იáƒ)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "სიგნáƒáƒšáƒ”ბის დáƒáƒ›áƒ›áƒ£áƒ¨áƒáƒ•ებლების დáƒáƒ›áƒ§áƒáƒ áƒ”ბის შეცდáƒáƒ›áƒ" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "სიმრთელის შემáƒáƒ¬áƒ›áƒ”ბის გáƒáƒ áƒ”შე. ფáƒáƒ˜áƒšáƒ˜áƒ¡ სიმრთელე áƒáƒ  შემáƒáƒ¬áƒ›áƒ“ებáƒ" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ სიმრთელის შემáƒáƒ¬áƒ›áƒ”ბის ხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელი ტიპი. ფáƒáƒ˜áƒšáƒ˜áƒ¡ სიმრთელე áƒáƒ  შემáƒáƒ¬áƒ›áƒ“ებáƒ" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "მეხსიერების გáƒáƒ›áƒáƒ§áƒ”ნების ლიმიტი მიღწეულიáƒ" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ ფáƒáƒ áƒ›áƒáƒ¢áƒ˜ უცნáƒáƒ‘იáƒ" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "მხáƒáƒ áƒ“áƒáƒ£áƒ¬áƒ”რელი პáƒáƒ áƒáƒ›áƒ”ტრები" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "შეკუმშული მáƒáƒœáƒáƒªáƒ”მები დáƒáƒ–იáƒáƒœáƒ”ბულიáƒ" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "შეყვáƒáƒœáƒ˜áƒ¡ მáƒáƒ£áƒšáƒáƒ“ნელი დáƒáƒ¡áƒáƒ¡áƒ áƒ£áƒšáƒ˜" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "სáƒáƒ­áƒ˜áƒ áƒáƒ %s მბ მეხსიერებáƒ. მსáƒáƒ–ღვრელი გáƒáƒ›áƒáƒ áƒ—ულიáƒ." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "სáƒáƒ­áƒ˜áƒ áƒáƒ %s მბ მეხსიერებáƒ. ზღვáƒáƒ áƒ˜áƒ: %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: ფილტრის ჯáƒáƒ­áƒ•ი: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "მეტი ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡áƒ—ვის სცáƒáƒ“ეთ '%s --help'." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "დáƒáƒ®áƒ›áƒáƒ áƒ”ბის ტექსტის გáƒáƒ›áƒáƒ¢áƒáƒœáƒ˜áƒ¡ შეცდáƒáƒ›áƒ (შეცდáƒáƒ›áƒ˜áƒ¡ კáƒáƒ“ირ%d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "გáƒáƒ›áƒáƒ§áƒ”ნებáƒ: %s [პáƒáƒ áƒáƒ›áƒ”ტრი].. [ფáƒáƒ˜áƒšáƒ˜]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "მითითებული ფáƒáƒ˜áƒšáƒ”ბის .xz ფáƒáƒ áƒ›áƒáƒ¢áƒ¨áƒ˜ შეკუმშვრáƒáƒœ გáƒáƒ¨áƒšáƒ." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "გრძელი პáƒáƒ áƒáƒ›áƒ”ტრების áƒáƒ£áƒªáƒ˜áƒšáƒ”ბელი áƒáƒ áƒ’უმენტები მáƒáƒ—ი მáƒáƒ™áƒšáƒ” ვáƒáƒ áƒ˜áƒáƒœáƒ¢áƒ”ბისთვისáƒáƒª სáƒáƒ•áƒáƒšáƒ“ებულáƒáƒ." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "áƒáƒžáƒ”რáƒáƒªáƒ˜áƒ˜áƒ¡ რეჟიმი:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "ნáƒáƒ«áƒáƒšáƒáƒ“ევი შეკუმშვáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "ნáƒáƒ«áƒáƒšáƒáƒ“ევი გáƒáƒ¨áƒšáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "შეკუმშული ფáƒáƒšáƒ˜áƒ¡ მთლიáƒáƒœáƒáƒ‘ის შემáƒáƒ¬áƒ›áƒ”ბáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ ჩáƒáƒ›áƒáƒ—ვლრ.xz ფáƒáƒ˜áƒšáƒ”ბის შესáƒáƒ®áƒ”ბ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "áƒáƒžáƒ”რáƒáƒªáƒ˜áƒ˜áƒ¡ მáƒáƒ“იფიკáƒáƒ¢áƒáƒ áƒ”ბი:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "შეყვáƒáƒœáƒ˜áƒ¡ ფáƒáƒ˜áƒšáƒ”ბის შენáƒáƒ áƒ©áƒ£áƒœáƒ”ბრ(áƒáƒ  წáƒáƒ¨áƒšáƒ)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "გáƒáƒ›áƒáƒ¢áƒáƒœáƒ˜áƒ¡ ფáƒáƒ˜áƒšáƒ˜áƒ¡ თáƒáƒ•ზე გáƒáƒ“áƒáƒ¬áƒ”რრდრბმულების შეკუმშვáƒ/გáƒáƒ¨áƒšáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒš გáƒáƒ›áƒáƒ¢áƒáƒœáƒáƒ–ე ჩáƒáƒ¬áƒ”რრდრშეყვáƒáƒœáƒ˜áƒšáƒ˜ ფáƒáƒ˜áƒšáƒ”ბი áƒáƒ  წáƒáƒ˜áƒ¨áƒšáƒ”ბáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "გáƒáƒ›áƒáƒ¢áƒáƒœáƒ˜áƒ¡ ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒªáƒáƒ•ის მáƒáƒ¬áƒ§áƒáƒ‘ილáƒáƒ‘áƒáƒ¡áƒ—áƒáƒœ სინქრáƒáƒœáƒ˜áƒ–áƒáƒªáƒ˜áƒ შეყვáƒáƒœáƒ˜áƒ¡ ფáƒáƒ˜áƒšáƒ˜áƒ¡ წáƒáƒ¨áƒšáƒáƒ›áƒ“ე áƒáƒ  მáƒáƒ®áƒ“ებáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "გáƒáƒ¨áƒšáƒ˜áƒ¡, მხáƒáƒšáƒáƒ“, პირველ ნáƒáƒ™áƒáƒ“ს დრჩუმáƒáƒ“ დáƒáƒáƒ˜áƒ’ნáƒáƒ áƒ”ბს დáƒáƒ áƒ©áƒ”ნილ შეყვáƒáƒœáƒ˜áƒš მáƒáƒœáƒáƒªáƒ”მებს" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "გáƒáƒ¨áƒšáƒ˜áƒ¡áƒáƒ¡ დáƒáƒ›áƒáƒ¢áƒ”ბითი ფáƒáƒ˜áƒšáƒ”ბი áƒáƒ  შეიქმნებáƒ" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "შეკუმშულ ფáƒáƒ˜áƒšáƒ”ბზე '.SUF' სუფიქსის გáƒáƒ›áƒáƒ§áƒ”ნებáƒ" + +#: src/xz/message.c +msgid "FILE" +msgstr "FILE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "დáƒáƒ¡áƒáƒ›áƒ£áƒ¨áƒáƒ•ებელი ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლების FILE-დáƒáƒœ წáƒáƒ™áƒ˜áƒ—ხვáƒ; თუ FILE მითითებული áƒáƒ áƒáƒ, ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლები სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ შეყვáƒáƒœáƒ˜áƒ“áƒáƒœ იქნებრწáƒáƒ™áƒ˜áƒ—ხული. ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლები ხáƒáƒ–ის გáƒáƒ“áƒáƒ¢áƒáƒœáƒ˜áƒ¡ სიმბáƒáƒšáƒáƒ—ი უნდრსრულდებáƒáƒ“ეს" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "--files-ის მსგáƒáƒ•სáƒáƒ“, მáƒáƒ’რáƒáƒ› ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის დáƒáƒ¡áƒáƒ¡áƒ áƒ£áƒšáƒ”ბლáƒáƒ“ ნულáƒáƒ•áƒáƒœáƒ˜ სიმბáƒáƒšáƒáƒ¡ გáƒáƒ›áƒáƒ§áƒ”ნებáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ ფáƒáƒ áƒ›áƒáƒ¢áƒ˜áƒ¡áƒ დრშეკუმშვის ძირითáƒáƒ“ი პáƒáƒ áƒáƒ›áƒ”ტრები:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "ფáƒáƒ áƒ›áƒáƒ¢áƒ˜" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "ფáƒáƒ˜áƒšáƒ˜áƒ¡ ფáƒáƒ áƒ›áƒáƒ¢áƒ˜ გáƒáƒ¡áƒáƒ¨áƒ˜áƒ¤áƒ áƒáƒ“ áƒáƒœ დáƒáƒ¡áƒáƒ¨áƒ˜áƒ¤áƒ áƒáƒ“. შესáƒáƒ«áƒšáƒ მნიშვნელáƒáƒ‘ებირ'auto' (ნáƒáƒ’ულიხმევი), 'xz', 'lzma', 'lzip' დრ'raw'" + +#: src/xz/message.c +msgid "NAME" +msgstr "სáƒáƒ®áƒ”ლი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "მთლიáƒáƒœáƒáƒ‘ის შემáƒáƒ¬áƒ›áƒ”ბის ტიპი: 'áƒáƒ áƒªáƒ”რთი' (გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნეთ ყურáƒáƒ“ღებით), 'crc32', 'crc64' (ნáƒáƒ’ულისხმევი), áƒáƒœ 'sha256'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "გáƒáƒ¨áƒšáƒ˜áƒ¡áƒáƒ¡ სიმრთელე áƒáƒ  შემáƒáƒ¬áƒ›áƒ“ებáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "შეკუმშვის პრესეტი. ნáƒáƒ’ულისხმებირ6; 7-9 მნიშვნელáƒáƒ‘ის მითითებáƒáƒ›áƒ“ე გáƒáƒ˜áƒ—ვáƒáƒšáƒ˜áƒ¡áƒ¬áƒ˜áƒœáƒ”თ შემკუმშáƒáƒ•ისრ*დáƒ* გáƒáƒ›áƒ¨áƒšáƒ”ლის მეხსიერების მáƒáƒ—ხáƒáƒ•ნები!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "CPU-ის მეტი დáƒáƒ¢áƒ•ირთვის ხáƒáƒ áƒ¯áƒ–ე შეკუმშვის დáƒáƒœáƒ˜áƒ¡ áƒáƒ¬áƒ”ვის ცდáƒ. áƒáƒ áƒ¥áƒ˜áƒ•ის გáƒáƒ¨áƒšáƒ˜áƒ¡áƒáƒ¡ მეხსიერების მáƒáƒ—ხáƒáƒ•ნები áƒáƒ  შეიცვლებáƒ" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "NUM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "გáƒáƒ›áƒáƒ§áƒ”ნებული იქნებრმáƒáƒ¥áƒ¡. NUM ნáƒáƒ™áƒáƒ“ი; ნáƒáƒ’ულისხმევი მნიშვნელáƒáƒ‘áƒáƒ 0, რáƒáƒª იყენებს იმდენ ნáƒáƒ™áƒáƒ“ს, რáƒáƒ›áƒ“ენი ბირთვიც áƒáƒ¥áƒ•ს პრáƒáƒªáƒ”სáƒáƒ áƒ¡" + +#: src/xz/message.c +msgid "SIZE" +msgstr "ზáƒáƒ›áƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "áƒáƒ®áƒáƒšáƒ˜ .xz ბლáƒáƒ™áƒ˜áƒ¡ დáƒáƒ¬áƒ§áƒ”ბრყáƒáƒ•ელი მითითებული ზáƒáƒ›áƒ˜áƒ¡ მიღწევისáƒáƒ¡. გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნეთ ეს, რáƒáƒ› დáƒáƒáƒ§áƒ”ნáƒáƒ— ბლáƒáƒ™áƒ˜áƒ¡ ზáƒáƒ›áƒ მრáƒáƒ•áƒáƒšáƒœáƒáƒ™áƒáƒ“იáƒáƒœáƒ˜ შეკუმშვისáƒáƒ¡" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "ბლáƒáƒ™áƒ”ბი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "დáƒáƒ˜áƒ¬áƒ§áƒ”ბრáƒáƒ®áƒáƒšáƒ˜ .xz ბლáƒáƒ™áƒ˜ მითითებული მძიმით გáƒáƒ›áƒáƒ§áƒáƒ¤áƒ˜áƒšáƒ˜ ინტერვáƒáƒšáƒ˜áƒ¡ გáƒáƒœáƒ›áƒáƒ•ლáƒáƒ‘áƒáƒ¨áƒ˜ შეუკუმშáƒáƒ•ი მáƒáƒœáƒáƒªáƒ”მების მიღების შემდეგ. áƒáƒ áƒáƒ¡áƒáƒ•áƒáƒšáƒ“ებულáƒáƒ“ შეგიძლიáƒáƒ— მიუთითáƒáƒ— ფილტრების ჯáƒáƒ­áƒ•ის ნáƒáƒ›áƒ”რი (0-9), რáƒáƒ›áƒ”ლსáƒáƒª '.' მáƒáƒ°áƒ§áƒ•ებრშეუკუმშáƒáƒ•ი მáƒáƒœáƒáƒªáƒ”მების ზáƒáƒ›áƒ˜áƒ¡ შემდეგ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "კáƒáƒ›áƒžáƒ áƒ”სიის დრáƒáƒ¡, თუ NUM მილიწáƒáƒ›áƒ–ე მეტი გáƒáƒ•იდრმáƒáƒ¡ შემდეგ, რáƒáƒª წინრფლეში დრმეტი შეყვáƒáƒœáƒ˜áƒ¡ წáƒáƒ™áƒ˜áƒ—ხვრდáƒáƒ‘ლáƒáƒ™áƒáƒ•ს, ყველრმáƒáƒ›áƒšáƒáƒ“ინე მáƒáƒœáƒáƒªáƒ”მი áƒáƒ›áƒáƒ˜áƒ¬áƒ£áƒ áƒ" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "ლიმიტი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "მეხსიერების ლიმიტის დáƒáƒ§áƒ”ნებრშეკუმშვისთვის, გáƒáƒ¨áƒšáƒ˜áƒ¡áƒ—ვის, მრáƒáƒ•áƒáƒšáƒœáƒáƒ™áƒáƒ“იáƒáƒœáƒ˜ გáƒáƒ¨áƒšáƒ˜áƒ¡áƒ—ვის, áƒáƒœ ყველáƒáƒ¡áƒ—ვის ლიმიტი მიეთითებრბáƒáƒ˜áƒ¢áƒ”ბში, RAM-ის %-ში, áƒáƒœ 0, ნáƒáƒ’ულისხმევი მნიშვნელáƒáƒ‘ის გáƒáƒ›áƒáƒ¡áƒáƒ§áƒ”ნებლáƒáƒ“" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "თუ შეკუმშვის პáƒáƒ áƒáƒ›áƒ”ტრი გáƒáƒ“áƒáƒ¡áƒªáƒ“ებრმეხსიერების გáƒáƒ›áƒáƒ§áƒ”ნების ლიმიტს, პáƒáƒ áƒáƒ›áƒ”ტრის შემცირების მáƒáƒ’იერ შეცდáƒáƒ›áƒ˜áƒ¡ გáƒáƒ›áƒáƒ¢áƒáƒœáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის ფილტრის ჯáƒáƒ­áƒ•ი შეკუმშვისთვის (პრესეტების გáƒáƒ›áƒáƒ§áƒ”ნების áƒáƒšáƒ¢áƒ”რნáƒáƒ¢áƒ˜áƒ•áƒ):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "ფილტრები" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "ფილტრების ჯáƒáƒ­áƒ•ის áƒáƒ¬áƒ§áƒáƒ‘რliblzma-ის ფილტრის პáƒáƒ áƒáƒ›áƒ”ტრის სინტáƒáƒ¥áƒ¡áƒ˜áƒ— მეტი ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡áƒ—ვის გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნეთ --filters-help" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "დáƒáƒ›áƒáƒ¢áƒ”ბითი ფილტრის ჯáƒáƒ­áƒ•ების დáƒáƒ§áƒ”ნებრliblzma-ის ფილტრის სინტáƒáƒ¥áƒ¡áƒ˜áƒ— --block-list პáƒáƒ áƒáƒ›áƒ”ტრით გáƒáƒ›áƒáƒ¡áƒáƒ§áƒ”ნებლáƒáƒ“" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "მეტი ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ›áƒáƒ¢áƒáƒœáƒ liblzma ფილტრის სტრიქáƒáƒœáƒ˜áƒ¡ სინტáƒáƒ¥áƒ˜áƒ¡ შესáƒáƒ®áƒ”ბ დრგáƒáƒ¡áƒ•ლáƒ" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "პáƒáƒ áƒáƒ›-ები" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 áƒáƒœ LZMA2. OPTS მძიმით გáƒáƒ›áƒáƒ§áƒáƒ¤áƒ˜áƒšáƒ˜ სიáƒáƒ ნული áƒáƒœ მეტი შემდეგი პáƒáƒ áƒáƒ›áƒ”ტრებიდáƒáƒœ (სწáƒáƒ áƒ˜ მნიშვნელáƒáƒ‘áƒ. ნáƒáƒ’ულიხმევი):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "პრე" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "პáƒáƒ áƒáƒ›áƒ”ტრების ჩáƒáƒ›áƒáƒ§áƒ áƒ პრესეტზე" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "ლექსიკáƒáƒœáƒ˜áƒ¡ ზáƒáƒ›áƒ" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "ლიტერáƒáƒšáƒ˜áƒ¡ კáƒáƒœáƒ¢áƒ”ქსტის ბიტების რáƒáƒáƒ“ენáƒáƒ‘áƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "ლიტერáƒáƒšáƒ˜áƒ¡ მდებáƒáƒ áƒ”áƒáƒ‘ის ბიტების რáƒáƒáƒ“ენáƒáƒ‘áƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "მდებáƒáƒ áƒ”áƒáƒ‘ის ბიტების რáƒáƒáƒ“ენáƒáƒ‘áƒ" + +#: src/xz/message.c +msgid "MODE" +msgstr "რეჟიმი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "შეკუმშვის რეჟიმი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "დáƒáƒ¤áƒáƒ áƒ›áƒáƒ¢áƒ”ბული დáƒáƒ›áƒ—ხვევის სიგრძე" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "დáƒáƒ›áƒ—ხვევის მძებნელი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "მáƒáƒ¥áƒ¡áƒ˜áƒ›áƒáƒšáƒ£áƒ áƒ˜ ძებნის სიღრმე. 0=áƒáƒ•ტáƒáƒ›áƒáƒ¢áƒ£áƒ áƒ˜ (ნáƒáƒ’ულისხმევი)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ ფილტრი (32-ბიტიáƒáƒœáƒ˜ დრ64-ბიტიáƒáƒœáƒ˜)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ ფილტრი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BCJ ფილტრი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ ფილტრი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ ფილტრი(მხáƒáƒšáƒáƒ“ მსხვილბáƒáƒšáƒáƒ˜áƒáƒœáƒ˜)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (Itanium) BCJ ფილტრი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ ფილტრი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ ფილტრი" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "სწáƒáƒ áƒ˜ პáƒáƒ áƒáƒ›áƒ”ტრები ყველრBCJ ფილტრისთვის:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "დáƒáƒ¬áƒ§áƒ”ბის წáƒáƒœáƒáƒªáƒ•ლებრგáƒáƒ“áƒáƒ§áƒ•áƒáƒœáƒ”ბისთვის (ნáƒáƒ’ულისხმევი=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "დელტრფილტრი. დáƒáƒ¨áƒ•ებული პáƒáƒ áƒáƒ›áƒ”ტრები (სწáƒáƒ áƒ˜ მნიშვნელáƒáƒ‘ები, ნáƒáƒ’ულისხმევი):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "დáƒáƒ¨áƒáƒ áƒ”ბრბáƒáƒ˜áƒ¢áƒ”ბს შáƒáƒ áƒ˜áƒ¡ გáƒáƒ›áƒáƒáƒ™áƒšáƒ“ებრერთმáƒáƒœáƒ”თს" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "სხვრპáƒáƒ áƒáƒ›áƒ”ტრები:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "გáƒáƒ¤áƒ áƒ—ხილებების დáƒáƒ“უმებáƒ. შეცდáƒáƒ›áƒ”ბის დáƒáƒ¡áƒáƒ›áƒáƒšáƒáƒ“ მიუთითეთ áƒáƒ áƒ¯áƒ”რ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "მეტი შეტყáƒáƒ‘ინების გáƒáƒ›áƒáƒ¢áƒáƒœáƒ. უფრრმეტი შეტყáƒáƒ‘ინებისთვის მიუთითეთ áƒáƒ áƒ¯áƒ”რ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "გáƒáƒ¤áƒ áƒ—ხილებებს გáƒáƒ¡áƒ•ლის სტáƒáƒ¢áƒ£áƒ¡áƒ–ე გáƒáƒ•ლენრáƒáƒ  ექნებáƒáƒ—" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "მáƒáƒœáƒ¥áƒáƒœáƒ˜áƒ¡áƒ—ვის დáƒáƒ›áƒ£áƒ¨áƒáƒ•ებáƒáƒ“ი შეტყáƒáƒ‘ინებები (სკრიპტებისთვის)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "მეხსიერების ჯáƒáƒ›áƒ£áƒ áƒ˜ რáƒáƒáƒ“ენáƒáƒ‘ის დრáƒáƒ›áƒŸáƒáƒ›áƒáƒ“ áƒáƒ¥áƒ¢áƒ˜áƒ£áƒ áƒ˜ მეხსიერების ლიმიტების გáƒáƒ›áƒáƒ¢áƒáƒœáƒ დრგáƒáƒ¡áƒ•ლáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "მáƒáƒ™áƒšáƒ” დáƒáƒ®áƒ›áƒáƒ áƒ”ბის ჩვენებრ(მხáƒáƒšáƒáƒ“, ძირითáƒáƒ“ი პáƒáƒ áƒáƒ›áƒ”ტრები)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "გრძელი დáƒáƒ®áƒ›áƒáƒ áƒ”ბის ჩვენებრდრგáƒáƒ¡áƒ•ლáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "áƒáƒ› მáƒáƒ™áƒšáƒ” დáƒáƒ®áƒ›áƒáƒ áƒ”ბის ჩვენებრდრგáƒáƒ¡áƒ•ლáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "უფრრგრძელი დáƒáƒ®áƒ›áƒáƒ áƒ”ბის ჩვენებრ(áƒáƒ¡áƒ”ვე ნáƒáƒ©áƒ•ენები ქნებრდáƒáƒ›áƒáƒ¢áƒ”ბითი პáƒáƒ áƒáƒ›áƒ”ტრებიც)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "ვერსიის ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ ჩვენებრდრგáƒáƒ¡áƒ•ლáƒ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "რáƒáƒªáƒ ფáƒáƒ˜áƒšáƒ˜ áƒáƒ  áƒáƒ áƒ¡áƒ”ბáƒáƒ‘ს áƒáƒœ '-'-იáƒ, წáƒáƒ™áƒ˜áƒ—ხვრstdin-დáƒáƒœ მáƒáƒ®áƒ“ებáƒ." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "შეცდáƒáƒ›áƒ”ბის შესáƒáƒ®áƒ”ბ მიწერეთ <%s> (ინგლისურáƒáƒ“, áƒáƒœ ფინურáƒáƒ“)." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "%s-ის სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ˜ გვერდიáƒ: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ეს სáƒáƒ¢áƒ”სტრვერსიáƒáƒ. ნუ გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნებთ ყáƒáƒ•ელდღიური მáƒáƒ®áƒ›áƒáƒ áƒ”ბისთვის." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "ფილტრის ჯáƒáƒ­áƒ•ების დáƒáƒ§áƒ”ნებრ--filters=ფილტრები áƒáƒœ --filters1=ფილტრები... --filters9=ფილტრები პáƒáƒ áƒáƒ›áƒ”ტრებით ხდებáƒ. თითáƒáƒ”ული ფილტრი áƒáƒ› ჯáƒáƒ­áƒ•ში ერთმáƒáƒœáƒ”თისგáƒáƒœ ჰáƒáƒ áƒ”ებით, áƒáƒœ '--'-ითáƒáƒ გáƒáƒ›áƒáƒ§áƒáƒ¤áƒ˜áƒšáƒ˜. áƒáƒ¡áƒ”ვე შეგიძლიáƒáƒ— მიუთითáƒáƒ— პრესეტი %s ფილტრის ჯáƒáƒ­áƒ•ის მáƒáƒ’იერ." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "მხáƒáƒ áƒ“áƒáƒ­áƒ”რელი ფილტრები დრმáƒáƒ— პáƒáƒ áƒáƒ›áƒ”ტრებიáƒ:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "პáƒáƒ áƒáƒ›áƒ”ტრები უნდრწáƒáƒ áƒ›áƒáƒáƒ“გენდეს \"სáƒáƒ®áƒ”ლი=მნიშვნელáƒáƒ‘áƒ\" ტიპის წყვილებს, მძიმეებით გáƒáƒ›áƒáƒ§áƒáƒ¤áƒ˜áƒšáƒ¡" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ პáƒáƒ áƒáƒ›áƒ”ტრის სáƒáƒ®áƒ”ლი" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ პáƒáƒ áƒáƒ›áƒ”ტრის მნიშვნელáƒáƒ‘áƒ" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელი LZMA1/LZMA2 პრესეტი: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "\"lc\" დრ\"lp\"-ის ჯáƒáƒ›áƒ˜ 4-ზე მეტი áƒáƒ  უნდრიყáƒ" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის უცნáƒáƒ‘ი სუფიქსი. გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: ფáƒáƒ˜áƒšáƒ¡ სუფიქსი `%s' უკვე გáƒáƒáƒ©áƒœáƒ. გáƒáƒ›áƒáƒ¢áƒáƒ•ებáƒ" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ სუფიქსი" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "მნიშვნელáƒáƒ‘რáƒáƒ áƒáƒ£áƒáƒ áƒ§áƒáƒ¤áƒ˜áƒ— მთელ რიცხვს áƒáƒ  წáƒáƒ áƒ›áƒáƒáƒ“გენს" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ მáƒáƒ›áƒ áƒáƒ•ლის სუფიქსი" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "სწáƒáƒ áƒ˜ სუფიქსებირ`KiB' (2^10), `MiB' (2^20) დრ`GiB' (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "პáƒáƒ áƒáƒ›áƒ”ტრის (%s) მნიშვნელáƒáƒ‘ის დáƒáƒ¡áƒáƒ¨áƒ•ები დიáƒáƒžáƒáƒ–áƒáƒœáƒ˜áƒ [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "შეკუმშული მáƒáƒœáƒáƒªáƒ”მების ტერმინáƒáƒšáƒ˜áƒ“áƒáƒœ წáƒáƒ™áƒ˜áƒ—ხვრშეუძლებელიáƒ" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "შეკუმშული მáƒáƒœáƒáƒªáƒ”მების ტერმინáƒáƒšáƒ¨áƒ˜ ჩáƒáƒ¬áƒ”რრშეუძლებელიáƒ" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "გáƒáƒ›áƒáƒ§áƒ”ნებáƒ: %s [--help] [--version] [ფáƒáƒ˜áƒšáƒ˜]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr ".lzma ფáƒáƒ˜áƒšáƒ˜áƒ¡ თáƒáƒ•სáƒáƒ áƒ—ში შენáƒáƒ®áƒ£áƒšáƒ˜ ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ ჩვენებáƒ." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "%s: მეტისმეტáƒáƒ“ პáƒáƒ¢áƒáƒ áƒáƒ, რáƒáƒ› სწáƒáƒ  .xz ფáƒáƒ˜áƒšáƒ¡ წáƒáƒ áƒ›áƒáƒáƒ“გენდეს" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "áƒáƒ  წáƒáƒ áƒ›áƒáƒáƒ“გენს .lzma ფáƒáƒ˜áƒšáƒ¡" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "სტáƒáƒœáƒ“áƒáƒ áƒ¢áƒ£áƒšáƒ˜ გáƒáƒ›áƒáƒ¢áƒáƒœáƒáƒ¨áƒ˜ ჩáƒáƒ¬áƒ”რის შეცდáƒáƒ›áƒ" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "უცნáƒáƒ‘ი შეცდáƒáƒ›áƒ" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელი პრესეტი" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "მხáƒáƒ áƒ“áƒáƒ£áƒ­áƒ”რელი áƒáƒšáƒáƒ›áƒ˜ პრესეტში" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "უცნáƒáƒ‘ი პáƒáƒ áƒáƒ›áƒ”ტრის სáƒáƒ®áƒ”ლი" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "პáƒáƒ áƒáƒ›áƒ”ტრი ცáƒáƒ áƒ˜áƒ”ლი ვერ იქნებáƒ" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "მნიშვნელáƒáƒ‘რდიáƒáƒžáƒáƒ–áƒáƒœáƒ¡ გáƒáƒ áƒ”თáƒáƒ" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "áƒáƒ› პáƒáƒ áƒáƒ›áƒ”ტრს გáƒáƒ›áƒáƒ›áƒ áƒáƒ•ლებელი სუფიქსების მხáƒáƒ áƒ“áƒáƒ­áƒ”რრáƒáƒ  გáƒáƒáƒ©áƒœáƒ˜áƒ" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ მულტიპლიკáƒáƒ¢áƒáƒ áƒ˜áƒ¡ სუფიქსი (KiB, MiB áƒáƒœ GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "ფილტრის უცნáƒáƒ‘ი სáƒáƒ®áƒ”ლი" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "áƒáƒ› ფილტრს .xz ფáƒáƒ áƒ›áƒáƒ¢áƒ¨áƒ˜ ვერ გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნებთ" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "მეხსიერების გáƒáƒ›áƒáƒ§áƒáƒ¤áƒ˜áƒ¡ შეცდáƒáƒ›áƒ" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "ცáƒáƒ áƒ˜áƒ”ლი სტრიქáƒáƒœáƒ˜ დáƒáƒ£áƒ¨áƒ•ებელიáƒ. სცáƒáƒ“ეთ '6', თუ ნáƒáƒ’ულისხმევი მნიშვნელáƒáƒ‘რგჭირდებáƒáƒ—" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "ფილტრების მáƒáƒ¥áƒ¡áƒ˜áƒ›áƒáƒšáƒ£áƒ áƒ˜ რáƒáƒáƒ“ენáƒáƒ‘რáƒáƒ—ხის ტáƒáƒšáƒ˜áƒ" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "ფილტრის სáƒáƒ®áƒ”ლი მითითებული áƒáƒ áƒáƒ" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ფილტრის ჯáƒáƒ­áƒ•ი (ბáƒáƒšáƒáƒ¨áƒ˜ áƒáƒ™áƒšáƒ˜áƒ 'lzma2'?)" diff --git a/cpp/third_party/xz-5.8.3/po/ko.gmo b/cpp/third_party/xz-5.8.3/po/ko.gmo new file mode 100644 index 0000000000000000000000000000000000000000..4d7123e36aee93244356b11c9613600943349565 GIT binary patch literal 29850 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, 2019, 2022, 2023, 2024, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-01-24 23:22+0900\n" +"Last-Translator: Seong-ho Cho \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.5\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: --block-listì˜ ì¸ìžê°’ì´ ìž˜ëª»ë¨" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: --block-list ì¸ìž 갯수가 너무 ë§ŽìŒ" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "--block-listì—서 í•„í„° ì²´ì¸ ë²ˆí˜¸ '%c:' ë‹¤ìŒ ë¸”ë¡ í¬ê¸°ê°€ 빠졌습니다." + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 ê°’ì€ --block-listì˜ ë§ˆì§€ë§‰ ì›ì†Œë¡œë§Œ 사용할 수 있습니다" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: 알 수 없는 íŒŒì¼ í˜•ì‹" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: ì§€ì›í•˜ì§€ 않는 무결성 검사 형ì‹" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "'--files' ë˜ëŠ” '--files0' 옵션ì—는 í•˜ë‚˜ì˜ íŒŒì¼ë§Œ 지정할 수 있습니다." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "%s 환경 ë³€ìˆ˜ì— ë„ˆë¬´ ë§Žì€ ì¸ìž ê°’ì´ ë“¤ì–´ìžˆìŠµë‹ˆë‹¤" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "빌드 시ì ì— ì••ì¶• ê¸°ëŠ¥ì„ ë¹„í™œì„±í–ˆìŠµë‹ˆë‹¤" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "빌드 시ì ì— ì••ì¶• í•´ì œ ê¸°ëŠ¥ì„ ë¹„í™œì„±í–ˆìŠµë‹ˆë‹¤" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "lzip íŒŒì¼ (.lz) ì••ì¶•ì€ ì§€ì›í•˜ì§€ 않습니다" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr ".xz 형ì‹ìœ¼ë¡œ 압축하지 않으면 --block-list ì˜µì…˜ì€ ë¬´ì‹œí•©ë‹ˆë‹¤" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "표준 출력으로 기ë¡í•˜ì§€ 않는 한 --format=raw, --suffix=.<확장ìž> ì˜µì…˜ì´ í•„ìš”í•©ë‹ˆë‹¤" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "최대 í•„í„° 갯수는 4 입니다" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "--filters%s=<í•„í„°> 옵션 오류:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "주어진 í•„í„° 설정으로는 메모리 사용 제한 ê°’ì´ ë„ˆë¬´ ì ìŠµë‹ˆë‹¤." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "--block-liskì—서 í•„í„° ì²´ì¸ %uë²ˆì„ ì‚¬ìš©í•˜ê³  있지만 --filters%u= 옵션으로 지정하지 않았습니다" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "RAW 모드ì—ì„œì˜ í”„ë¦¬ì…‹ ì‚¬ìš©ì€ ê¶Œìž¥í•˜ì§€ 않습니다." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "í”„ë¦¬ì…‹ì˜ ì •í™•í•œ 옵션 ê°’ì€ í”„ë¡œê·¸ëž¨ ë²„ì „ì— ë”°ë¼ ë‹¤ë¦…ë‹ˆë‹¤." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr ".lzma 형ì‹ì€ LZMA1 í•„í„°ë§Œ ì§€ì›í•©ë‹ˆë‹¤" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr ".xz 형ì‹ì—는 LZMA1 필터를 사용할 수 없습니다" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "í•„í„° ì²´ì¸ %uë²ˆì´ --flush-timeout 옵션과 ë§žì§€ 않습니다" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "--flush-timeout ì˜µì…˜ì„ ì§€ì •í•˜ì˜€ìœ¼ë¯€ë¡œ ë‹¨ì¼ ìŠ¤ë ˆë“œ 모드로 전환합니다" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "í•„í„° ì²´ì¸ %u번ì—서 ì§€ì›í•˜ì§€ 않는 옵션" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "최대 스레드 %개를 사용합니다." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "ì§€ì›í•˜ì§€ 않는 í•„í„° ì²´ì¸ ë˜ëŠ” í•„í„° 옵션" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "ì••ì¶• 해제시 %s MiB 메모리 ìš©ëŸ‰ì´ í•„ìš”í•©ë‹ˆë‹¤." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "메모리 사용량 %s MiB ì œí•œì„ ë„˜ì§€ 않으려 스레드 수를 %s(ì—)서 %s(으)로 줄였습니다" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "스레드 수가 %s(ì—)서 하나로 줄었습니다. 메모리 사용 ìžë™ 제한량 %sMiB를 여전히 초과합니다. 메모리 공간 %sMiBê°€ 필요합니다. 어쨌든 계ì†í•©ë‹ˆë‹¤." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "메모리 사용 제한량 %sMiB를 넘지 않으려 ë‹¨ì¼ ìŠ¤ë ˆë“œ 모드로 전환합니다" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "메모리 사용 제한량 %4$sMiB를 넘지 않으려 %2$sMiBì—서 %3$sMiB로 LZMA%1$c 딕셔너리 í¬ê¸°ë¥¼ 조정했습니다" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "메모리 사용 제한량 %5$sMiB를 넘지 않으려 %3$sMiBì—서 %4$sMiB로 --filters%2$uì˜ LZMA%1$c 딕셔너리 í¬ê¸°ë¥¼ 조정했습니다" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "í•„í„° ì²´ì¸ %u번 전환 오류: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "파ì´í”„ ìƒì„± 오류: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() 실패: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: 파ì¼ì„ ì´ë™í•œ 것 ê°™ìŒ, 제거 안함" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: 제거할 수 ì—†ìŒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: íŒŒì¼ ì†Œìœ ìžë¥¼ 설정할 수 ì—†ìŒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: íŒŒì¼ ì†Œìœ  ê·¸ë£¹ì„ ì„¤ì •í•  수 ì—†ìŒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: íŒŒì¼ ê¶Œí•œì„ ì„¤ì •í•  수 ì—†ìŒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: íŒŒì¼ ë™ê¸°í™” 실패: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: 파ì¼ì˜ 디렉터리 ë™ê¸°í™” 실패: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "표준 ìž…ë ¥ì—서 íŒŒì¼ ìƒíƒœ 플래그 가져오기 오류: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: 심볼릭 ë§í¬, 건너뜀" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: 디렉터리입니다, 건너뜀" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: ì¼ë°˜ íŒŒì¼ ì•„ë‹˜, 건너뜀" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: setuid ë˜ëŠ” setgid 비트 설정 있ìŒ, 건너뜀" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: ëˆì ì´ 비트 ì„¤ì •ì´ ìžˆëŠ” 파ì¼, 건너뜀" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: ìž…ë ¥ 파ì¼ì— 하나 ì´ìƒì˜ 하드ë§í¬ê°€ 있습니다, 건너뜀" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "íŒŒì¼ ì´ë¦„ ì—†ìŒ, 건너뜀" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "표준 ìž…ë ¥ìœ¼ë¡œì˜ ìƒíƒœ 플래그 ë³µì› ì˜¤ë¥˜: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "표준 출력ì—서 íŒŒì¼ ìƒíƒœ 플래그 가져오기 오류: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: 디렉터리 열기 실패: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: 대ìƒì´ ì¼ë°˜ 파ì¼ì´ 아닙니다" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "표준 ì¶œë ¥ìœ¼ë¡œì˜ O_APPEND 플래그 ë³µì› ì˜¤ë¥˜: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: íŒŒì¼ ë‹«ê¸° 실패: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: ë¶„í•  íŒŒì¼ ìƒì„± 시ë„시 íƒìƒ‰ 실패: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: ì½ê¸° 오류: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: íŒŒì¼ íƒìƒ‰ 오류: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: 예ìƒì¹˜ 못한 파ì¼ì˜ ë" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: 쓰기 오류: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "사용 안함" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "물리 메모리 ì–‘ (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "프로세서 스레드 수:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "ì••ì¶•:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "ì••ì¶•í•´ì œ:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "멀티 스레드 ì••ì¶• í•´ì œ:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "-T0 기본값:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "하드웨어 ì •ë³´:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "메모리 사용 제한량:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "스트림:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "ë¸”ë¡ ìˆ˜:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "ì••ì¶• 용량:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "ì••ì¶•í•´ì œ 용량:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "압축율:" + +#: src/xz/list.c +msgid "Check:" +msgstr "검사:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "스트림 패딩:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "요구 메모리:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "í—¤ë” ê¸¸ì´:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "íŒŒì¼ ê°¯ìˆ˜:" + +#: src/xz/list.c +msgid "Stream" +msgstr "스트림" + +#: src/xz/list.c +msgid "Block" +msgstr "블ë¡" + +#: src/xz/list.c +msgid "Blocks" +msgstr "블ë¡" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "압축오프셋" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "압축해제오프셋" + +#: src/xz/list.c +msgid "CompSize" +msgstr "ì••ì¶•í¬ê¸°" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "ì••ì¶•í•´ì œí¬ê¸°" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "ì´í¬ê¸°" + +#: src/xz/list.c +msgid "Ratio" +msgstr "압축율" + +#: src/xz/list.c +msgid "Check" +msgstr "검사" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "검사값" + +#: src/xz/list.c +msgid "Padding" +msgstr "패딩" + +#: src/xz/list.c +msgid "Header" +msgstr "í—¤ë”" + +#: src/xz/list.c +msgid "Flags" +msgstr "플래그" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "메모리사용" + +#: src/xz/list.c +msgid "Filters" +msgstr "í•„í„°" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "ì—†ìŒ" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "알 수 ì—†ìŒ-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "알 수 ì—†ìŒ-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "알 수 ì—†ìŒ-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "알 수 ì—†ìŒ-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "알 수 ì—†ìŒ-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "알 수 ì—†ìŒ-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "알 수 ì—†ìŒ-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "알 수 ì—†ìŒ-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "알 수 ì—†ìŒ-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "알 수 ì—†ìŒ-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "알 수 ì—†ìŒ-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "알 수 ì—†ìŒ-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: íŒŒì¼ ë‚´ìš© ì—†ìŒ" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: 유효한 .xz 파ì¼ë¡œ 보기ì—는 너무 작습니다" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "스트림 ë¸”ë¡ ì••ì¶• ì••ì¶•í•´ì œ 압축율 검사 íŒŒì¼ ì´ë¦„" + +#: src/xz/list.c +msgid "Yes" +msgstr "예" + +# 주: 아니오가 ì•„ë‹ˆë¼ ì•„ë‹ˆìš”ê°€ 맞는 표현 +#: src/xz/list.c +msgid "No" +msgstr "아니요" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "최소 XZ 유틸리티 버전:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "íŒŒì¼ %sê°œ\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "ì´:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list ì˜µì…˜ì€ .xz 파ì¼ì—ë§Œ ë™ìž‘합니다(--format=xz ë˜ëŠ” --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "'lzmainfo' ëª…ë ¹ì— .lzma íŒŒì¼ ì´ë¦„ì„ ë¶™ì—¬ 실행해보십시오." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list ì˜µì…˜ì€ í‘œì¤€ ìž…ë ¥ ì½ê¸°ë¥¼ ì§€ì›í•˜ì§€ 않습니다" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: íŒŒì¼ ì´ë¦„ ì½ê¸° 오류: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: íŒŒì¼ ì´ë¦„ ì½ëŠ” 중 예ìƒì¹˜ 못한 ìž…ë ¥ ë" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: íŒŒì¼ ì´ë¦„ì„ ì½ëŠ” ë„중 NULL ë¬¸ìž ë°œê²¬. '--files' 옵션 대신 '--files0' ì˜µì…˜ì„ ì‚¬ìš©í•˜ì‹œë ¤ëŠ”ê²Œ 아닙니까?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "ì•„ì§ ì••ì¶• ë™ìž‘ê³¼ ì••ì¶• í•´ì œ ë™ìž‘ì— --robot ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않습니다." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "표준 출력ì—서 íŒŒì¼ ì´ë¦„ì„ ì½ì„ 때 표준 ìž…ë ¥ì—서 ë°ì´í„°ë¥¼ ì½ì„ 수 없습니다" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "ë‚´ë¶€ 오류 (버그)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "ì‹œê·¸ë„ ì²˜ë¦¬ìžë¥¼ 준비할 수 없습니다" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "무결성 검사 안함. íŒŒì¼ ë¬´ê²°ì„±ì„ ê²€ì¦í•˜ì§€ 않습니다" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "ì§€ì›í•˜ì§€ 않는 무결성 검사 형ì‹. íŒŒì¼ ë¬´ê²°ì„±ì„ ê²€ì¦í•˜ì§€ 않습니다" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "메모리 사용량 í•œê³„ì— ë„달했습니다" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "íŒŒì¼ í˜•ì‹ì„ ì¸ì‹í•  수 ì—†ìŒ" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "ì§€ì›í•˜ì§€ 않는 옵션" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "ì••ì¶• ë°ì´í„° 깨ì§" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "예ìƒì¹˜ 못한 ìž…ë ¥ ë" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB 메모리 ìš©ëŸ‰ì´ í•„ìš”í•©ë‹ˆë‹¤. ì œí•œì„ ë¹„í™œì„±í•©ë‹ˆë‹¤." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB 메모리 ìš©ëŸ‰ì´ í•„ìš”í•©ë‹ˆë‹¤. 제한 ìš©ëŸ‰ì€ %s 입니다." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: í•„í„° ì²´ì¸: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "ìžì„¸í•œ ì‚¬ìš©ë²•ì€ '%s --help'를 입력하십시오." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "ë„ì›€ë§ í…스트 출력 오류(오류 코드 %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "사용법: %s [옵션]... [파ì¼]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr ".xz 형ì‹ì˜ <파ì¼>로 압축하거나 ì••ì¶•ì„ í•´ì œí•©ë‹ˆë‹¤." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "긴 옵션 ë²„ì „ì˜ í•„ìˆ˜ ì¸ìžëŠ” ì§§ì€ ì˜µì…˜ì—ë„ í•´ë‹¹í•©ë‹ˆë‹¤." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "ë™ìž‘ ë°©ì‹:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "ê°•ì œ ì••ì¶•" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "ê°•ì œ ì••ì¶• í•´ì œ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "ì••ì¶• íŒŒì¼ ë¬´ê²°ì„±ì„ ì‹œí—˜í•©ë‹ˆë‹¤" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr ".xz 파ì¼ì— 대한 정보를 ë³´ì—¬ì¤ë‹ˆë‹¤" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "ë™ìž‘ 지정ìž:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "ìž…ë ¥ 파ì¼ì„ 그대로 둡니다 (ì‚­ì œ 안함)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "출력 파ì¼ì„ 강제로 ë®ì–´ì“°ê³  ë§í¬ ì••ì¶•ì„ ì§„í–‰(í•´ì œ)합니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "표준 ì¶œë ¥ì— ê¸°ë¡í•˜ê³  ìž…ë ¥ 파ì¼ì„ 삭제하지 않습니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "ìž…ë ¥ 파ì¼ì„ 제거하기 ì „ 저장 장치로 출력 파ì¼ì„ ë™ê¸°í™”하지 않습니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "첫 스트림 ì••ì¶•ë§Œ 해제하며, 가능한 나머지 ìž…ë ¥ ë°ì´í„°ëŠ” 무시합니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "ì••ì¶• 해제시 í¬ì†Œ 처리 파ì¼ì„ 만들지 않습니다" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "íŒŒì¼ ì••ì¶•ì‹œ 접미사를 '.SUF'로 사용합니다" + +#: src/xz/message.c +msgid "FILE" +msgstr "<파ì¼>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "<파ì¼>ì—서 처리할 íŒŒì¼ ì´ë¦„ì„ ì½ìŠµë‹ˆë‹¤. <파ì¼> ê°’ì„ ìƒëžµí•˜ë©´, 표준 입ㄹ겨ì—서 íŒŒì¼ ì´ë¦„ì„ ì½ì–´ë“¤ìž…니다. íŒŒì¼ ì´ë¦„ì€ ê°œí–‰ 문ìžë¡œ ë나야 합니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "--files와 비슷하나 ë„ ë¬¸ìžë¥¼ 종결 문ìžë¡œ 사용합니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "기본 íŒŒì¼ í˜•ì‹ ë° ì••ì¶• 옵션:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "<형ì‹>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "ì¸ì½”딩 ë˜ëŠ” 디코딩할 íŒŒì¼ í˜•ì‹ìž…니다. 사용할 수 있는 ê°’ì€ 'auto'(기본), 'xz', 'lzma', 'lzip', 'raw'ê°€ 있습니다" + +#: src/xz/message.c +msgid "NAME" +msgstr "<ì´ë¦„>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "무결성 검사 형ì‹: 'none'(ì‚¬ìš©ì— ìœ ì˜), 'crc32', 'crc64' (기본값), 'sha256'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "ì••ì¶• 해제시" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "ì••ì¶• 사전 설정. ê¸°ë³¸ê°’ì€ 6 입니다. 7-9를 사용하려면 ì••ì¶• 메모리 사용량*ê³¼* ì••ì¶• í•´ì œ 메모리 ì‚¬ìš©ëŸ‰ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "CPU ì ìœ  ì‹œê°„ì„ ë” í™•ë³´í•˜ì—¬ ì••ì¶•ë¥ ì„ ê°œì„ í•©ë‹ˆë‹¤. ì••ì¶• 해제시 메모리 요구 용량ì—는 ì˜í–¥ì„ 주지 않습니다" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "<숫ìž>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "최대 스레드 <개수>를 사용합니다. ê¸°ë³¸ê°’ì€ ì‹¤ì œ 프로세서 코어 수 ë§Œí¼ì˜ 스레드를 사용하ë„ë¡ ì§€ì •í•˜ëŠ” 0 값입니다" + +#: src/xz/message.c +msgid "SIZE" +msgstr "<í¬ê¸°>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "모든 <í¬ê¸°>ì˜ ìž…ë ¥ ë‹¤ìŒ ìƒˆ .xz 블ë¡ì„ 시작합니다. 스레드 ì••ì¶•ì˜ ë¸”ë¡ í¬ê¸°ë¥¼ 지정할 때 사용합니다" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "<블ë¡>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "콤마로 구분한 ì—°ì† ì§€ì •ê°’ ë§Œí¼ ì••ì¶• 해제한 ë°ì´í„° 용량 다ìŒ, 새 .xz 블ë¡ì„ 시작합니다. ì••ì¶• í•´ì œ ë°ì´í„° í¬ê¸° ì•žì— ì½œë¡ (':') 표기 후 í•„í„° ì²´ì¸ ë²ˆí˜¸(0-9)를 추가로 지정할 수 있습니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "압축하는 ë™ì•ˆ, ì´ì „ ë°ì´í„°ë¥¼ 플러싱한 후 ë” ë§Žì€ ë¸”ë¡ ìž…ë ¥ì„ ì½ì–´ë“¤ì¼ 때 <숫ìž> ë§Œí¼ì˜ 밀리초단위 ì œí•œì‹œê°„ì„ ë„˜ê¸°ë©´ 모든 대기 ë°ì´í„°ë¥¼ 소거합니다" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "<제한>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "ì••ì¶•, í•´ì œ, 스레드 ë¶„ì‚° ì••ì¶• í•´ì œ, ë˜ëŠ” 유사 ë™ìž‘ 수행시 메모리 사용량 ì œí•œì„ ì„¤ì •í•©ë‹ˆë‹¤. ë°”ì´íЏ 단위 <제한>ê°’, % 단위 RAM ì‚¬ìš©ëŸ‰ì„ ì§€ì •í•˜ë“ ì§€ 아니면 기본값으로 0ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "ì••ì¶• ì„¤ì •ì´ ë©”ëª¨ë¦¬ 사용량 ì œí•œì„ ë„˜ì–´ì„œë©´ 설정 ê°’ì„ ì¤„ì´ëŠ” 대신 오류 메시지를 나타냅니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "ì••ì¶•ìš© 개별 í•„í„° ì²´ì¸ ì„¤ì • (사전 설정 ì‚¬ìš©ì„ ëŒ€ì‹ í•¨):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "<í•„í„°>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "liblzma í•„í„° 문ìžì—´ 문법으로 í•„í„° ì²´ì¸ì„ 설정합니다. ìžì„¸í•œ 정보는 --filters-help ì˜µì…˜ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "--block-list ì˜µì…˜ì„ í•¨ê»˜ 사용할 수 있는 liblzma í•„í„° 문ìžì—´ 문법으로 추가 í•„í„° ì²´ì¸ì„ 설정합니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "liblzma í•„í„° 문ìžì—´ 문법 추가 정보를 나타낸 후 빠져나갑니다" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "<옵션>" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 ë˜ëŠ” LZMA2입니다. <옵션> ê°’ì€ ë‹¤ìŒê³¼ ê°™ì€ 0ê°œ ì´ìƒì˜ 쉼표 구분 값입니다 (유효한 ê°’. 기본값):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "<사전설정>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "사전 설정 값으로 옵션 재설정" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "딕셔너리 í¬ê¸°" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "ë³´ì´ëŠ” ëŒ€ë¡œì˜ ì»¨í…스트 비트 갯수" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "ë³´ì´ëŠ” ëŒ€ë¡œì˜ ìœ„ì¹˜ 비트 갯수" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "위치 비트 수" + +#: src/xz/message.c +msgid "MODE" +msgstr "<모드>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "ì••ì¶• 모드" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "ì¼ì¹˜í•˜ëŠ” í•­ëª©ì˜ nice 길ì´" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "ì¼ì¹˜ 항목 검색기" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "최대 검색 ê¹Šì´ ê°’. 0=ìžë™ (기본값)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ í•„í„° (32비트 ë° 64비트)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ í•„í„°" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BCJ í•„í„°" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ í•„ë”" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ í•„í„° (ë¹… 엔디안 ì „ìš©)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (ì•„ì´íƒœë‹ˆì—„) BCJ í•„í„°" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ í•„í„°" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ í•„í„°" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "모든 BCJ í•„í„°ì— ëŒ€í•œ ì ì ˆí•œ <옵션>ê°’:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "변환 시작 오프셋 ê°’ (기본값=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "ë¸íƒ€ í•„í„°. ì ì ˆí•œ <옵션> (ì ì ˆí•œ ê°’. 기본값):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "ë°”ì´íЏ ê°’ ì°¨ì´ ê±°ë¦¬" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "기타 옵션:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "경고문 숨김. ë” ë§Žì€ ì˜¤ë¥˜ 메시지를 숨가려면 ë‘번 지정하십시오" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "ìžì„¸í•˜ê²Œ 표시. ë” ìžì„¸í•˜ê²Œ 출력하려면 ë‘번 지정하십시오" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "경고가 종료 ìƒíƒœì— ì˜í–¥ì„ 주지 않게합니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "기계 í•´ì„ ê°€ëŠ¥í•œ 메시지를 사용합니다 (스í¬ë¦½íЏ 활용시 유용함)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "RAM ì´ ìš©ëŸ‰ê³¼ 현재 활성 메모리 사용 í•œê³„ê°’ì„ í‘œì‹œí•˜ê³  나갑니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "간단한 ë„ì›€ë§ í‘œì‹œ (기본 옵션만 표시)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "ì´ ê¸´ ë„움ë§ì„ 보여주고 나갑니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "ì´ ê°„ë‹¨í•œ ë„움ë§ì„ 보여주고 나갑니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "긴 ë„ì›€ë§ í‘œì‹œ (고급 ì˜µì…˜ë„ ë³´ì—¬ì¤ë‹ˆë‹¤)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "버전 번호를 표시하고 빠져나갑니다" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "<파ì¼> ê°’ì´ ì—†ê±°ë‚˜, <파ì¼> ê°’ì´ - 문ìžì´ë©´, 표준 ìž…ë ¥ì„ ì½ì–´ë“¤ìž…니다." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "<%s> (ì˜ë¬¸ ë˜ëŠ” 핀란드어)ì— ë²„ê·¸ë¥¼ 보고하십시오." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "%s 홈페ì´ì§€: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "!! ì£¼ì˜ !! 개발 버전ì´ë©° 실제 사용 ìš©ë„ê°€ 아닙니다." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" +"--filters=<í•„í„°> ë˜ëŠ” --filters1=<í•„í„°> ... --filters9=<í•„í„°> 옵션으로\n" +"í•„í„° ì²´ì¸ì„ 지정합니다. ì²´ì¸ì˜ ê° í•„í„°ëŠ” 공백 ë¬¸ìž ë˜ëŠ” '--'으로 구분할 수 있습니다.\n" +"í•„í„° ì²´ì¸ ëŒ€ì‹  %s 사전 설정 ê°’ì„ ì§€ì •í•  수 있습니다." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "ì§€ì›í•˜ëŠ” 필터와 ì˜µì…˜ì€ ë‹¤ìŒê³¼ 같습니다:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "ì˜µì…˜ì€ ì‰¼í‘œë¡œ 구분한 'ì´ë¦„=ê°’' ìŒì´ì–´ì•¼í•©ë‹ˆë‹¤" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: ìž˜ëª»ëœ ì˜µì…˜ ì´ë¦„" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "ìž˜ëª»ëœ ì˜µì…˜ ê°’" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "ì§€ì›í•˜ì§€ 않는 LZMA1/LZMA2 사전 설정: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "lcê°’ê³¼ lpê°’ì˜ í•©ì´ 4를 초과하면 안ë©ë‹ˆë‹¤" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: íŒŒì¼ ì´ë¦„ì— ì•Œ 수 없는 í™•ìž¥ìž ë¶™ìŒ, 건너뜀" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: 파ì¼ì— ì´ë¯¸ '%s' 확장ìžê°€ ë¶™ìŒ, 건너뜀" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: ìž˜ëª»ëœ íŒŒì¼ ì´ë¦„ 확장ìž" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "ê°’ì´ 10ì§„ ì–‘ì˜ ì •ìˆ˜ê°€ 아닙니다" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: ìž˜ëª»ëœ ìŠ¹ìˆ˜ 단위" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "사용할 수 있는 단위는 'KiB' (2^10), 'MiB' (2^20), 'GiB' (2^30) 입니다." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "'%s' 옵션 ê°’ì€ [%, %] 범위 ì•ˆì— ìžˆì–´ì•¼ 합니다" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "ì••ì¶• ë°ì´í„°ë¥¼ 터미ë„ì—서 ì½ì„ 수 없습니다" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "ì••ì¶• ë°ì´í„°ë¥¼ 터미ë„ì— ê¸°ë¡í•  수 없습니다" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "사용법: %s [--help] [--version] [<파ì¼>]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr ".lzma íŒŒì¼ í—¤ë”ì— ì €ìž¥í•œ 정보를 ë³´ì—¬ì¤ë‹ˆë‹¤." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr ".lzma 파ì¼ì´ê¸°ì—는 너무 작습니다" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr ".lzma 파ì¼ì´ 아닙니다" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "표준 출력 ê¸°ë¡ ì‹¤íŒ¨" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "알 수 없는 오류" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "ì§€ì›í•˜ì§€ 않는 사전 설정" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "ì§€ì›í•˜ì§€ 않는 사전 설정 플래그" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "알 수 없는 옵션 ì´ë¦„" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "옵션 ê°’ì„ ë¹„ì›Œë‘˜ 수 없습니다" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "ê°’ 범위 벗어남" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "ì´ ì˜µì…˜ì€ ë°°ìˆ˜ 단위 접미사를 ì§€ì›í•˜ì§€ 않습니다" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "ìž˜ëª»ëœ ë°°ìˆ˜ 단위 (KiB, MiB, ë˜ëŠ” GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "알 수 없는 íŒŒì¼ í˜•ì‹" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr ".xz 형ì‹ì— ì´ í•„í„°ë¥¼ 사용할 수 없습니다" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "메모리 할당 실패" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "빈 문ìžì—´ì„ 허용하지 않습니다. ê¸°ë³¸ê°’ì´ í•„ìš”í•˜ë‹¤ë©´ '6'ì„ ë„£ìœ¼ì‹­ì‹œì˜¤" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "최대 í•„í„° 갯수는 4 입니다" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "í•„í„° ì´ë¦„ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "ë¶€ì ì ˆí•œ í•„í„° ì²´ì¸ ('lzma2'를 ëºìŠµë‹ˆê¹Œ?)" diff --git a/cpp/third_party/xz-5.8.3/po/nl.gmo b/cpp/third_party/xz-5.8.3/po/nl.gmo new file mode 100644 index 0000000000000000000000000000000000000000..6f2c6756bbb1b98bd8a277721cc8badcfa45a213 GIT binary patch literal 28532 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/nl.po b/cpp/third_party/xz-5.8.3/po/nl.po new file mode 100644 index 000000000..4dc897f5e --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/nl.po @@ -0,0 +1,1269 @@ +# SPDX-License-Identifier: 0BSD +# +# Dutch translation for xz-utils. +# This file is published under the BSD Zero Clause License. +# +# "Wie soll ich wissen was ich meine bevor ich höre was ich sage." +# +# Benno Schulenberg , 2019, 2024, 2025. +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-01-25 15:51+0100\n" +"Last-Translator: Benno Schulenberg \n" +"Language-Team: Dutch \n" +"Language: nl\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" +"X-Bugs: Report translation errors to the Language-Team address.\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Ongeldig argument bij --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Te veel argumenten bij --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "Bij '--block-list' ontbreekt blokgrootte na filterketennummer '%c':" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "Bij '--block-list' kan '0' alleen het laatste element zijn" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Onbekend soort bestandsindeling" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Niet-ondersteund soort integriteitscontrole" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Slechts één bestand kan opgegeven worden met '--files' of '--files0'." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Omgevingsvariabele '%s' bevat te veel argumenten" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Compressie werd uitgeschakeld tijdens compilatie" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Decompressie werd uitgeschakeld tijdens compilatie" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Compressie van LZIP-bestanden (.lz) wordt niet ondersteund" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "'--block-list' wordt genegeerd (alleen geldig bij comprimeren naar .xz-indeling)" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Met '--format=raw' is optie '--suffix=.EXT' vereist (tenzij naar standaarduitvoer geschreven wordt)" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Het maximum aantal filters is vier" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Fout in optie '--filters%s=FILTERS':" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Geheugengebruiksgrens is te laag voor de gegeven filterconfiguratie." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "filterketen %u is gebruikt bij '--block-list' maar niet gegeven met '--filters%u='" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Gebruik van een voorinstelling in rauwe modus wordt ontraden." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "De precieze opties van de voorinstellingen kunnen variëren tussen programmaversies." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "De .lzma-indeling ondersteunt alleen het LZMA1-filter" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 kan niet gebruikt worden met de .xz-indeling" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Filterketen %u is niet compatibel met '--flush-timeout'" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Overgeschakeld naar enkeldraads modus wegens '--flush-timeout'" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Niet-ondersteunde opties in filterketen %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Tot % threads worden gebruikt." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Niet-ondersteunde filterketen of filteropties" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Decompressie heeft %s MiB aan geheugen nodig." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Aantal threads is gereduceerd van %s naar %s om de geheugengebruiksgrens van %s MiB niet te overschrijden" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Het aantal threads is gereduceerd van %s naar 1, maar de automatische geheugengebruiksgrens van %s MiB wordt alsnog overschreden. %s MiB aan geheugen is nodig. Toch doorgegaan." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Overgeschakeld naar enkeldraads modus, om de geheugengebruiksgrens van %s MiB niet te overschrijden" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Grootte van LZMA%c-woordenboek is aangepast van %s MiB naar %s MiB om de geheugengebruiksgrens van %s MiB niet te overschrijden" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Grootte van LZMA%c-woordenboek voor '--filters%u' is aangepast van %s MiB naar %s MiB om de geheugengebruiksgrens van %s MiB niet te overschrijden" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Fout bij overgaan naar filterketen %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Fout bij aanmaken van pijp: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() is mislukt: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "Bestand '%s' schijnt verplaatst te zijn -- niet verwijderd" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "Kan '%s' niet verwijderen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Kan bestandseigenaar niet instellen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Kan bestandsgroep niet instellen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Kan de toegangsrechten niet instellen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Synchroniseren van bestand is mislukt: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Synchroniseren van bestandsmap is mislukt: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Fout bij verkrijgen van de bestandstoestandsvlaggen van standaardinvoer: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Is een symbolische koppeling -- overgeslagen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Is een map -- overgeslagen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Is geen gewoon bestand -- overgeslagen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Bestand heeft SETUID- of SETGID-bit gezet -- overgeslagen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Bestand heeft 'sticky'-bit gezet -- overgeslagen" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Invoerbestand heeft meer dan één harde koppeling -- overgeslagen" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Lege bestandsnaam -- overgeslagen" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Fout bij herstellen van de bestandstoestandsvlaggen naar standaardinvoer: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Fout bij verkrijgen van de bestandstoestandsvlaggen van standaarduitvoer: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Openen van map is mislukt: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: Doel is geen gewoon bestand" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Fout bij herstellen van de 'O_APPEND'-vlag naar standaardinvoer: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Sluiten van bestand is mislukt: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: 'Seeken' is mislukt bij aanmaken van een bestand met gaten: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Leesfout: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Fout bij 'seeken': %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Onverwacht einde van bestand" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Schrijffout: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Uitgeschakeld" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Hoeveelheid fysiek geheugen (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Aantal processor-threads:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Compressie:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Decompressie:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Multi-threaded decompressie:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Default voor -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Hardware-informatie:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Geheugengebruiksgrenzen:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Streams:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blokken:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Gecomprimeerde grootte:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Ongecomprimeerde grootte:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Ratio:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Controle:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Stream-opvulling:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Benodigd geheugen:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Groottes in koppen:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Aantal bestanden:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Stream" + +#: src/xz/list.c +msgid "Block" +msgstr "Blok" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blokken" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "Gecomp.Start" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "Ongecomp.Start" + +#: src/xz/list.c +msgid "CompSize" +msgstr "Gecomp.Grootte" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "Ongecomp.Grootte" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "TotaleGrootte" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Ratio" + +#: src/xz/list.c +msgid "Check" +msgstr "Controle" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "Cont.waarde" + +#: src/xz/list.c +msgid "Padding" +msgstr "Vulling" + +#: src/xz/list.c +msgid "Header" +msgstr "Kop" + +#: src/xz/list.c +msgid "Flags" +msgstr "Vlaggen" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "Geh.geb." + +#: src/xz/list.c +msgid "Filters" +msgstr "Filters" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Geen" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Onbekend-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Onbekend-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Onbekend-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Onbekend-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Onbekend-8" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Onbekend-9" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Onbekend-10" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Onbekend-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Onbekend-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Onbekend-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Onbekend-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Onbekend-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Bestand is leeg" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Te klein om een geldig .xz-bestand te zijn" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Strms Blokkn Gecomprim. Ongecomprim. Ratio Contrle Bestandsnaam" + +#: src/xz/list.c +msgid "Yes" +msgstr "Ja" + +#: src/xz/list.c +msgid "No" +msgstr "Nee" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Minimale XZ-Utils-versie:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s bestand\n" +msgstr[1] "%s bestanden\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Totalen:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "'--list' werkt alleen voor .xz-bestanden (--format=xz of --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Probeer 'lzmainfo' met .lzma-bestanden." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "'--list' is niet mogelijk bij lezen van standaardinvoer" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Fout bij lezen van bestandsnamen: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Onverwacht einde van invoer tijdens lezen van bestandsnamen" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: NUL-teken gevonden bij lezen van bestandsnamen; misschien bedoelde u '--files0' i.p.v. '--files'?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Compressie en decompressie met '--robot' worden nog niet ondersteund." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Kan geen gegevens van standaardinvoer lezen wanneer bestandsnamen daarvan gelezen worden" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "** Interne fout (bug) **" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Kan signaalverwerkers niet instellen" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Geen integriteitscontrole -- bestandsintegriteit wordt niet gecontroleerd" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Niet-ondersteunde integriteitscontrole -- bestandsintegriteit wordt niet gecontroleerd" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Geheugengebruiksgrens is bereikt" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Bestandsindeling niet herkend" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Niet-ondersteunde opties" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Gecomprimeerde gegevens zijn beschadigd" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Onverwacht einde van invoer" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB aan geheugen is nodig. De begrenzer is uitgeschakeld." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB aan geheugen is nodig. De grens is %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Filterketen: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Typ '%s --help' voor meer informatie." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Fout bij tonen van hulptekst (foutcode %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Gebruikt: %s [OPTIE...] [BESTAND...]\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Comprimeert of decomprimeert BESTANDen in de .xz-indeling." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "(Een verplicht argument bij een lange optie geldt ook voor de korte vorm.)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr " Werkingsmodus:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "comprimeren" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "decomprimeren" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "integriteit van gecomprimeerd bestand controleren" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "informatie tonen over .xz-bestanden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Werkingsaanpassers:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "invoerbestanden behouden (niet verwijderen)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "uitvoerbestand overschrijven, koppelingen (de)comprimeren" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "naar standaarduitvoer schrijven, invoerbestanden behouden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "het uitvoerbestand niet met het opslagmedium synchroniseren alvorens het invoerbestand te verwijderen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "alleen de eerste stream decomprimeren, en stilzwijgend eventuele overige invoergegevens negeren" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "geen bestanden met gaten aanmaken bij het decomprimeren" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".EXT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "deze extensie gebruiken voor gecomprimeerde bestanden" + +#: src/xz/message.c +msgid "FILE" +msgstr "BESTAND" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "namen van te verwerken bestanden uit dit BESTAND halen; als BESTAND weggelaten wordt, dan worden de namen van standaardinvoer gelezen; elke naam moet afgesloten worden met een nieuweregelteken" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "zoals '--files' maar met het NUL-teken als naamsafsluiting" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Bestandsindeling- en compressie-opties:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "INDELING" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "te coderen of decoderen bestandsindeling; mogelijke waarden zijn 'auto' (standaard), 'xz', 'lzma', 'lzip', en 'raw'" + +#: src/xz/message.c +msgid "NAME" +msgstr "NAAM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "soort integriteitscontrole: 'none' (ontraden), 'crc32', 'crc64' (standaard), of 'sha256'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "geen integriteitscontrole doen tijdens decomprimeren" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "compressiegraad (standaard is 6); denk aan geheugengebruik van compressor *en* decompressor alvorens 7-9 te gebruiken" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "compressieratio verbeteren met meer processortijd; heeft geen invloed op het geheugengebruik bij decompressie" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "GETAL" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" +"maximaal dit aantal threads gebruiken; standaard is 0,\n" +"wat zoveel threads als er processorkernen zijn betekent" + +#: src/xz/message.c +msgid "SIZE" +msgstr "GROOTTE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "een nieuw .xz-blok beginnen na steeds dit aantal invoerbytes; gebruik dit om de blokgrootte voor threaded compressie in te stellen" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOKKEN" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "een nieuw .xz-blok beginnen na deze komma-gescheiden groottes van ongecomprimeerde gegevens; geef eventueel het filterketennummer op (0-9) gevolgd door ':' vóór een gegeven grootte" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "als tijdens compressie meer dan dit aantal milliseconden voorbijgegaan is sinds de vorige doorspoeling, en het lezen van meer gegevens zou blokkeren, dan alle wachtende gegevens doorspoelen" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "GRENS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "de geheugengebruiksgrens instellen voor compressie, decompressie, threaded decompressie, of allemaal; GRENS is in bytes, % van RAM, of 0 voor de standaardwaarden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "als compressie-instellingen de geheugengebruiksgrens overschrijden, een fout melden i.p.v. de instellingen te verlagen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Aangepaste filterketen voor compressie (een alternatief voor compressiegraden):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTERS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "de filterketen instellen met de liblzma-filtersyntax; gebruik '--filters-help' voor meer informatie" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "extra filterketens instellen met de liblzma-filtersyntax te gebruiken met '--block-list'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "meer informatie over de liblzma-filtersyntax tonen en stoppen" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "INSTEL" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 of LZMA2; INSTEL is een komma-gescheiden lijst van nul of meer van de volgende opties (geldige waarden; standaard):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "GRAAD" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "opties terugstellen op een voorinstelling" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "woordenboekgrootte" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "aantal contextbits per byte" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "aantal positiebits per byte" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "aantal positiebits" + +#: src/xz/message.c +msgid "MODE" +msgstr "MODUS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "compressiemodus" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "mooie lengte van overeenkomst" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "overeenkomstzoeker" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "maximum zoekdiepte; 0=automatisch (standaard)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ-filter (32-bit en 64-bit)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ-filter (alleen big endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (Itanium) BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "Geldige INSTEL voor alle BCJ-filters:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "beginpunt voor conversies (standaard=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Delta-filter; geldige INSTEL (geldige waarden; standaard):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "afstand tussen bytes die van elkaar afgetrokken worden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Andere opties:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "waarschuwingen onderdrukken; -q -q onderdrukt ook fouten" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "melden wat er gedaan wordt; -v -v geeft nog meer info" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "waarschuwingen de afsluitwaarde niet laten beïnvloeden" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "meldingen in machine-opmaak geven (nuttig voor scripts)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "de totale hoeveelheid RAM en de actieve geheugengebruiksgrenzen tonen en stoppen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "korte hulptekst tonen (met alleen basisopties)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "deze lange hulptekst tonen en stoppen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "deze korte hulptekst tonen en stoppen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "lange hulptekst tonen (met ook geavanceerde opties)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "versienummer tonen en stoppen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Zonder BESTAND, of wanneer BESTAND '-' is, wordt standaardinvoer gelezen." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"Rapporteer programmagebreken aan <%s> (in het Engels);\n" +"meld fouten in de vertaling aan ." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "Webpagina van %s: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "DIT IS een ONTWIKKELINGSVERSIE -- NIET BEDOELD voor WERKELIJK GEBRUIK." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Filterketens worden ingesteld met de opties '--filters=FILTERS' of '--filters1=FILTERS ... --filters9=FILTERS'. Elk filter in de keten kan gescheiden worden door spaties of '--'. In plaats van een filterketen kan ook een voorinstelling %s gegeven worden." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Ondersteunde filters en hun opties zijn:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Opties moeten 'naam=waarde'-paren zijn, gescheiden door komma's" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Ongeldige optienaam" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Ongeldige optiewaarde" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Niet-ondersteunde LZMA1/LZMA2-voorinstelling: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "De som van lc en lp mag niet groter zijn dan 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Bestand heeft onbekende extensie -- overgeslagen" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Bestand heeft al '%s'-extensie -- overgeslagen" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Ongeldige bestandsnaamextensie" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Waarde is geen niet-negatief tientallig geheel getal" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Ongeldig vermenigvuldigingsachtervoegsel" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Geldige achtervoegsels zijn 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Waarde van optie '%s' moet in het bereik [%, %] liggen" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Gecomprimeerde gegevens kunnen niet van een terminal gelezen worden" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Gecomprimeerde gegevens kunnen niet naar een terminal geschreven worden" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Gebruik: %s [--help] [--version] [BESTAND...]\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Toont informatie uit de .lzma-bestandskop." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Bestand is te klein om een .lzma-bestand te zijn" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Geen .lzma-bestand" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Schrijven naar standaarduitvoer is mislukt" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Onbekende fout" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Niet-ondersteunde voorinstelling" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Niet-ondersteunde vlag in voorinstelling" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Ongeldige optienaam" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Optiewaarde mag niet leeg zijn" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Waarde ligt buiten bereik" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Deze optie accepteert geen vermenigvuldigingsachtervoegsels" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Ongeldig vermenigvuldigingsachtervoegsel (KiB, MiB, of GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Onbekende filternaam" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Dit filter kan niet gebruikt worden met de .xz-indeling" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Onvoldoende geheugen beschikbaar" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Lege tekenreeks is niet toegestaan; probeer '6' als een standaardwaarde nodig is" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Het maximum aantal filters is vier" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Ontbrekende filternaam" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Ongeldige filterketen (ontbreekt 'lzma2' aan het eind?)" diff --git a/cpp/third_party/xz-5.8.3/po/pl.gmo b/cpp/third_party/xz-5.8.3/po/pl.gmo new file mode 100644 index 0000000000000000000000000000000000000000..93864523d4fe9984c447bf5a1fc2a5a196128c67 GIT binary patch literal 29090 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, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (الاسم)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "هذا دائماً هو السطر الأول عند البدء ÙÙŠ سرد ملÙ. العمود الثاني ÙÙŠ السطر هو اسم الملÙ." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (الملÙ)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "يحتوي هذا السطر على معلومات عامة حول مل٠B<.xz>. ÙŠÙØ·Ø¨Ø¹ هذا السطر دائماً بعد سطر B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (التدÙÙ‚)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "ÙŠÙØ³ØªØ®Ø¯Ù… نوع السطر هذا Ùقط عند تحديد B<--verbose>. يوجد من أسطر B بعدد التدÙقات الموجودة ÙÙŠ مل٠B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (الكتلة)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "ÙŠÙØ³ØªØ®Ø¯Ù… نوع السطر هذا Ùقط عند تحديد B<--verbose>. يوجد من أسطر B بعدد الكتل الموجودة ÙÙŠ مل٠B<.xz>. تظهر أسطر B بعد كل أسطر BØ› ولا تتداخل أنواع الأسطر Ø§Ù„Ù…Ø®ØªÙ„ÙØ©." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (الملخص)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "ÙŠÙØ³ØªØ®Ø¯Ù… نوع السطر هذا Ùقط عند تحديد B<--verbose> مرتين. ÙŠÙØ·Ø¨Ø¹ هذا السطر بعد كل أسطر B. مثل سطر BØŒ يحتوي سطر B على معلومات عامة حول مل٠B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (الإجماليات)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "هذا السطر هو دائماً السطر الأخير تماماً ÙÙŠ مخرجات القائمة. يعرض الأعداد والأحجام الإجمالية." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "أعمدة أسطر B:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "عدد التدÙقات ÙÙŠ الملÙ" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "إجمالي عدد الكتل ÙÙŠ التدÙÙ‚ (التدÙقات)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "الحجم المضغوط للملÙ" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "الحجم غير المضغوط للملÙ" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "نسبة الضغط، مثلاً B<0.123>. إذا كانت النسبة Ùوق 9.999ØŒ ØªÙØ¹Ø±Ø¶ ثلاث شرطات (B<--->) بدلاً من النسبة." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "قائمة Ù…ÙØµÙˆÙ„Ø© بÙواصل لأسماء ÙØ­ÙˆØµØ§Øª السلامة. ØªÙØ³ØªØ®Ø¯Ù… السلاسل التالية لأنواع Ø§Ù„ÙØ­Øµ Ø§Ù„Ù…Ø¹Ø±ÙˆÙØ©: BØŒ BØŒ BØŒ Ùˆ B. لأنواع Ø§Ù„ÙØ­Øµ غير Ø§Ù„Ù…Ø¹Ø±ÙˆÙØ©ØŒ ÙŠÙØ³ØªØ®Ø¯Ù… BIØŒ حيث I هو Ù…Ø¹Ø±Ù‘Ù Ø§Ù„ÙØ­Øµ كرقم عشري (رقم واحد أو رقمان)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "إجمالي حجم حشو التدÙÙ‚ ÙÙŠ الملÙ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "أعمدة أسطر B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "رقم التدÙÙ‚ (التدÙÙ‚ الأول هو 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "عدد الكتل ÙÙŠ التدÙÙ‚" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "إزاحة البداية المضغوطة" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "إزاحة البداية غير المضغوطة" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "الحجم المضغوط (لا يشمل حشو التدÙÙ‚)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "الحجم غير المضغوط" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "نسبة الضغط" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "اسم ÙØ­Øµ السلامة" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "حجم حشو التدÙÙ‚" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "أعمدة أسطر B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "رقم التدÙÙ‚ الذي يحتوي على هذه الكتلة" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "رقم الكتلة بالنسبة لبداية التدÙÙ‚ (الكتلة الأولى هي 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "رقم الكتلة بالنسبة لبداية الملÙ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "إزاحة البداية المضغوطة بالنسبة لبداية الملÙ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "إزاحة البداية غير المضغوطة بالنسبة لبداية الملÙ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "إجمالي الحجم المضغوط للكتلة (يشمل الترويسات)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "إذا Ø­ÙØ¯Ø¯ B<--verbose> مرتين، تضا٠أعمدة إضاÙية ÙÙŠ أسطر B. لا ØªÙØ¹Ø±Ø¶ هذه الأعمدة مع B<--verbose> واحدة، لأن الحصول عليها يتطلب عمليات بحث (seeks) كثيرة وبالتالي قد يكون بطيئاً:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "قيمة ÙØ­Øµ السلامة بالتمثيل الست عشري" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "حجم ترويسة الكتلة" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "أعلام الكتلة: يشير B إلى وجود الحجم المضغوط، ويشير B إلى وجود الحجم غير المضغوط. إذا لم ÙŠÙØ¶Ø¨Ø· العلم، تظهر شرطة (B<->) بدلاً منه Ù„Ù„Ø­ÙØ§Ø¸ على طول السلسلة ثابتاً. قد تضا٠أعلام جديدة ÙÙŠ نهاية السلسلة مستقبلاً." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "حجم البيانات المضغوطة Ø§Ù„ÙØ¹Ù„ية ÙÙŠ الكتلة (هذا يستثني ترويسة الكتلة، وحشو الكتلة، وحقول Ø§Ù„ÙØ­Øµ)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "مقدار الذاكرة (بالبايت) المطلوبة Ù„ÙÙƒ ضغط هذه الكتلة باستخدام إصدار B هذا" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "تسلسل المرشحات. لاحظ أن معظم الخيارات المستخدمة وقت الضغط لا يمكن Ù…Ø¹Ø±ÙØªÙ‡Ø§ØŒ لأن الخيارات اللازمة Ù„ÙÙƒ الضغط Ùقط هي التي تخزن ÙÙŠ ترويسات B<.xz>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "أعمدة أسطر B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "مقدار الذاكرة (بالبايت) المطلوبة Ù„ÙÙƒ ضغط هذا المل٠باستخدام إصدار B هذا" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B أو B للإشارة إلى ما إذا كانت كل ترويسات الكتل تحتوي على الحجم المضغوط وغير المضغوط مخزنين Ùيها" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I<منذ> B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "أقل إصدار B مطلوب Ù„ÙÙƒ ضغط الملÙ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "أعمدة سطر B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "عدد التدÙقات" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "عدد الكتل" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "الحجم المضغوط" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "متوسط نسبة الضغط" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "قائمة Ù…ÙØµÙˆÙ„Ø© بÙواصل لأسماء ÙØ­ÙˆØµØ§Øª السلامة التي كانت موجودة ÙÙŠ Ø§Ù„Ù…Ù„ÙØ§Øª" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "حجم حشو التدÙÙ‚" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "عدد Ø§Ù„Ù…Ù„ÙØ§Øª. هذا موجود Ù„Ù„Ø­ÙØ§Ø¸ على ترتيب الأعمدة السابقة Ø¨Ù†ÙØ³ ترتيبها ÙÙŠ أسطر B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "إذا Ø­ÙØ¯Ø¯ B<--verbose> مرتين، تضا٠أعمدة إضاÙية ÙÙŠ سطر B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "أقصى مقدار للذاكرة (بالبايت) المطلوبة Ù„ÙÙƒ ضغط Ø§Ù„Ù…Ù„ÙØ§Øª باستخدام إصدار B هذا" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "قد تضي٠الإصدارات المستقبلية أنواع أسطر جديدة وأعمدة جديدة للأنواع الحالية، لكن الأعمدة الحالية لن تتغير." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "مساعدة المرشحات" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "تطبع B المرشحات المدعومة بالتنسيق التالي:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "Dies ist stets die erste Zeile, wenn eine Datei aufgelistet wird. Die zweite Spalte in der Zeile enthält den Dateinamen." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +# CHECK overall +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "Diese Zeile enthält allgemeine Informationen zur B<.xz>-Datei. Diese Zeile wird stets nach der B-Zeile ausgegeben." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "Dieser Zeilentyp wird nur verwendet, wenn B<--verbose> angegeben wurde. Es gibt genau so viele B-Zeilen, wie Datenströme in der B<.xz>-Datei enthalten sind." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "Dieser Zeilentyp wird nur verwendet, wenn B<--verbose> angegeben wurde. Es gibt so viele B-Zeilen, wie Blöcke in der B<.xz>-Datei. Die B-Zeilen werden nach allen B-Zeilen angezeigt; verschiedene Zeilentypen werden nicht verschachtelt." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "Dieser Zeilentyp wird nur verwendet, wenn B<--verbose> zwei Mal angegeben wurde. Diese Zeile wird nach allen B-Zeilen ausgegeben. Wie die B-Zeile enthält die B-Zeile allgemeine Informationen zur B<.xz>-Datei." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "Diese Zeile ist immer die letzte der Listenausgabe. Sie zeigt die Gesamtanzahlen und -größen an." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Die Spalten der B-Zeilen:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "Anzahl der Datenströme in der Datei" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "Gesamtanzahl der Blöcke in den Datenströmen" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "Komprimierte Größe der Datei" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "Unkomprimierte Größe der Datei" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "Das Kompressionsverhältnis, zum Beispiel B<0.123>. Wenn das Verhältnis über 9.999 liegt, werden drei Minuszeichen (B<--->) anstelle des Kompressionsverhältnisses angezeigt." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "Durch Kommata getrennte Liste der Namen der Integritätsprüfungen. Für die bekannten Überprüfungstypen werden folgende Zeichenketten verwendet: B, B, B und B. BI wird verwendet, wobei I die Kennung der Überprüfung als Dezimalzahl angibt (ein- oder zweistellig)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "Gesamtgröße der Datenstromauffüllung in der Datei" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Die Spalten der B-Zeilen:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "Datenstromnummer (der erste Datenstrom ist 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "Anzahl der Blöcke im Datenstrom" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "Komprimierte Startposition" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "Unkomprimierte Startposition" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "Komprimierte Größe (schließt die Datenstromauffüllung nicht mit ein)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "Unkomprimierte Größe" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "Kompressionsverhältnis" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "Name der Integritätsprüfung" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "Größe der Datenstromauffüllung" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Die Spalten der B-Zeilen:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "Anzahl der in diesem Block enthaltenen Datenströme" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "Blocknummer relativ zum Anfang des Datenstroms (der erste Block ist 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "Blocknummer relativ zum Anfang der Datei" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "Komprimierter Startversatz relativ zum Beginn der Datei" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "Unkomprimierter Startversatz relativ zum Beginn der Datei" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "Komprimierte Gesamtgröße des Blocks (einschließlich Header)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "Wenn B<--verbose> zwei Mal angegeben wurde, werden zusätzliche Spalten in die B-Zeilen eingefügt. Diese werden mit einem einfachen B<--verbose> nicht angezeigt, da das Ermitteln dieser Informationen viele Suchvorgänge erfordert und daher recht langsam sein kann:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "Wert der Integritätsprüfung in hexadezimaler Notation" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "Block-Header-Größe" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "Block-Schalter: B gibt an, dass die komprimierte Größe verfügbar ist, und B gibt an, dass die unkomprimierte Größe verfügbar ist. Falls der Schalter nicht gesetzt ist, wird stattdessen ein Bindestrich (B<->) angezeigt, um die Länge der Zeichenkette beizubehalten. In Zukunft könnten neue Schalter am Ende der Zeichenkette hinzugefügt werden." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "Größe der tatsächlichen komprimierten Daten im Block. Ausgeschlossen sind hierbei die Block-Header, die Blockauffüllung und die Prüffelder." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "Größe des Speichers (in Byte), der zum Dekomprimieren dieses Blocks mit dieser B-Version benötigt wird." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "Filterkette. Beachten Sie, dass die meisten der bei der Kompression verwendeten Optionen nicht bekannt sein können, da in den B<.xz>-Headern nur die für die Dekompression erforderlichen Optionen gespeichert sind." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Die Spalten der B-Zeilen:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "Größe des Speichers (in Byte), der zum Dekomprimieren dieser Datei mit dieser B-Version benötigt wird." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B oder B geben an, ob in allen Block-Headern sowohl die komprimierte als auch die unkomprimierte Größe gespeichert ist." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "Minimale B-Version, die zur Dekompression der Datei erforderlich ist" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "Die Spalten der B-Zeile:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "Anzahl der Datenströme" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "Anzahl der Blöcke" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "Komprimierte Größe" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "Durchschnittliches Kompressionsverhältnis" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "Durch Kommata getrennte Liste der Namen der Integritätsprüfungen, die in den Dateien präsent waren." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "Größe der Datenstromauffüllung" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "Anzahl der Dateien. Dies dient dazu, die Reihenfolge der vorigen Spalten an die in den B-Zeilen anzugleichen." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "Wenn B<--verbose> zwei Mal angegeben wird, werden zusätzliche Spalten in die B-Zeile eingefügt:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "Maximale Größe des Speichers (in Byte), der zum Dekomprimieren der Dateien mit dieser B-Version benötigt wird." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "Zukünftige Versionen könnten neue Zeilentypen hinzufügen, weiterhin könnten auch in den vorhandenen Zeilentypen weitere Spalten hinzugefügt werden, aber die existierenden Spalten werden nicht geändert." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "Filterhilfe" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "B gibt die unterstützten Filter im folgenden Format aus:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "C'est toujours la première ligne au début de la liste d'un fichier. La seconde colonne de la ligne est le nom de fichier." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "Cette ligne contient l'information globale sur le fichier B<.xz>. Cette ligne est toujours écrite après la ligne B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "Ce type de ligne n'est utilisée que lorsque B< --verbose> a été indiquée. Il y a autant de lignes B qu'il y a de flux dans le fichier B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "Ce type de ligne n'est utilisé seulement lorsque B<--verbose> a été indiquée. Il y a autant de lignes B qu'il y a de blocs dans le fichier B<.xz>. Les lignes B sont affichées après toutes les lignes B ; les différents types de lignes ne sont pas imbriqués." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "Ce type de ligne n'est utilisé que lorsque B<--verbose> a été indiqué deux fois. Cette ligne est affichée après toutes les lignes B. Comme la ligne B, la ligne B contient l'information globale sur le fichier B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "Cette ligne est toujours la toute dernière ligne de la sortie. Elle affiche les comptes et les tailles totaux." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Les colonnes des lignes B :" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "Nombre de flux dans le fichier" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "Nombre total de blocs dans le ou les flux." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "Taille compressée du fichier" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "Taille décompressée du fichier" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "Liste de noms de contrôles d'intégrité séparés par des virgules. Les chaînes suivantes sont utilisées pour les types de vérification connus : B, B, B et B. Pour le types de vérification inconnus, BI est utilisé, où I est un identifiant de vérification sous la forme d'un nombre décimal (un ou deux chiffres)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "Taille totale du remplissage du flux dans le fichier" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Les colonnes des lignes B :" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "Numéro de flux (le premier flux a le numéro 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "Nombre de blocs dans le flux" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "Décalage de départ compressé" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "Décalage de départ décompressé" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "Taille compressée (ne comprend pas le remplissage du flux)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "Taille décompressée" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "Taux de compression" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "Nom de la vérification d'intégrité" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "Taille du remplissage de flux" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Les colonnes des lignes B :" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "Numéro du flux qui contient ce bloc" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "Numéro du bloc relatif au commencement du flux (le premier bloc a pour numéro 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "Numéro du bloc relatif au début du fichier" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "Décalage de départ compressé relatif au début du fichier" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "Décalage de départ décompressé relatif au début du fichier" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "Taille compressée totale du bloc (en-têtes inclus)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "Si B<--verbose> a été indiqué deux fois, les colonnes additionnelles sont inclues sur les lignes B. Elles ne sont pas affichées avec un seul B<--verbose>, car l'obtention de ces informations nécessite de nombreuses recherches et peut donc être lente :" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "Valeur de la vérification d'intégrité en hexadécimal" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "Taille d'en-tête de bloc" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "Drapeaux du bloc : B indique que la taille compressée est présente, et B indique que la taille décompréssée est présente. Si le drapeau n'est pas indiqué, un tiret (B<->) est affiché à la place pour que la longueur de la chaîne reste fixe. De nouveaux drapeaux pourraient être ajoutés à la fin de la chaîne dans le futur." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "Taille des données effectivement compressées dans le bloc (en excluant l'en-tête de bloc, le remplissage de bloc et les champs de vérification)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "Quantité de mémoire (en octets) nécessaire pour décompresser ce bloc avec cette version de B." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "Chaîne de filtrage. Remarquez que la plupart des options utilisées au moment de la compression ne peuvent pas être connues, car seules les options nécessaires pour la décompression sont stockées dans les en-têtes B<.xz>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Les colonnes des lignes B :" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "Quantité de mémoire (en octets) nécessaire pour décompresser ce fichier avec cette version de B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B ou B indique si tous les en-têtes de bloc stockent à la fois la taille compressée et la taille décompressée." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "Version minimale de B nécessaire pour décompresser le fichier." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "Les colonnes de la ligne B :" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "Nombre de flux" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "Nombre de blocs" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "Taille compressée" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "Taux de compression moyen" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "Liste séparée par des virgules des noms de vérification d'intégrité qui étaient présents dans les fichiers" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "Taille de remplissage de flux" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "Nombre de fichiers. Permet de garder l'ordre des colonnes précédentes comme sur les lignes B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "Si B<--verbose> a été indiqué deux fois, des colonnes supplémentaires sont incluses sur la ligne B :" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "Quantité maximale de mémoire (en octets) nécessaire pour décompresser les fichiers avec cette version de B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "Les versions futures pourront ajouter de nouveaux types de lignes et de nouvelles colonnes pourront être ajoutées aux types de lignes existants, mais les colonnes existantes ne seront pas modifiées." + +#. type: SS +#: ../src/xz/xz.1 +#, fuzzy, no-wrap +#| msgid "Filter" +msgid "Filters help" +msgstr "Filtre" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "Questa è sempre la prima riga quando si inizia a elencare un file. La seconda colonna della riga è il nome del file." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "Questa riga contiene informazioni generali sul file B<.xz>. Questa riga viene sempre stampata dopo la riga B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "Questo tipo di riga viene utilizzato solo quando è stato specificato B<--verbose>. Sono presenti tante righe B quanti sono i flussi nel file B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "Questo tipo di riga viene utilizzato solo quando è stato specificato B<--verbose>. Ci sono tante righe B quanti sono i blocchi nel file B<.xz>. Le righe B vengono visualizzate dopo tutte le righe B; i diversi tipi di riga non vengono interlacciati." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "Questo tipo di riga viene utilizzato solo quando B<--verbose> è stato specificato due volte. Questa riga viene stampata dopo tutte le righe B. Come la riga B, la riga B contiene informazioni generali sul file B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "Questa riga è sempre l'ultima riga dell'output dell'elenco. Mostra i conteggi totali e le dimensioni." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Le colonne delle righe B:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "Numero di flussi nel file" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "Numero totale di blocchi nel flusso/i." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "Dimensione compressa del file" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "Dimensione non compressa del file" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "Rapporto di compressione, es. B<0.123>. Se il rapporto è oltre 9999, al posto del rapporto vengono mostrati tre trattini (B<--->)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "Elenco separato da virgole dei nomi dei controlli di integrità. Le stringhe seguenti vengono utilizzate per i tipi di controllo conosciuti: B, B, B, e B. Per i tipi di controllo non conosciuti viene utilizzato BI, dove I è l'ID del controllo come numero decimale (una o due cifre)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "Dimensione totale del padding del flusso nel file" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Le colonne delle righe B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "Numero di flusso (il primo è 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "Numero di blocchi nel flusso" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "Offset iniziale compressione" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "Offset iniziale decompressione" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "Dimensione compressa (non include il padding del flusso)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "Dimensione non compressa" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "Rapporto di compressione" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "Nome del controllo di integrità" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "Dimensione del padding del flusso" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Le colonne delle righe B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "Numero di flussi che contengono questo blocco" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "Numero del blocco relativo all'inizio del flusso (il primo blocco è 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "Numero del blocco relativo all'inizio del file" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "Offset iniziale compressione relativo all'inizio del file" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "Offset iniziale decompressione relativo all'inizio del file" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "Dimensione totale compressa del blocco (incluse le intestazioni)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "Se B<--verbose> viene specificato due volte, sono incluse colonne aggiuntive nelle righe B. Queste non sono mostrate con un B<--verbose> singolo, perché recuperare queste informazioni richiede molte ricerche e quindi può essere lento:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "Valore del controllo di integrità in formato esadecimale" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "Dimensione intestazione blocco" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "Flag del blocco: Bindica che è presente la dimensione compressa, B indica che è presente la dimensione non compressa. Se il flag non è impostato, viene mostrato un trattino (B<->) per mantenere fissa la lunghezza della stringa. Nuovi flag potrebbero essere aggiunti alla fine della stringa in futuro." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "Dimensione dei dati compressi effettivi nel blocco (sono esclusi l'intestazione del blocco, il padding del blocco e i campi di controllo)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "Quantità di memoria (in byte) necessaria per decomprimere questo blocco con questa versione B" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "Catena di filtri. Si noti che la maggior parte delle opzioni utilizzate al momento della compressione non è nota, perché solo le opzioni necessarie per la decompressione sono memorizzate nelle intestazioni B<.xz>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Le colonne delle righe B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "Quantità di memoria (in byte) necessaria per decomprimere questo file con questa versione B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B o B indica se tutte le intestazioni di blocco contengono all'interno sia dimensioni compresse che dimensioni non compresse" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "Versione minima di B richiesta per decomprimere il file" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "Le colonne delle righe B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "Numero di flussi" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "Numero di blocchi" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "Dimensione compressa" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "Rapporto di compressione medio" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "Elenco separato da virgole dei nomi dei controlli di integrità presenti nei file" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "Dimensione del padding dello stream" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "Numero di file. Questo serve a mantenere l'ordine delle colonne precedenti uguale a quello delle righe del B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "Se B<--verbose> viene specificato due volte, sono incluse colonne aggiuntive nella riga B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "Quantità massima di memoria (in byte) necessaria per decomprimere i file con questa versione B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "Versioni future potrebbero aggiungere nuovi tipi di riga e nuove colonne possono essere aggiunte ai tipi di riga esistenti, ma le colonne esistenti non verranno modificate." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "Aiuto sui filtri" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "B stampa i filtri supportati nel seguente formato:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "ì´ í–‰ì€ í•­ìƒ íŒŒì¼ ëª©ë¡ ì‹œìž‘ ë¶€ë¶„ì˜ ì²«ë²ˆì§¸ ì¤„ì— ìžˆìŠµë‹ˆë‹¤. ì´ í–‰ì˜ ë‘번째 ì»¬ëŸ¼ì— íŒŒì¼ ì´ë¦„ì´ ë“¤ì–´ìžˆìŠµë‹ˆë‹¤." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "ì´ í–‰ì—는 B<.xz> 파ì¼ì˜ ì „ë°˜ì ì¸ ì •ë³´ê°€ 들어있습니다. ì´ í–‰ì€ í•­ìƒ B í–‰ 다ìŒì— 있습니다." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "ì´ í–‰ 형ì‹ì€ B<--verbose> ì˜µì…˜ì„ ì§€ì •í–ˆì„ ë•Œë§Œ 사용합니다. B<.xz> 파ì¼ì˜ B í–‰ ìˆ˜ë§Œí¼ ë‚˜íƒ€ë‚©ë‹ˆë‹¤." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "ì´ í–‰ 형ì‹ì€ B<--verbose> ì˜µì…˜ì„ ì§€ì •í–ˆì„ ë•Œë§Œ 사용합니다. B<.xz> 파ì¼ì˜ ë¸”ë¡ ìˆ˜ë§Œí¼ B í–‰ì´ ë‚˜íƒ€ë‚©ë‹ˆë‹¤. B í–‰ì€ ëª¨ë“  B í–‰ 다ìŒì— 나타납니다. 다른 형ì‹ì˜ í–‰ì´ ë¼ì–´ë“¤ì§€ëŠ” 않습니다." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "ì´ í–‰ 형ì‹ì€ B<--verbose> ì˜µì…˜ì„ ë‘번 ì§€ì •í–ˆì„ ë•Œë§Œ 사용합니다. ì´ í–‰ì€ ëª¨ë“  B í–‰ 다ìŒì— 출력합니다. B 행과 비슷하게, B í–‰ì—는 B<.xz> 파ì¼ì˜ ì „ë°˜ì ì¸ ì •ë³´ê°€ 담겨있습니다." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "ì´ í–‰ì€ ëª©ë¡ ì¶œë ¥ì˜ ê°€ìž¥ ë§ˆì§€ë§‰ì— í•­ìƒ ë‚˜íƒ€ë‚©ë‹ˆë‹¤. ì´ ê°¯ìˆ˜ì™€ í¬ê¸°ë¥¼ 나타냅니다." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "B í–‰ 컬럼:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "íŒŒì¼ ìŠ¤íŠ¸ë¦¼ 갯수" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "ìŠ¤íŠ¸ë¦¼ì˜ ë¸”ë¡ ì´ ê°¯ìˆ˜" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "íŒŒì¼ ì••ì¶• í¬ê¸°" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "íŒŒì¼ ì••ì¶• í•´ì œ í¬ê¸°" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "예를 들면, B<0.123>ê³¼ ê°™ì€ ì••ì¶•ìœ¨ 입니다. ë¹„ìœ¨ì´ 9.999ë¼ë©´, 대시 ë¬¸ìž 3ê°œ (B<--->)를 비율 ê°’ 대신 나타냅니다." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "쉼표로 구분한 무결성 검사 ì´ë¦„ 목ë¡ìž…니다. B, B, B, B 문ìžì—´ì„ 알려진 검사 형ì‹ìœ¼ë¡œ 사용합니다. 알 수 없는 검사 형ì‹ì— 대해서는 BIì„ ì‚¬ìš©í•˜ë©°, 여기서 Iì€ (한 ë‘ìžë¦¬) 정수형 숫ìžê°’으로 ì´ë£¨ì–´ì§„ 검사 ID 입니다." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "파ì¼ì˜ 스트림 패딩 ì´ ê¸¸ì´" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "B í–‰ 컬럼:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "스트림 번호 (첫 ìŠ¤íŠ¸ë¦¼ì€ 1번)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "ìŠ¤íŠ¸ë¦¼ì˜ ë¸”ë¡ ì´ ê°¯ìˆ˜" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "ì••ì¶• 시작 오프셋" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "비압축 시작 오프셋" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "ì••ì¶• í¬ê¸° (스트림 패딩 미í¬í•¨)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "ì••ì¶• í•´ì œ 용량" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "압축율" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "무결성 검사 ì´ë¦„" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "스트림 패딩 길ì´" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "B í–‰ 컬럼:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "ì´ ë¸”ë¡ì´ 들어간 스트림 갯수" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "스트림 시작 ë¶€ë¶„ì˜ ë¸”ë¡ ë²ˆí˜¸ (첫번째 블ë¡ì€ 1번)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "íŒŒì¼ ì‹œìž‘ ë¶€ë¶„ì˜ ë¸”ë¡ ë²ˆí˜¸" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "íŒŒì¼ ì‹œìž‘ ë¶€ë¶„ì˜ ì••ì¶• 시작 오프셋" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "íŒŒì¼ ì‹œìž‘ ë¶€ë¶„ì˜ ë¹„ì••ì¶• 시작 오프셋" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "ì´ ë¸”ë¡ ì••ì¶• í¬ê¸° (í—¤ë” í¬í•¨)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "B<--verbose>를 ë‘ ë²ˆ 지정하면, 추가 ì»¬ëŸ¼ì„ B í–‰ì— ë„£ìŠµë‹ˆë‹¤. B<--verbose> ë‹¨ì¼ ì§€ì •ì‹œì—는 ì´ ì •ë³´ë¥¼ ë³¼ 때 íƒìƒ‰ì„ 여러번 수행해야 하기 ë•Œë¬¸ì— ì‹¤í–‰ ê³¼ì •ì´ ëŠë ¤ì§ˆ 수 있어서 나타내지 않습니다:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "16진수 무결성 검사값" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "ë¸”ë¡ í—¤ë” í¬ê¸°" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "ë¸”ë¡ í”Œëž˜ê·¸: B는 ì••ì¶• í¬ê¸°ê°€ 현재 ê°’ìž„ì„ ë‚˜íƒ€ë‚´ê³ , B는 ì••ì¶• ì „ ì›ë³¸ í¬ê¸°ê°€ 현재 ê°’ìž„ì„ ë‚˜íƒ€ëƒ…ë‹ˆë‹¤. 플래그를 설정하지 않았다면, 문ìžì—´ 길ì´ë¥¼ 유지할 목ì ìœ¼ë¡œ 대시 B<-> 를 대신 나타냅니다. 새 플래그는 ë‚˜ì¤‘ì— ë¬¸ìžì—´ ë ë¶€ë¶„ì— ì¶”ê°€í•  예정입니다." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "블ë¡ì— ì••ì¶• 해서 ë„£ì€ ë°ì´í„°ì˜ 실제 츠기 (ë¸”ë¡ í—¤ë”, ë¸”ë¡ íŒ¨ë”©, 검사 필드 제외)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "ì´ B 버전ì—서 ì´ ë¸”ë¡ì˜ ì••ì¶•ì„ í•´ì œí•  때 필요한 (ë°”ì´íЏ 단위) 메모리 용량" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "í•„í„° ì²´ì¸. 대부분 사용하는 ì˜µì…˜ì€ ì••ì¶• 해제시 필요한 ì˜µì…˜ë§Œì„ B<.xz> í—¤ë”ì— ì €ìž¥í•˜ê¸° ë•Œë¬¸ì— ì••ì¶• ì‹œê°„ì— ì•Œ 수 없습니다." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "B í–‰ 컬럼:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "ì´ B 버전ì—서 ì´ íŒŒì¼ ì••ì¶•ì„ í•´ì œí•  때 필요한 (ë°”ì´íЏ 단위) 메모리 용량" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "모든 ë¸”ë¡ í—¤ë”ì— ì••ì¶• í¬ê¸°ì™€ ì••ì¶• ì „ ì›ë³¸ í¬ê¸° ì •ë³´ê°€ 들어갔는지 여부를 나타내는 B ë˜ëŠ” B ê°’" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "B I<5.1.2alpha> I<부터:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "íŒŒì¼ ì••ì¶• 해제시 필요한 최소 B 버전" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "B í–‰ 컬럼:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "스트림 갯수" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "ë¸”ë¡ ê°¯ìˆ˜" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "ì••ì¶• í¬ê¸°" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "í‰ê·  압축율" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "파ì¼ì— 들어 있어 쉼표로 구분한 무결성 검사 ì´ë¦„ 목ë¡" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "스트림 패딩 길ì´" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "íŒŒì¼ ê°¯ìˆ˜. B í–‰ì˜ ì»¬ëŸ¼ 순서를 ë”°ë¼ê°‘니다." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "B<--verbose> ì˜µì…˜ì„ ë‘ ë²ˆ 지정하면, B í–‰ì— ì¶”ê°€ ì»¬ëŸ¼ì´ ë“¤ì–´ê°‘ë‹ˆë‹¤:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "ì´ B 버전ì—서 íŒŒì¼ ì••ì¶•ì„ í•´ì œí•  ë–„ 필요한 (ë°”ì´íЏ 단위) 최대 메모리 사용량" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "차후 버전ì—서는 새 í–‰ 형ì‹ì„ 추가하고 기존 í–‰ 형ì‹ì— 추가할 수 있는 새 ì»¬ëŸ¼ì„ ë„£ê¸° 까지는 알 수 있겠지만, 기존 ì»¬ëŸ¼ì€ ë°”ê¾¸ì§€ ì•Šì„ ì˜ˆì •ìž…ë‹ˆë‹¤." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "í•„í„° ë„움ë§" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "B 는 ë‹¤ìŒ í˜•ì‹ì˜ ì§€ì› í•„í„° 목ë¡ì„ 출력합니다:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP (الاسم) +هذا دائماً هو السطر الأول عند البدء ÙÙŠ سرد ملÙ. العمود الثاني ÙÙŠ السطر هو +اسم الملÙ. +.TP +\fBfile\fP (الملÙ) +يحتوي هذا السطر على معلومات عامة حول مل٠\fB.xz\fP. ÙŠÙØ·Ø¨Ø¹ هذا السطر دائماً بعد +سطر \fBname\fP. +.TP +\fBstream\fP (التدÙÙ‚) +ÙŠÙØ³ØªØ®Ø¯Ù… نوع السطر هذا Ùقط عند تحديد \fB\-\-verbose\fP. يوجد من أسطر \fBstream\fP +بعدد التدÙقات الموجودة ÙÙŠ مل٠\fB.xz\fP. +.TP +\fBblock\fP (الكتلة) +ÙŠÙØ³ØªØ®Ø¯Ù… نوع السطر هذا Ùقط عند تحديد \fB\-\-verbose\fP. يوجد من أسطر \fBblock\fP بعدد +الكتل الموجودة ÙÙŠ مل٠\fB.xz\fP. تظهر أسطر \fBblock\fP بعد كل أسطر \fBstream\fPØ› ولا +تتداخل أنواع الأسطر Ø§Ù„Ù…Ø®ØªÙ„ÙØ©. +.TP +\fBsummary\fP (الملخص) +ÙŠÙØ³ØªØ®Ø¯Ù… نوع السطر هذا Ùقط عند تحديد \fB\-\-verbose\fP مرتين. ÙŠÙØ·Ø¨Ø¹ هذا السطر بعد +كل أسطر \fBblock\fP. مثل سطر \fBfile\fPØŒ يحتوي سطر \fBsummary\fP على معلومات عامة حول +مل٠\fB.xz\fP. +.TP +\fBtotals\fP (الإجماليات) +هذا السطر هو دائماً السطر الأخير تماماً ÙÙŠ مخرجات القائمة. يعرض الأعداد +والأحجام الإجمالية. +.PP +أعمدة أسطر \fBfile\fP: +.PD 0 +.RS +.IP 2. 4 +عدد التدÙقات ÙÙŠ المل٠+.IP 3. 4 +إجمالي عدد الكتل ÙÙŠ التدÙÙ‚ (التدÙقات) +.IP 4. 4 +الحجم المضغوط للمل٠+.IP 5. 4 +الحجم غير المضغوط للمل٠+.IP 6. 4 +نسبة الضغط، مثلاً \fB0.123\fP. إذا كانت النسبة Ùوق 9.999ØŒ ØªÙØ¹Ø±Ø¶ ثلاث شرطات +(\fB\-\-\-\fP) بدلاً من النسبة. +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +قائمة Ù…ÙØµÙˆÙ„Ø© بÙواصل لأسماء ÙØ­ÙˆØµØ§Øª السلامة. ØªÙØ³ØªØ®Ø¯Ù… السلاسل التالية لأنواع +Ø§Ù„ÙØ­Øµ Ø§Ù„Ù…Ø¹Ø±ÙˆÙØ©: \fBNone\fPØŒ \fBCRC32\fPØŒ \fBCRC64\fPØŒ Ùˆ \fBSHA\-256\fP. لأنواع Ø§Ù„ÙØ­Øµ غير +Ø§Ù„Ù…Ø¹Ø±ÙˆÙØ©ØŒ ÙŠÙØ³ØªØ®Ø¯Ù… \fBUnknown\-\fP\fIN\fPØŒ حيث \fIN\fP هو Ù…Ø¹Ø±Ù‘Ù Ø§Ù„ÙØ­Øµ كرقم عشري (رقم +واحد أو رقمان). +.IP 8. 4 +إجمالي حجم حشو التدÙÙ‚ ÙÙŠ المل٠+.RE +.PD +.PP +أعمدة أسطر \fBstream\fP: +.PD 0 +.RS +.IP 2. 4 +رقم التدÙÙ‚ (التدÙÙ‚ الأول هو 1) +.IP 3. 4 +عدد الكتل ÙÙŠ التدÙÙ‚ +.IP 4. 4 +إزاحة البداية المضغوطة +.IP 5. 4 +إزاحة البداية غير المضغوطة +.IP 6. 4 +الحجم المضغوط (لا يشمل حشو التدÙÙ‚) +.IP 7. 4 +الحجم غير المضغوط +.IP 8. 4 +نسبة الضغط +.IP 9. 4 +اسم ÙØ­Øµ السلامة +.IP 10. 4 +حجم حشو التدÙÙ‚ +.RE +.PD +.PP +أعمدة أسطر \fBblock\fP: +.PD 0 +.RS +.IP 2. 4 +رقم التدÙÙ‚ الذي يحتوي على هذه الكتلة +.IP 3. 4 +رقم الكتلة بالنسبة لبداية التدÙÙ‚ (الكتلة الأولى هي 1) +.IP 4. 4 +رقم الكتلة بالنسبة لبداية المل٠+.IP 5. 4 +إزاحة البداية المضغوطة بالنسبة لبداية المل٠+.IP 6. 4 +إزاحة البداية غير المضغوطة بالنسبة لبداية المل٠+.IP 7. 4 +إجمالي الحجم المضغوط للكتلة (يشمل الترويسات) +.IP 8. 4 +الحجم غير المضغوط +.IP 9. 4 +نسبة الضغط +.IP 10. 4 +اسم ÙØ­Øµ السلامة +.RE +.PD +.PP +إذا Ø­ÙØ¯Ø¯ \fB\-\-verbose\fP مرتين، تضا٠أعمدة إضاÙية ÙÙŠ أسطر \fBblock\fP. لا ØªÙØ¹Ø±Ø¶ +هذه الأعمدة مع \fB\-\-verbose\fP واحدة، لأن الحصول عليها يتطلب عمليات بحث (seeks) +كثيرة وبالتالي قد يكون بطيئاً: +.PD 0 +.RS +.IP 11. 4 +قيمة ÙØ­Øµ السلامة بالتمثيل الست عشري +.IP 12. 4 +حجم ترويسة الكتلة +.IP 13. 4 +أعلام الكتلة: يشير \fBc\fP إلى وجود الحجم المضغوط، ويشير \fBu\fP إلى وجود الحجم +غير المضغوط. إذا لم ÙŠÙØ¶Ø¨Ø· العلم، تظهر شرطة (\fB\-\fP) بدلاً منه Ù„Ù„Ø­ÙØ§Ø¸ على طول +السلسلة ثابتاً. قد تضا٠أعلام جديدة ÙÙŠ نهاية السلسلة مستقبلاً. +.IP 14. 4 +حجم البيانات المضغوطة Ø§Ù„ÙØ¹Ù„ية ÙÙŠ الكتلة (هذا يستثني ترويسة الكتلة، وحشو +الكتلة، وحقول Ø§Ù„ÙØ­Øµ) +.IP 15. 4 +مقدار الذاكرة (بالبايت) المطلوبة Ù„ÙÙƒ ضغط هذه الكتلة باستخدام إصدار \fBxz\fP هذا +.IP 16. 4 +تسلسل المرشحات. لاحظ أن معظم الخيارات المستخدمة وقت الضغط لا يمكن Ù…Ø¹Ø±ÙØªÙ‡Ø§ØŒ +لأن الخيارات اللازمة Ù„ÙÙƒ الضغط Ùقط هي التي تخزن ÙÙŠ ترويسات \fB.xz\fP. +.RE +.PD +.PP +أعمدة أسطر \fBsummary\fP: +.PD 0 +.RS +.IP 2. 4 +مقدار الذاكرة (بالبايت) المطلوبة Ù„ÙÙƒ ضغط هذا المل٠باستخدام إصدار \fBxz\fP هذا +.IP 3. 4 +\fByes\fP أو \fBno\fP للإشارة إلى ما إذا كانت كل ترويسات الكتل تحتوي على الحجم +المضغوط وغير المضغوط مخزنين Ùيها +.PP +\fIمنذ\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +أقل إصدار \fBxz\fP مطلوب Ù„ÙÙƒ ضغط المل٠+.RE +.PD +.PP +أعمدة سطر \fBtotals\fP: +.PD 0 +.RS +.IP 2. 4 +عدد التدÙقات +.IP 3. 4 +عدد الكتل +.IP 4. 4 +الحجم المضغوط +.IP 5. 4 +الحجم غير المضغوط +.IP 6. 4 +متوسط نسبة الضغط +.IP 7. 4 +قائمة Ù…ÙØµÙˆÙ„Ø© بÙواصل لأسماء ÙØ­ÙˆØµØ§Øª السلامة التي كانت موجودة ÙÙŠ Ø§Ù„Ù…Ù„ÙØ§Øª +.IP 8. 4 +حجم حشو التدÙÙ‚ +.IP 9. 4 +عدد Ø§Ù„Ù…Ù„ÙØ§Øª. هذا موجود Ù„Ù„Ø­ÙØ§Ø¸ على ترتيب الأعمدة السابقة Ø¨Ù†ÙØ³ ترتيبها ÙÙŠ أسطر +\fBfile\fP. +.PD +.RE +.PP +إذا Ø­ÙØ¯Ø¯ \fB\-\-verbose\fP مرتين، تضا٠أعمدة إضاÙية ÙÙŠ سطر \fBtotals\fP: +.PD 0 +.RS +.IP 10. 4 +أقصى مقدار للذاكرة (بالبايت) المطلوبة Ù„ÙÙƒ ضغط Ø§Ù„Ù…Ù„ÙØ§Øª باستخدام إصدار \fBxz\fP +هذا +.IP 11. 4 +\fByes\fP أو \fBno\fP للإشارة إلى ما إذا كانت كل ترويسات الكتل تحتوي على الحجم +المضغوط وغير المضغوط مخزنين Ùيها +.PP +\fIمنذ\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +أقل إصدار \fBxz\fP مطلوب Ù„ÙÙƒ ضغط المل٠+.RE +.PD +.PP +قد تضي٠الإصدارات المستقبلية أنواع أسطر جديدة وأعمدة جديدة للأنواع الحالية، +لكن الأعمدة الحالية لن تتغير. +. +.SS "مساعدة المرشحات" +تطبع \fBxz \-\-robot \-\-filters\-help\fP المرشحات المدعومة بالتنسيق التالي: +.PP +\fIالمرشح\fP\fB:\fP\fIالخيار\fP\fB=<\fP\fIالقيمة\fP\fB>,\fP\fIالخيار\fP\fB=<\fP\fIالقيمة\fP\fB>\fP... +.TP +\fIfilter\fP (المرشح) +اسم المرشح +.TP +\fIoption\fP (الخيار) +اسم خيار خاص بالمرشح +.TP +\fIvalue\fP (القيمة) +تظهر نطاقات الـ \fIالقيمة\fP الرقمية كـ +\fB<\fP\fImin\fP\fB\-\fP\fImax\fP\fB>\fP. خيارات الـ \fIالقيمة\fP النصية تظهر داخل +\fB< >\fP ÙˆÙ…ÙØµÙˆÙ„Ø© بمحر٠\fB|\fP. +.PP +ÙŠÙØ·Ø¨Ø¹ كل مرشح ÙÙŠ سطر خاص به. +. +.SS "معلومات حد الذاكرة" +تطبع \fBxz \-\-robot \-\-info\-memory\fP سطراً واحداً بعدة أعمدة Ù…ÙØµÙˆÙ„Ø© بعلامات +جدولة: +.IP 1. 4 +إجمالي مقدار الذاكرة Ø§Ù„ÙØ¹Ù„ية (RAM) بالبايت. +.IP 2. 4 +حد استهلاك الذاكرة للضغط بالبايت (\fB\-\-memlimit\-compress\fP). القيمة الخاصة +\fB0\fP تشير إلى الإعداد المبدئي الذي يكون ÙÙŠ نمط الخيط الواحد بلا حد. +.IP 3. 4 +حد استهلاك الذاكرة Ù„ÙÙƒ الضغط بالبايت (\fB\-\-memlimit\-decompress\fP). القيمة +الخاصة \fB0\fP تشير إلى الإعداد المبدئي الذي يكون ÙÙŠ نمط الخيط الواحد بلا حد. +.IP 4. 4 +منذ \fBxz\fP 5.3.4alpha: استهلاك الذاكرة Ù„ÙÙƒ الضغط متعدد الخيوط بالبايت +(\fB\-\-memlimit\-mt\-decompress\fP). هذه القيمة ليست ØµÙØ±Ø§Ù‹ أبداً لأن قيمة مبدئية +خاصة بالنظام تظهر ÙÙŠ العمود 5 ØªÙØ³ØªØ®Ø¯Ù… إذا لم ÙŠÙØ­Ø¯Ø¯ حد صراحةً. كما أنها ليست +أكبر من القيمة ÙÙŠ العمود 3 أبداً حتى لو Ø­ÙØ¯Ø¯Øª قيمة أكبر باستخدام +\fB\-\-memlimit\-mt\-decompress\fP. +.IP 5. 4 +منذ \fBxz\fP 5.3.4alpha: حد استهلاك ذاكرة مبدئي خاص بالنظام ÙŠÙØ³ØªØ®Ø¯Ù… للحد من عدد +الخيوط عند الضغط بعدد خيوط آلي (\fB\-\-threads=0\fP) ولم ÙŠÙØ­Ø¯Ø¯ حد لاستهلاك +الذاكرة (\fB\-\-memlimit\-compress\fP). ÙŠÙØ³ØªØ®Ø¯Ù… هذا أيضاً كقيمة مبدئية لـ +\fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +منذ \fBxz\fP 5.3.4alpha: عدد خيوط المعالج المتاحة. +.PP +ÙÙŠ المستقبل، قد تحتوي مخرجات \fBxz \-\-robot \-\-info\-memory\fP على أعمدة أكثر، +لكنها لن تتجاوز سطراً واحداً أبداً. +. +.SS الإصدار +تطبع \fBxz \-\-robot \-\-version\fP رقم إصدار \fBxz\fP Ùˆ liblzma بالتنسيق التالي: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +الإصدار الرئيسي. +.TP +\fIYYY\fP +الإصدار Ø§Ù„ÙØ±Ø¹ÙŠ. الأرقام الزوجية مستقرة. الأرقام Ø§Ù„ÙØ±Ø¯ÙŠØ© هي إصدارات Ø£Ù„ÙØ§ أو +بيتا. +.TP +\fIZZZ\fP +مستوى التصحيح للإصدارات المستقرة أو مجرد عداد لإصدارات التطوير. +.TP +\fIS\fP +الاستقرار. 0 Ù„Ø£Ù„ÙØ§ØŒ 1 لبيتا، Ùˆ 2 للمستقر. يجب أن يكون \fIS\fP دائماً 2 عندما +يكون \fIYYY\fP زوجياً. +.PP +\fIXYYYZZZS\fP متطابقان ÙÙŠ السطرين إذا كان \fBxz\fP Ùˆ liblzma من Ù†ÙØ³ إصدار XZ +Utils. +.PP +أمثلة: 4.999.9beta هو \fB49990091\fP Ùˆ 5.0.0 هو \fB50000002\fP. +. +.SH "حالة الخروج" +.TP +\fB0\fP +كل شيء على ما يرام. +.TP +\fB1\fP +حدث خطأ. +.TP +\fB2\fP +حدث شيء يستحق التحذير، ولكن لم تحدث أخطاء ÙØ¹Ù„ية. +.PP +الملاحظات (ليست تحذيرات أو أخطاء) المطبوعة على الخطأ القياسي لا تؤثر على +حالة الخروج. +. +.SH البيئة +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +يحلل \fBxz\fP قوائم الخيارات Ø§Ù„Ù…ÙØµÙˆÙ„Ø© Ø¨Ù…Ø³Ø§ÙØ§Øª من متغيرات البيئة \fBXZ_DEFAULTS\fP +Ùˆ \fBXZ_OPT\fP بهذا الترتيب، قبل تحليل الخيارات من سطر الأوامر. لاحظ أن +الخيارات Ùقط هي التي ØªÙØ­Ù„Ù„ من متغيرات البيئة؛ ÙˆØªÙØªØ¬Ø§Ù‡Ù„ جميع غير الخيارات +بصمت. يتم التحليل باستخدام \fBgetopt_long\fP(3) المستخدم أيضاً لوسائط سطر +الأوامر. +.PP +\fBتحذير:\fP بضبط متغيرات البيئة هذه، ÙØ¥Ù†Ùƒ تقوم ÙØ¹Ù„ياً بتعديل البرامج +والسكربتات التي تشغل \fBxz\fP. ÙÙŠ معظم الأوقات يكون من الآمن ضبط حدود استهلاك +الذاكرة، وعدد الخيوط، وخيارات الضغط عبر متغيرات البيئة. ومع ذلك، يمكن لبعض +الخيارات أن تعطل السكربتات. مثال واضح هو \fB\-\-help\fP الذي يجعل \fBxz\fP يعرض نص +المساعدة بدلاً من ضغط أو ÙÙƒ ضغط الملÙ. أمثلة أكثر دقة هي \fB\-\-quiet\fP Ùˆ +\fB\-\-verbose\fP. ÙÙŠ كثير من الحالات يعمل تمكين مؤشر التقدم باستخدام +\fB\-\-verbose\fP بشكل جيد، ولكن ÙÙŠ بعض المواق٠تسبب الرسائل الإضاÙية مشاكل. كما +يؤثر مستوى الإسهاب على سلوك \fB\-\-list\fP. +.TP +\fBXZ_DEFAULTS\fP +خيارات مبدئية خاصة بالمستخدم أو شاملة للنظام. عادةً ما ØªÙØ¶Ø¨Ø· ÙÙŠ سكربت تهيئة +Ø§Ù„ØµØ¯ÙØ© لتمكين محدد استهلاك ذاكرة \fBxz\fP بشكل مبدئي أو ضبط عدد الخيوط +المبدئي. باستثناء سكربتات تهيئة Ø§Ù„ØµØ¯ÙØ© والحالات الخاصة المماثلة، يجب ألا +تقوم السكربتات أبداً بضبط أو إلغاء ضبط \fBXZ_DEFAULTS\fP. +.TP +\fBXZ_OPT\fP +هذا لتمرير الخيارات إلى \fBxz\fP عندما لا يكون من الممكن ضبط الخيارات مباشرة +على سطر أوامر \fBxz\fP. هذا هو الحال عندما يتم تشغيل \fBxz\fP بواسطة سكربت أو +أداة، على سبيل المثال GNU \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +قد تستخدم البرامج النصية \fBXZ_OPT\fPØŒ مثلاً، لضبط خيارات ضغط مبدئية خاصة +بالبرنامج النصي. لا يزال ÙŠÙنصح بالسماح للمستخدمين بتجاوز \fBXZ_OPT\fP إذا كان +ذلك معقولاً. مثلاً، ÙÙŠ برامج \fBsh\fP(1) النصية يمكن للمرء استخدام شيء كهذا: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "التواÙÙ‚ مع أدوات LZMA" +ØªÙØ¹Ø¯ صيغة سطر أوامر \fBxz\fP عملياً مجموعة Ùوقية لكل من \fBlzma\fPØŒ Ùˆ\fBunlzma\fPØŒ +Ùˆ\fBlzcat\fP كما هي موجودة ÙÙŠ أدوات LZMA إصدار 4.32.x. ÙÙŠ معظم الحالات، يمكن +استبدال أدوات LZMA بأدوات XZ دون كسر البرامج النصية الموجودة. ومع ذلك، توجد +بعض أوجه عدم التواÙÙ‚ التي قد تسبب مشاكل أحياناً. +. +.SS "مستويات الضبط المسبق للضغط" +ترقيم مستويات الضبط المسبق للضغط ليس متطابقاً ÙÙŠ \fBxz\fP وأدوات LZMA. الاختلا٠+الأهم هو كيÙية تعيين أحجام القواميس لمختل٠مستويات الضبط. حجم القاموس يساوي +تقريباً استهلاك الذاكرة عند ÙÙƒ الضغط. +.RS +.PP +.TS +tab(;); +c c c +c n n. +المستوى;xz;أدوات LZMA +\-0;256 كيلوبايت;غير متاح +\-1;1 ميجابايت;64 Ùƒ.بايت +\-2;2 ميجابايت;1 ميجابايت +\-3;4 ميجابايت;512 Ùƒ.بايت +\-4;4 ميجابايت;1 ميجابايت +\-5;8 ميجابايت;2 ميجابايت +\-6;8 ميجابايت;4 ميجابايت +\-7;16 ميجابايت;8 ميجابايت +\-8;32 ميجابايت;16 ميجابايت +\-9;64 ميجابايت;32 ميجابايت +.TE +.RE +.PP +تؤثر Ø§Ø®ØªÙ„Ø§ÙØ§Øª حجم القاموس على استهلاك ذاكرة الضاغط أيضاً، ولكن توجد Ø§Ø®ØªÙ„Ø§ÙØ§Øª +أخرى بين أدوات LZMA وأدوات XZ تجعل Ø§Ù„ÙØ§Ø±Ù‚ أكبر: +.RS +.PP +.TS +tab(;); +c c c +c n n. +المستوى;xz;أدوات LZMA إصدار 4.32.x +\-0;3 ميجابايت;غير متاح +\-1;9 ميجابايت;2 ميجابايت +\-2;17 ميجابايت;12 Ù….بايت +\-3;32 ميجابايت;12 Ù….بايت +\-4;48 ميجابايت;16 ميجابايت +\-5;94 ميجابايت;26 Ù….بايت +\-6;94 ميجابايت;45 Ù….بايت +\-7;186 ميجابايت;83 Ù….بايت +\-8;370 ميجابايت;159 Ù….بايت +\-9;674 ميجابايت;311 Ù….بايت +.TE +.RE +.PP +مستوى الضبط المبدئي ÙÙŠ أدوات LZMA هو \fB\-7\fP بينما ÙÙŠ أدوات XZ هو \fB\-6\fPØŒ لذا +كلاهما يستخدم قاموساً بحجم 8 Ù….بايت بشكل مبدئي. +. +.SS "Ù…Ù„ÙØ§Øª lzma. المتدÙقة مقابل غير المتدÙقة" +يمكن تخزين الحجم غير المضغوط للمل٠ÙÙŠ ترويسة \fB.lzma\fP. تقوم أدوات LZMA بذلك +عند ضغط Ø§Ù„Ù…Ù„ÙØ§Øª العادية. البديل هو وسم الحجم غير المضغوط بأنه غير معرو٠+واستخدام علامة نهاية الحمولة للإشارة إلى المكان الذي يجب أن يتوق٠عنده ÙÙƒ +الضغط. تستخدم أدوات LZMA هذه الطريقة عندما يكون الحجم غير المضغوط غير Ù…Ø¹Ø±ÙˆÙØŒ +كما هو الحال مثلاً ÙÙŠ الأنابيب. +.PP +يدعم \fBxz\fP ÙÙƒ ضغط Ù…Ù„ÙØ§Øª \fB.lzma\fP بوجود علامة نهاية الحمولة أو بدونها، لكن +جميع Ù…Ù„ÙØ§Øª \fB.lzma\fP التي ينشئها \fBxz\fP تستخدم علامة نهاية الحمولة ويكون الحجم +غير المضغوط Ùيها موسوماً بأنه غير معرو٠ÙÙŠ الترويسة. قد يسبب هذا مشكلة ÙÙŠ +بعض الحالات غير الشائعة. مثلاً، قد يعمل Ù…Ùكك ضغط \fB.lzma\fP ÙÙŠ جهاز مدمج Ùقط +مع Ø§Ù„Ù…Ù„ÙØ§Øª ذات الحجم غير المضغوط المعروÙ. إذا واجهت هذه المشكلة، تحتاج +لاستخدام أدوات LZMA أو LZMA SDK لإنشاء Ù…Ù„ÙØ§Øª \fB.lzma\fP بحجم غير مضغوط معروÙ. +. +.SS "Ù…Ù„ÙØ§Øª lzma. غير المدعومة" +تسمح صيغة \fB.lzma\fP بقيم \fIlc\fP تصل إلى 8ØŒ وقيم \fIlp\fP تصل إلى 4. يمكن لأدوات +LZMA ÙÙƒ ضغط Ø§Ù„Ù…Ù„ÙØ§Øª بأي قيم \fIlc\fP Ùˆ\fIlp\fPØŒ لكنها تنشئ دائماً Ù…Ù„ÙØ§Øª بـ \fBlc=3\fP +Ùˆ\fBlp=0\fP. إنشاء Ù…Ù„ÙØ§Øª بقيم \fIlc\fP Ùˆ\fIlp\fP أخرى متاح عبر \fBxz\fP وعبر LZMA SDK. +.PP +يتطلب تنÙيذ مرشح LZMA1 ÙÙŠ liblzma ألا يتجاوز مجموع \fIlc\fP Ùˆ\fIlp\fP القيمة +4. لذا، لا يمكن ÙÙƒ ضغط Ù…Ù„ÙØ§Øª \fB.lzma\fP التي تتجاوز هذا القيد باستخدام \fBxz\fP. +.PP +تنشئ أدوات LZMA Ù…Ù„ÙØ§Øª \fB.lzma\fP Ùقط بأحجام قواميس هي 2^\fIn\fP (قوة للعدد 2) +لكنها تقبل Ø§Ù„Ù…Ù„ÙØ§Øª بأي حجم قاموس. تقبل liblzma Ùقط Ù…Ù„ÙØ§Øª \fB.lzma\fP التي يكون +حجم قاموسها 2^\fIn\fP أو 2^\fIn\fP + 2^(\fIn\fP\-1). الهد٠من ذلك هو تقليل الإيجابيات +الخاطئة عند الكش٠عن Ù…Ù„ÙØ§Øª \fB.lzma\fP. +.PP +ÙŠÙÙØªØ±Ø¶ ألا تمثل هذه القيود مشكلة من الناحية العملية، حيث أن جميع Ù…Ù„ÙØ§Øª +\&\fB.lzma\fP تقريباً Ø¶ÙØºØ·Øª بإعدادات تقبلها liblzma. +. +.SS "Ù…Ø®Ù„ÙØ§Øª لاحقة" +عند ÙÙƒ الضغط، تتجاهل أدوات LZMA بصمت كل شيء بعد تدÙÙ‚ \fB.lzma\fP الأول. ÙÙŠ معظم +الحالات، ÙŠÙØ¹Ø¯ هذا خطأ برمجياً. يعني هذا أيضاً أن أدوات LZMA لا تدعم ÙÙƒ ضغط +Ù…Ù„ÙØ§Øª \fB.lzma\fP المتسلسلة. +.PP +إذا تبقى بيانات بعد تدÙÙ‚ \fB.lzma\fP الأول، يعتبر \fBxz\fP Ø§Ù„Ù…Ù„Ù ØªØ§Ù„ÙØ§Ù‹ إلا إذا +استخدم خيار \fB\-\-single\-stream\fP. قد يؤدي هذا لكسر البرامج النصية الغامضة التي +Ø§ÙØªØ±Ø¶Øª تجاهل Ø§Ù„Ù…Ø®Ù„ÙØ§Øª اللاحقة. +. +.SH ملاحظات +. +.SS "قد يختل٠المخرج المضغوط" +قد يختل٠المخرج المضغوط بدقة والناتج عن Ù†ÙØ³ مل٠المدخلات غير المضغوط بين +إصدارات أدوات XZ حتى لو كانت خيارات الضغط متطابقة. يرجع ذلك إلى إمكانية +تحسين المرمز (ضغط أسرع أو Ø£ÙØ¶Ù„) دون التأثير على صيغة الملÙ. يمكن أن يختل٠+المخرج حتى بين البناءات Ø§Ù„Ù…Ø®ØªÙ„ÙØ© Ù„Ù†ÙØ³ إصدار أدوات XZØŒ ÙÙŠ حال استخدام خيارات +بناء Ù…Ø®ØªÙ„ÙØ©. +.PP +ما سبق يعني أنه بمجرد تنÙيذ \fB\-\-rsyncable\fPØŒ لن تكون Ø§Ù„Ù…Ù„ÙØ§Øª الناتجة بالضرورة +قابلة لـ rsync ما لم ØªÙØ¶ØºØ· Ø§Ù„Ù…Ù„ÙØ§Øª القديمة والجديدة Ø¨Ù†ÙØ³ إصدار xz. يمكن حل +هذه المشكلة إذا جÙمد جزء من تنÙيذ المرمز Ù„Ù„Ø­ÙØ§Ø¸ على استقرار مخرج rsync عبر +إصدارات xz. +. +.SS "Ù…Ùكات ضغط xz. المدمجة" +تنÙيذات Ù…Ùكك ضغط \fB.xz\fP المدمجة مثل XZ Embedded لا تدعم بالضرورة Ø§Ù„Ù…Ù„ÙØ§Øª +المنشأة بأنواع ÙØ­Øµ سلامة (\fIcheck\fP) غير \fBnone\fP Ùˆ\fBcrc32\fP. بما أن الخيار +المبدئي هو \fB\-\-check=crc64\fPØŒ يجب عليك استخدام \fB\-\-check=none\fP أو +\fB\-\-check=crc32\fP عند إنشاء Ù…Ù„ÙØ§Øª للأنظمة المدمجة. +.PP +خارج الأنظمة المدمجة، تدعم جميع Ù…Ùكات ضغط صيغة \fB.xz\fP ÙƒØ§ÙØ© أنواع Ø§Ù„ÙØ­ØµØŒ أو +على الأقل تكون قادرة على ÙÙƒ ضغط المل٠دون التحقق من ÙØ­Øµ السلامة إذا كان ذلك +Ø§Ù„ÙØ­Øµ المحدد غير مدعوم. +.PP +يدعم XZ Embedded مرشحات BCJØŒ ولكن Ùقط مع إزاحة البدء المبدئية. +. +.SH أمثلة +. +.SS أساسيات +ضغط المل٠\fIfoo\fP إلى \fIfoo.xz\fP باستخدام مستوى الضغط المبدئي (\fB\-6\fP)ØŒ وإزالة +\fIfoo\fP إذا نجح الضغط: +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +ÙÙƒ ضغط \fIbar.xz\fP إلى \fIbar\fP وعدم إزالة \fIbar.xz\fP حتى لو نجح ÙÙƒ الضغط: +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +إنشاء \fIbaz.tar.xz\fP بضبط مسبق \fB\-4e\fP (أي \fB\-4 \-\-extreme\fP)ØŒ وهو أبطأ من +الخيار المبدئي \fB\-6\fPØŒ ولكنه يحتاج ذاكرة أقل للضغط ÙˆÙÙƒ الضغط (48 Ù….بايت Ùˆ5 +Ù….بايت على التوالي): +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +يمكن ÙÙƒ ضغط مزيج من Ø§Ù„Ù…Ù„ÙØ§Øª المضغوطة وغير المضغوطة إلى المخرج القياسي بأمر +واحد: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "الضغط المتوازي Ù„Ù…Ù„ÙØ§Øª عديدة" +ÙÙŠ GNU ÙˆBSD*ØŒ يمكن استخدام \fBfind\fP(1) Ùˆ\fBxargs\fP(1) لموازاة ضغط العديد من +Ø§Ù„Ù…Ù„ÙØ§Øª: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +يحدد الخيار \fB\-P\fP ÙÙŠ \fBxargs\fP(1) عدد عمليات \fBxz\fP المتوازية. تعتمد Ø£ÙØ¶Ù„ قيمة +للخيار \fB\-n\fP على عدد Ø§Ù„Ù…Ù„ÙØ§Øª المراد ضغطها. إذا كان هناك Ù…Ù„ÙØ§Ù† Ùقط، ÙŠÙÙØ¶Ù„ أن +تكون القيمة 1Ø› ومع وجود عشرات Ø¢Ù„Ø§Ù Ø§Ù„Ù…Ù„ÙØ§ØªØŒ قد تكون القيمة 100 أو أكثر +مناسبة لتقليل عدد عمليات \fBxz\fP التي سينشئها \fBxargs\fP(1) ÙÙŠ النهاية. +.PP +الخيار \fB\-T1\fP لـ \fBxz\fP موجود لإجباره على وضع الخيط الواحد، لأن \fBxargs\fP(1) +ÙŠÙØ³ØªØ®Ø¯Ù… للتحكم ÙÙŠ كمية الموازاة. +. +.SS "وضع الروبوت" +حساب إجمالي عدد البايتات التي Ø­ÙÙØ¸Øª بعد ضغط Ù…Ù„ÙØ§Øª متعددة: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +قد يرغب برنامج نصي ÙÙŠ Ù…Ø¹Ø±ÙØ© أنه يستخدم نسخة \fBxz\fP حديثة ÙƒÙØ§ÙŠØ©. يتحقق برنامج +\fBsh\fP(1) التالي من أن رقم إصدار أداة \fBxz\fP لا يقل عن 5.0.0. هذه الطريقة +متواÙقة مع النسخ التجريبية القديمة التي لم تكن تدعم خيار \fB\-\-robot\fP: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Your xz is too old." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +ضبط حد استهلاك الذاكرة Ù„ÙÙƒ الضغط باستخدام \fBXZ_OPT\fPØŒ ولكن إذا ÙˆÙØ¶Ø¹ حد +مسبقاً، Ùلا تزده: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "سلاسل مرشحات ضاغط مخصصة" +أبسط استخدام لسلاسل المرشحات المخصصة هو تخصيص ضبط LZMA2 مسبق. يمكن أن يكون +هذا Ù…Ùيداً لأن عمليات الضبط المسبق تغطي Ùقط مجموعة ÙØ±Ø¹ÙŠØ© من مجموعات إعدادات +الضغط المÙيدة المحتملة. +.PP +ØªÙØ¹Ø¯ أعمدة CompCPU ÙÙŠ الجداول الموجودة ÙÙŠ أوصا٠الخيارات \fB\-0\fP ... \fB\-9\fP +Ùˆ\fB\-\-extreme\fP Ù…Ùيدة عند تخصيص إعدادات LZMA2 المسبقة. إليك الأجزاء ذات الصلة +المجموعة من هذين الجدولين: +.RS +.PP +.TS +tab(;); +c c +n n. +المستوى;معالج الضغط +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +إذا كنت تعر٠أن Ù…Ù„ÙØ§Ù‹ يتطلب قاموساً كبيراً نوعاً ما (مثلاً 32 Ù….بايت) Ù„ÙŠÙØ¶ØºØ· +جيداً، ولكنك تريد ضغطه بشكل أسرع مما ÙŠÙØ¹Ù„Ù‡ \fBxz \-8\fPØŒ يمكن تعديل ضبط مسبق +بقيمة CompCPU Ù…Ù†Ø®ÙØ¶Ø© (مثلاً 1) لاستخدام قاموس أكبر: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +مع Ù…Ù„ÙØ§Øª معينة، قد يكون الأمر أعلاه أسرع من \fBxz \-6\fP مع ضغط Ø£ÙØ¶Ù„ بكثير. ومع +ذلك، يجب التأكيد على أن بعض Ø§Ù„Ù…Ù„ÙØ§Øª Ùقط تستÙيد من قاموس كبير مع إبقاء قيمة +CompCPU Ù…Ù†Ø®ÙØ¶Ø©. الحالة الأكثر وضوحاً التي يمكن أن يساعد Ùيها قاموس كبير هي +أرشي٠يحتوي Ù…Ù„ÙØ§Øª متشابهة جداً حجم كل منها بضعة ميجابايتات على الأقل. يجب أن +يكون حجم القاموس أكبر بكثير من أي Ù…Ù„Ù ÙØ±Ø¯ÙŠ Ù„Ù„Ø³Ù…Ø§Ø­ لـ LZMA2 Ø¨Ø§Ù„Ø§Ø³ØªÙØ§Ø¯Ø© +الكاملة من أوجه التشابه بين Ø§Ù„Ù…Ù„ÙØ§Øª المتتالية. +.PP +إذا كان استهلاك الذاكرة العالي جداً للضاغط ومÙكك الضغط مقبولاً، وكان المل٠+المضغوط لا يقل عن عدة مئات من الميجابايتات، Ùقد يكون من المÙيد استخدام قاموس +أكبر حتى من 64 Ù….بايت التي يستخدمها \fBxz \-9\fP: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +يمكن أن يكون استخدام \fB\-vv\fP (أي \fB\-\-verbose \-\-verbose\fP) كما ÙÙŠ المثال أعلاه +Ù…Ùيداً لرؤية متطلبات الذاكرة للضاغط ومÙكك الضغط. تذكر أن استخدام قاموس أكبر +من حجم المل٠غير المضغوط هو هدر للذاكرة، لذا ÙØ¥Ù† الأمر أعلاه ليس Ù…Ùيداً +Ù„Ù„Ù…Ù„ÙØ§Øª الصغيرة. +.PP +أحياناً لا يهم وقت الضغط، ولكن يجب Ø§Ù„Ø­ÙØ§Ø¸ على Ø§Ù†Ø®ÙØ§Ø¶ استهلاك ذاكرة Ù…Ùكك +الضغط، مثلاً لجعل ÙÙƒ ضغط المل٠ممكناً على نظام مدمج. يستخدم الأمر التالي +\fB\-6e\fP (أي \fB\-6 \-\-extreme\fP) كقاعدة ويضبط القاموس على 64 Ùƒ.بايت Ùقط. يمكن ÙÙƒ +ضغط المل٠الناتج باستخدام XZ Embedded (لهذا السبب يوجد \fB\-\-check=crc32\fP) +باستخدام حوالي 100 Ùƒ.بايت من الذاكرة. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +إذا أردت عصر أكبر عدد ممكن من البايتات، ÙØ¥Ù† تعديل عدد بتات سياق الحرو٠+(\fIlc\fP) وعدد بتات الموضع (\fIpb\fP) قد يساعد أحياناً. قد يساعد أيضاً تعديل عدد +بتات موضع الحرو٠(\fIlp\fP)ØŒ ولكن عادة ما تكون \fIlc\fP Ùˆ\fIpb\fP أكثر أهمية. مثلاً، +Ø£Ø±Ø´ÙŠÙ Ø´ÙŠÙØ±Ø© مصدرية يحتوي غالباً نص US\-ASCIIØŒ لذا قد يعطي شيء مثل التالي +Ù…Ù„ÙØ§Ù‹ أصغر قليلاً (بحوالي 0.1 %) من \fBxz \-6e\fP (جرب أيضاً بدون \fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar\fR +.fi +.RE +.PP +استخدام مرشح آخر مع LZMA2 يمكن أن يحسن الضغط مع أنواع Ù…Ù„ÙØ§Øª معينة. مثلاً، +لضغط مكتبة مشتركة x86\-32 أو x86\-64 باستخدام مرشح x86 BCJ: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +لاحظ أن ترتيب خيارات المرشحات مهم. إذا Ø­ÙØ¯Ø¯ \fB\-\-x86\fP بعد \fB\-\-lzma2\fPØŒ Ø³ÙŠÙØ¸Ù‡Ø± +\fBxz\fP خطأ، لأنه لا يمكن وجود أي مرشح بعد LZMA2ØŒ وأيضاً لأن مرشح x86 BCJ لا +يمكن استخدامه كآخر مرشح ÙÙŠ السلسلة. +.PP +يمكن لمرشح دلتا مع LZMA2 إعطاء نتائج جيدة مع الصور النقطية. ÙŠÙÙØªØ±Ø¶ أن يتÙوق +عادةً على PNGØŒ التي تملك مرشحات أكثر تقدماً من دلتا البسيط ولكنها تستخدم +Deflate للضغط Ø§Ù„ÙØ¹Ù„ÙŠ. +.PP +يجب Ø­ÙØ¸ الصورة بصيغة غير مضغوطة، مثلاً كـ TIFF غير مضغوط. ØªÙØ¶Ø¨Ø· معلمة +Ø§Ù„Ù…Ø³Ø§ÙØ© (distance) لمرشح دلتا لتطابق عدد البايتات لكل بكسل ÙÙŠ الصورة. مثلاً، +تحتاج الصورة النقطية RGB بـ 24 بتة إلى \fBdist=3\fPØŒ ومن الجيد أيضاً تمرير +\fBpb=0\fP لـ LZMA2 لمواءمة محاذاة الثلاثة بايتات: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +إذا وضعت صور متعددة ÙÙŠ أرشي٠واحد (مثلاً tar.)ØŒ سيعمل مرشح دلتا على ذلك +أيضاً طالما أن جميع الصور لها Ù†ÙØ³ عدد البايتات لكل بكسل. +. +.SH "انظر أيضاً" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +أدوات XZ: +.br +XZ Embedded: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ar/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzdec.1 new file mode 100644 index 000000000..8537753c7 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzdec.1 @@ -0,0 +1,77 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Arabic translation for xz-man. +.\" Zayed Al-Saidi , 2026. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 2024\-04\-08 توكاني "أدوات XZ" +.SH الاسم +xzdec, lzmadec \- Ù…Ùكات ضغط صغيرة لـ xz. Ùˆ lzma. +.SH موجز +\fBxzdec\fP [\fIخيار...\fP] [\fIملÙ...\fP] +.br +\fBlzmadec\fP [\fIخيار...\fP] [\fIملÙ...\fP] +.SH الوص٠+\fBxzdec\fP هي أداة Ù„ÙÙƒ الضغط Ùقط تعتمد على liblzma Ù„Ù…Ù„ÙØ§Øª \fB.xz\fP (ÙˆÙقط +\&\fB.xz\fP). ÙŠÙقصد من \fBxzdec\fP أن تعمل كبديل جاهز لـ \fBxz\fP(1) ÙÙŠ أكثر الحالات +شيوعاً حيث ÙŠÙكتب البرنامج النصي لاستخدام \fBxz \-\-decompress \-\-stdout\fP (وربما +خيارات شائعة أخرى) Ù„ÙÙƒ ضغط Ù…Ù„ÙØ§Øª \fB.xz\fP. أداة \fBlzmadec\fP مطابقة لـ \fBxzdec\fP +باستثناء أنها تدعم Ù…Ù„ÙØ§Øª \fB.lzma\fP بدلاً من Ù…Ù„ÙØ§Øª \fB.xz\fP. +.PP +لتقليل حجم المل٠القابل للتنÙيذ، لا تدعم \fBxzdec\fP تعدد الخيوط أو التوطين، +ولا تقرأ الخيارات من متغيرات البيئة \fBXZ_DEFAULTS\fP Ùˆ\fBXZ_OPT\fP. كما لا تدعم +\fBxzdec\fP عرض معلومات التقدم الوسيطة: إرسال \fBSIGINFO\fP لـ \fBxzdec\fP لا ÙŠÙØ¹Ù„ +شيئاً، وإرسال \fBSIGUSR1\fP ينهي العملية بدلاً من عرض معلومات التقدم. +.SH خيارات +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +ÙŠÙØªØ¬Ø§Ù‡Ù„ للتواÙÙ‚ مع \fBxz\fP(1). تدعم \fBxzdec\fP ÙÙƒ الضغط Ùقط. +.TP +\fB\-k\fP, \fB\-\-keep\fP +ÙŠÙØªØ¬Ø§Ù‡Ù„ للتواÙÙ‚ مع \fBxz\fP(1). لا تنشئ \fBxzdec\fP أو تزيل أي Ù…Ù„ÙØ§Øª أبداً. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +ÙŠÙØªØ¬Ø§Ù‡Ù„ للتواÙÙ‚ مع \fBxz\fP(1). تكتب \fBxzdec\fP دائماً البيانات المÙكوكة إلى +المخرج القياسي. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +تحديد هذا مرة واحدة لا ÙŠÙØ¹Ù„ شيئاً لأن \fBxzdec\fP لا تعرض أي تحذيرات أو +إشعارات. حدده مرتين لكتم الأخطاء. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +ÙŠÙØªØ¬Ø§Ù‡Ù„ للتواÙÙ‚ مع \fBxz\fP(1). لا تستخدم \fBxzdec\fP حالة الخروج 2 أبداً. +.TP +\fB\-h\fP, \fB\-\-help\fP +عرض رسالة مساعدة والخروج بنجاح. +.TP +\fB\-V\fP, \fB\-\-version\fP +عرض رقم إصدار \fBxzdec\fP Ùˆ liblzma. +.SH "حالة الخروج" +.TP +\fB0\fP +كل شيء كان جيداً. +.TP +\fB1\fP +حدث خطأ. +.PP +لا تملك \fBxzdec\fP أي رسائل تحذير مثل \fBxz\fP(1)ØŒ ولذا لا تستخدم \fBxzdec\fP حالة +الخروج 2. +.SH ملاحظات +استخدم \fBxz\fP(1) بدلاً من \fBxzdec\fP أو \fBlzmadec\fP للاستخدام اليومي +العادي. \fBxzdec\fP أو \fBlzmadec\fP مخصصان Ùقط للحالات التي يكون Ùيها من المهم +توÙير Ù…Ùكك ضغط أصغر حجماً من \fBxz\fP(1) كامل الميزات. +.PP +\fBxzdec\fP Ùˆ \fBlzmadec\fP ليسا صغيرين حقاً. يمكن تقليل الحجم أكثر عن طريق إسقاط +ميزات من liblzma وقت التجميع، لكن لا ينبغي ÙØ¹Ù„ ذلك عادةً Ù„Ù„Ù…Ù„ÙØ§Øª التنÙيذية +الموزعة ÙÙŠ توزيعات أنظمة التشغيل غير المدمجة التقليدية. إذا كنت بحاجة لمÙكك +ضغط \fB.xz\fP صغير حقاً، Ùكر ÙÙŠ استخدام XZ Embedded. +.SH "انظر أيضاً" +\fBxz\fP(1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ar/xzdiff.1 b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzdiff.1 new file mode 100644 index 000000000..79fdefab6 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzdiff.1 @@ -0,0 +1,52 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Arabic translation for xz-man. +.\" Zayed Al-Saidi , 2026. +.\" +.\" (Note that this file is not based on gzip's zdiff.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDIFF 1 2025\-03\-06 توكاني "أدوات XZ" +.SH الاسم +xzcmp, xzdiff, lzcmp, lzdiff \- مقارنة Ø§Ù„Ù…Ù„ÙØ§Øª المضغوطة +. +.SH موجز +\fBxzcmp\fP [\fIخيار...\fP] \fIملÙ1\fP [\fIملÙ2\fP] +.br +\fBxzdiff\fP \&... +.br +\fBlzcmp\fP \&... (مهجور) +.br +\fBlzdiff\fP \&... (مهجور) +. +.SH الوص٠+يقارن \fBxzcmp\fP Ùˆ \fBxzdiff\fP المحتويات غير المضغوطة لملÙين. تÙمرر البيانات غير +المضغوطة والخيارات إلى \fBcmp\fP(1) أو \fBdiff\fP(1) ما لم ÙŠÙØ­Ø¯Ø¯ \fB\-\-help\fP أو +\fB\-\-version\fP. +.PP +إذا Ø­ÙØ¯Ø¯ كل من \fIملÙ1\fP Ùˆ \fIملÙ2\fPØŒ يمكن أن يكونا Ù…Ù„ÙØ§Øª غير مضغوطة أو Ù…Ù„ÙØ§Øª +بصيغ يمكن لكل من \fBxz\fP(1) أو \fBgzip\fP(1) أو \fBbzip2\fP(1) أو \fBlzop\fP(1) أو +\fBzstd\fP(1) أو \fBlz4\fP(1) ÙÙƒ ضغطها. ØªÙØ­Ø¯Ø¯ أوامر ÙÙƒ الضغط المطلوبة من لاحقات +أسماء Ø§Ù„Ù…Ù„ÙØ§Øª. ÙŠÙÙØªØ±Ø¶ أن المل٠ذو اللاحقة غير Ø§Ù„Ù…Ø¹Ø±ÙˆÙØ© إما غير مضغوط أو +بصيغة يمكن لـ \fBxz\fP(1) ÙÙƒ ضغطها. +.PP +إذا ÙˆÙÙØ± اسم مل٠واحد Ùقط، يجب أن يملك \fIملÙ1\fP لاحقة صيغة ضغط مدعومة، +ويÙÙØªØ±Ø¶ أن اسم \fIملÙ2\fP هو \fIملÙ1\fP مع حذ٠لاحقة صيغة الضغط. +.PP +ØªØªÙˆÙØ± أوامر \fBlzcmp\fP Ùˆ \fBlzdiff\fP للتواÙÙ‚ مع أدوات LZMA القديمة. هذه الأوامر +مهجورة ÙˆØ³ØªÙØ­Ø°Ù ÙÙŠ إصدار مستقبلي. +. +.SH "حالة الخروج" +ÙÙŠ حال حدوث خطأ ÙÙŠ ÙÙƒ الضغط، تكون حالة الخروج \fB2\fP. بخلا٠ذلك، ØªÙØ³ØªØ®Ø¯Ù… حالة +خروج \fBcmp\fP(1) أو \fBdiff\fP(1). +. +.SH "انظر أيضاً" +\fBcmp\fP(1), \fBdiff\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), +\fBzstd\fP(1), \fBlz4\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ar/xzgrep.1 b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzgrep.1 new file mode 100644 index 000000000..3dbd58c66 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzgrep.1 @@ -0,0 +1,89 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Arabic translation for xz-man. +.\" Zayed Al-Saidi , 2026. +.\" +.\" (Note that this file is not based on gzip's zgrep.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZGREP 1 2025\-03\-06 توكاني "أدوات XZ" +.SH الاسم +xzgrep \- البحث عن أنماط داخل Ø§Ù„Ù…Ù„ÙØ§Øª التي قد تكون مضغوطة +. +.SH موجز +\fBxzgrep\fP [\fIخيار...\fP] [\fIقائمة_أنماط\fP] [\fIملÙ...\fP] +.br +\fBxzegrep\fP \&... +.br +\fBxzfgrep\fP \&... +.br +\fBlzgrep\fP \&... (مهجور) +.br +\fBlzegrep\fP \&... (مهجور) +.br +\fBlzfgrep\fP \&... (مهجور) +. +.SH الوص٠+يستدعي \fBxzgrep\fP الأداة \fBgrep\fP(1) على المحتويات غير المضغوطة Ù„Ù„Ù…Ù„ÙØ§Øª. ØªÙØ­Ø¯Ø¯ +صيغ \fIØ§Ù„Ù…Ù„ÙØ§Øª\fP من لاحقات أسمائها. أي \fIملÙ\fP بلاحقة يدعمها \fBxz\fP(1) أو +\fBgzip\fP(1) أو \fBbzip2\fP(1) أو \fBlzop\fP(1) أو \fBzstd\fP(1) أو \fBlz4\fP(1) سيجري ÙÙƒ +ضغطه؛ ويÙÙØªØ±Ø¶ أن جميع Ø§Ù„Ù…Ù„ÙØ§Øª الأخرى غير مضغوطة. +.PP +إذا لم ØªÙØ­Ø¯Ø¯ \fIÙ…Ù„ÙØ§Øª\fP أو كان \fIالملÙ\fP هو \fB\-\fPØŒ تÙقرأ المدخلات القياسية. عند +القراءة من المدخلات القياسية، تÙÙÙƒ Ùقط Ø§Ù„Ù…Ù„ÙØ§Øª التي يدعمها \fBxz\fP(1). ÙŠÙÙØªØ±Ø¶ +أن Ø§Ù„Ù…Ù„ÙØ§Øª الأخرى ÙÙŠ صيغتها غير المضغوطة Ø¨Ø§Ù„ÙØ¹Ù„. +.PP +معظم \fIخيارات\fP \fBgrep\fP(1) مدعومة. ومع ذلك، الخيارات التالية غير مدعومة: +.IP "" 4 +\fB\-r\fP, \fB\-\-recursive\fP +.IP "" 4 +\fB\-R\fP, \fB\-\-dereference\-recursive\fP +.IP "" 4 +\fB\-d\fP, \fB\-\-directories=\fP\fIإجراء\fP +.IP "" 4 +\fB\-Z\fP, \fB\-\-null\fP +.IP "" 4 +\fB\-z\fP, \fB\-\-null\-data\fP +.IP "" 4 +\fB\-\-include=\fP\fIنمط\fP +.IP "" 4 +\fB\-\-exclude=\fP\fIنمط\fP +.IP "" 4 +\fB\-\-exclude\-from=\fP\fIملÙ\fP +.IP "" 4 +\fB\-\-exclude\-dir=\fP\fIنمط\fP +.PP +\fBxzegrep\fP هو اسم مستعار لـ \fBxzgrep \-E\fP. Ùˆ \fBxzfgrep\fP هو اسم مستعار لـ +\fBxzgrep \-F\fP. +.PP +أوامر \fBlzgrep\fP Ùˆ \fBlzegrep\fP Ùˆ \fBlzfgrep\fP Ù…ØªÙˆÙØ±Ø© للتواÙÙ‚ مع أدوات LZMA +القديمة. وهي مهجورة ÙˆØ³ØªÙØ­Ø°Ù ÙÙŠ إصدار مستقبلي. +. +.SH "حالة الخروج" +.TP +0 +ÙˆÙØ¬Ø¯Øª مطابقة واحدة على الأقل ÙÙŠ مل٠واحد على الأقل من Ù…Ù„ÙØ§Øª المدخلات. ولم +تحدث أخطاء. +.TP +1 +لم توجد أي مطابقات ÙÙŠ أي من Ù…Ù„ÙØ§Øª المدخلات. ولم تحدث أخطاء. +.TP +>1 +حدث خطأ واحد أو أكثر. من غير المعرو٠ما إذا Ø¹ÙØ«Ø± على مطابقات. +. +.SH البيئة +.TP +\fBGREP\fP +إذا Ø¶ÙØ¨Ø· المتغير \fBGREP\fP على قيمة غير ÙØ§Ø±ØºØ©ØŒ ÙØ³ÙŠÙستخدم بدلاً من \fBgrep\fP أو +\fBgrep \-E\fP أو \fBgrep \-F\fP. +. +.SH "انظر أيضاً" +\fBgrep\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), +\fBlz4\fP(1), \fBzgrep\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ar/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzless.1 new file mode 100644 index 000000000..4833c9ae4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzless.1 @@ -0,0 +1,45 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Arabic translation for xz-man. +.\" Zayed Al-Saidi , 2026. +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 2025\-03\-06 توكاني "أدوات XZ" +.SH الاسم +xzless, lzless \- عرض Ù…Ù„ÙØ§Øª (نصية) مضغوطة بصيغة xz أو lzma +.SH موجز +\fBxzless\fP [\fIملÙ\fP...] +.br +\fBlzless\fP [\fIملÙ\fP...] (مهجور) +.SH الوص٠+\fBxzless\fP هو مرشح يعرض النصوص من Ø§Ù„Ù…Ù„ÙØ§Øª المضغوطة على الطرÙية. تÙÙÙƒ Ø§Ù„Ù…Ù„ÙØ§Øª +التي يدعمها \fBxz\fP(1)Ø› ويÙÙØªØ±Ø¶ أن Ø§Ù„Ù…Ù„ÙØ§Øª الأخرى ÙÙŠ صيغتها غير المضغوطة +Ø¨Ø§Ù„ÙØ¹Ù„. إذا لم ØªÙØ¹Ø·ÙŽ \fIÙ…Ù„ÙØ§Øª\fPØŒ تقرأ \fBxzless\fP من المدخلات القياسية. +.PP +تستخدم \fBxzless\fP الأداة \fBless\fP(1) لعرض مخرجها. وبخلا٠\fBxzmore\fPØŒ لا يمكن +تغيير خيار المستعرض (pager) الخاص بها عن طريق ضبط متغير بيئة. تعتمد الأوامر +على كل من \fBmore\fP(1) Ùˆ \fBvi\fP(1) وتسمح بالتحرك للأمام والخل٠والبحث. انظر +دليل \fBless\fP(1) لمزيد من المعلومات. +.PP +ÙŠØªÙˆÙØ± الأمر \fBlzless\fP للتواÙÙ‚ مع أدوات LZMA القديمة. وهو مهجور ÙˆØ³ÙŠÙØ­Ø°Ù ÙÙŠ +إصدار مستقبلي. +.SH البيئة +.TP +\fBLESSMETACHARS\fP +قائمة من الحرو٠الخاصة Ø¨Ø§Ù„ØµØ¯ÙØ© (shell). تضبطها \fBxzless\fP ما لم تكن مضبوطة +Ø¨Ø§Ù„ÙØ¹Ù„ ÙÙŠ البيئة. +.TP +\fBLESSOPEN\fP +ÙŠÙØ¶Ø¨Ø· على سطر أوامر لاستدعاء Ù…Ùكك ضغط \fBxz\fP(1) للمعالجة المسبقة Ù„Ù…Ù„ÙØ§Øª +المدخلات قبل تمريرها لـ \fBless\fP(1). +.SH "انظر أيضاً" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ar/xzmore.1 b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzmore.1 new file mode 100644 index 000000000..19a989b6a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ar/xzmore.1 @@ -0,0 +1,47 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Arabic translation for xz-man. +.\" Zayed Al-Saidi , 2026. +.\" +.\" (Note that this file is based on xzless.1 instead of gzip's zmore.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZMORE 1 2025\-03\-06 توكاني "أدوات XZ" +.SH الاسم +xzmore, lzmore \- عرض Ù…Ù„ÙØ§Øª (نصية) مضغوطة بصيغة xz أو lzma +. +.SH موجز +\fBxzmore\fP [\fIملÙ\fP...] +.br +\fBlzmore\fP [\fIملÙ\fP...] (مهجور) +. +.SH الوص٠+تعرض \fBxzmore\fP النصوص من Ø§Ù„Ù…Ù„ÙØ§Øª المضغوطة على الطرÙية باستخدام +\fBmore\fP(1). تÙÙÙƒ Ø§Ù„Ù…Ù„ÙØ§Øª التي يدعمها \fBxz\fP(1)Ø› ويÙÙØªØ±Ø¶ أن Ø§Ù„Ù…Ù„ÙØ§Øª الأخرى ÙÙŠ +صيغتها غير المضغوطة Ø¨Ø§Ù„ÙØ¹Ù„. إذا لم ØªÙØ¹Ø·ÙŽ \fIÙ…Ù„ÙØ§Øª\fPØŒ تقرأ \fBxzmore\fP من +المدخلات القياسية. انظر دليل \fBmore\fP(1) Ù„Ù…Ø¹Ø±ÙØ© أوامر لوحة Ø§Ù„Ù…ÙØ§ØªÙŠØ­. +.PP +لاحظ أن التمرير للخل٠قد لا يكون ممكناً اعتماداً على تنÙيذ \fBmore\fP(1). وذلك +لأن \fBxzmore\fP تستخدم أنبوباً لتمرير البيانات المÙكوكة إلى \fBmore\fP(1). بينما +تستخدم \fBxzless\fP(1) الأداة \fBless\fP(1) التي ØªÙˆÙØ± ميزات أكثر تقدماً. +.PP +ÙŠØªÙˆÙØ± الأمر \fBlzmore\fP للتواÙÙ‚ مع أدوات LZMA القديمة. وهو مهجور ÙˆØ³ÙŠÙØ­Ø°Ù ÙÙŠ +إصدار مستقبلي. +. +.SH البيئة +.TP +.\" TRANSLATORS: Don't translate the uppercase PAGER. +.\" It is a name of an environment variable. +\fBPAGER\fP +إذا Ø¶ÙØ¨Ø· المتغير \fBPAGER\fPØŒ ÙØ³ØªÙستخدم قيمته كمستعرض (pager) بدلاً من +\fBmore\fP(1). +. +.SH "انظر أيضاً" +\fBmore\fP(1), \fBxz\fP(1), \fBxzless\fP(1), \fBzmore\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/de/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/de/lzmainfo.1 new file mode 100644 index 000000000..10eba6fb5 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/de/lzmainfo.1 @@ -0,0 +1,46 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" German translation for xz-man. +.\" Mario Blättermann , 2015, 2019-2020, 2022-2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 "30. Juni 2013" Tukaani XZ\-Dienstprogramme +.SH BEZEICHNUNG +lzmainfo \- im .lzma\-Dateikopf enthaltene Informationen anzeigen +.SH ÜBERSICHT +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fIDatei …\fP] +.SH BESCHREIBUNG +\fBlzmainfo\fP zeigt die im \fB.lzma\fP\-Dateikopf enthaltenen Informationen an. Es +liest die ersten 13 Bytes aus der angegebenen \fIDatei\fP, dekodiert den +Dateikopf und gibt das Ergebnis in die Standardausgabe in einem +menschenlesbaren Format aus. Falls keine \fIDatei\fPen angegeben werden oder +die \fIDatei\fP als \fB\-\fP übergeben wird, dann wird aus der Standardeingabe +gelesen. +.PP +In der Regel sind die unkomprimierte Größe der Daten und die Größe des +Wörterbuchs am bedeutsamsten. Die unkomprimierte Größe kann nur dann +angezeigt werden, wenn die Datei im \fB.lzma\fP\-Format kein Datenstrom ist. Die +Größe des für die Dekompression nötigen Speichers beträgt einige Dutzend +Kilobyte zuzüglich der Größe des Inhaltsverzeichnisses. +.PP +\fBlzmainfo\fP ist in den XZ\-Dienstprogrammen hauptsächlich zur Kompatibilität +zu den LZMA\-Dienstprogrammen enthalten. +.SH EXIT\-STATUS +.TP +\fB0\fP +Alles ist in Ordnung. +.TP +\fB1\fP +Ein Fehler ist aufgetreten. +.SH FEHLER +\fBlzmainfo\fP verwendet \fBMB\fP, während das korrekte Suffix \fBMiB\fP (2^20 Bytes) +wäre. Damit wird die Kompatibilität zu den LZMA\-Dienstprogrammen +gewährleistet. +.SH "SIEHE AUCH" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/de/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/de/xz.1 new file mode 100644 index 000000000..39e92ce91 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/de/xz.1 @@ -0,0 +1,2117 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" German translation for xz-man. +.\" Mario Blättermann , 2015, 2019-2020, 2022-2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 "8. März 2025" Tukaani XZ\-Dienstprogramme +. +.SH BEZEICHNUNG +xz, unxz, xzcat, lzma, unlzma, lzcat \- .xz\- und .lzma\-Dateien komprimieren +oder dekomprimieren +. +.SH ÜBERSICHT +\fBxz\fP [\fIOption…\fP] [\fIDatei…\fP] +. +.SH BEFEHLSALIASE +\fBunxz\fP ist gleichbedeutend mit \fBxz \-\-decompress\fP. +.br +\fBxzcat\fP ist gleichbedeutend mit \fBxz \-\-decompress \-\-stdout\fP. +.br +\fBlzma\fP ist gleichbedeutend mit \fBxz \-\-format=lzma\fP. +.br +\fBunlzma\fP ist gleichbedeutend mit \fBxz \-\-format=lzma \-\-decompress\fP. +.br +\fBlzcat\fP ist gleichbedeutend mit \fBxz \-\-format=lzma \-\-decompress \-\-stdout\fP. +.PP +Wenn Sie Skripte schreiben, die Dateien dekomprimieren, sollten Sie stets +den Namen \fBxz\fP mit den entsprechenden Argumenten (\fBxz \-d\fP oder \fBxz \-dc\fP) +anstelle der Namen \fBunxz\fP und \fBxzcat\fP verwenden. +. +.SH BESCHREIBUNG +\fBxz\fP ist ein Allzweckwerkzeug zur Datenkompression, dessen +Befehlszeilensyntax denen von \fBgzip\fP(1) und \fBbzip2\fP(1) ähnelt. Das native +Dateiformat ist das \fB.xz\fP\-Format, aber das veraltete, von den +LZMA\-Dienstprogrammen verwendete Format sowie komprimierte Rohdatenströme +ohne Containerformat\-Header werden ebenfalls unterstützt. Außerdem wird die +Dekompression des von \fBlzip\fP verwendeten \fB.lz\fP\-Formats unterstützt. +.PP +\fBxz\fP komprimiert oder dekomprimiert jede \fIDatei\fP entsprechend des +gewählten Vorgangsmodus. Falls entweder \fB\-\fP oder keine Datei angegeben ist, +liest \fBxz\fP aus der Standardeingabe und leitet die verarbeiteten Dateien in +die Standardausgabe. Wenn die Standardausgabe kein Terminal ist, verweigert +\fBxz\fP das Schreiben komprimierter Daten in die Standardausgabe. Dabei wird +eine Fehlermeldung angezeigt und die \fIDatei\fP übersprungen. Ebenso +verweigert \fBxz\fP das Lesen komprimierter Daten aus der Standardeingabe, wenn +diese ein Terminal ist. +.PP +\fIDateien\fP, die nicht als \fB\-\fP angegeben sind, werden in eine neue Datei +geschrieben, deren Name aus dem Namen der Quell\-\fIDatei\fP abgeleitet wird +(außer wenn \fB\-\-stdout\fP angegeben ist): +.IP \(bu 3 +Bei der Kompression wird das Suffix des Formats der Zieldatei (\fB.xz\fP oder +\&\fB.lzma\fP) an den Namen der Quelldatei angehängt und so der Name der +Zieldatei gebildet. +.IP \(bu 3 +Bei der Dekompression wird das Suffix \fB.xz\fP, \fB.lzma\fP oder \fB.lz\fP vom +Dateinamen entfernt und so der Name der Zieldatei gebildet. Außerdem erkennt +\fBxz\fP die Suffixe \fB.txz\fP und \fB.tlz\fP und ersetzt diese durch \fB.tar\fP. +.PP +Wenn die Zieldatei bereits existiert, wird eine Fehlermeldung angezeigt und +die \fIDatei\fP übersprungen. +.PP +Außer beim Schreiben in die Standardausgabe zeigt \fBxz\fP eine Warnung an und +überspringt die \fIDatei\fP, wenn eine der folgenden Bedingungen zutreffend +ist: +.IP \(bu 3 +Die \fIDatei\fP ist keine reguläre Datei. Symbolischen Verknüpfungen wird nicht +gefolgt und diese daher nicht zu den regulären Dateien gezählt. +.IP \(bu 3 +Die \fIDatei\fP hat mehr als eine harte Verknüpfung. +.IP \(bu 3 +Für die \fIDatei\fP ist das »setuid«\-, »setgid«\- oder »sticky«\-Bit gesetzt. +.IP \(bu 3 +Der Aktionsmodus wird auf Kompression gesetzt und die \fIDatei\fP hat bereits +das Suffix des Zieldateiformats (\fB.xz\fP oder \fB.txz\fP beim Komprimieren in +das \fB.xz\fP\-Format und \fB.lzma\fP oder \fB.tlz\fP beim Komprimieren in das +\&\fB.lzma\fP\-Format). +.IP \(bu 3 +Der Aktionsmodus wird auf Dekompression gesetzt und die \fIDatei\fP hat nicht +das Suffix eines der unterstützten Zieldateiformate (\fB.xz\fP, \fB.txz\fP, +\&\fB.lzma\fP, \fB.tlz\fP oder \fB.lz\fP). +.PP +Nach erfolgreicher Kompression oder Dekompression der \fIDatei\fP kopiert \fBxz\fP +Eigentümer, Gruppe, Zugriffsrechte, Zugriffszeit und Änderungszeit aus der +Ursprungs\-\fIDatei\fP in die Zieldatei. Sollte das Kopieren der Gruppe +fehlschlagen, werden die Zugriffsrechte so angepasst, dass jenen Benutzern +der Zugriff auf die Zieldatei verwehrt bleibt, die auch keinen Zugriff auf +die Ursprungs\-\fIDatei\fP hatten. Das Kopieren anderer Metadaten wie +Zugriffssteuerlisten oder erweiterter Attribute wird von \fBxz\fP noch nicht +unterstützt. +.PP +Sobald die Zieldatei erfolgreich geschlossen wurde, wird die +Ursprungs\-\fIDatei\fP entfernt. Dies wird durch die Option \fB\-\-keep\fP +verhindert. Die Ursprungs\-\fIDatei\fP wird niemals entfernt, wenn die Ausgabe +in die Standardausgabe geschrieben wird oder falls ein Fehler auftritt. +.PP +Durch Senden der Signale \fBSIGINFO\fP oder \fBSIGUSR1\fP an den \fBxz\fP\-Prozess +werden Fortschrittsinformationen in den Fehlerkanal der Standardausgabe +geleitet. Dies ist nur eingeschränkt hilfreich, wenn die +Standardfehlerausgabe ein Terminal ist. Mittels \fB\-\-verbose\fP wird ein +automatisch aktualisierter Fortschrittsanzeiger angezeigt. +. +.SS Speicherbedarf +In Abhängigkeit von den gewählten Kompressionseinstellungen bewegt sich der +Speicherverbrauch zwischen wenigen hundert Kilobyte und mehreren +Gigabyte. Die Einstellungen bei der Kompression einer Datei bestimmen dabei +den Speicherbedarf bei der Dekompression. Die Dekompression benötigt +üblicherweise zwischen 5\ % und 20\ % des Speichers, der bei der Kompression +der Datei erforderlich war. Beispielsweise benötigt die Dekompression einer +Datei, die mit \fBxz \-9\fP komprimiert wurde, gegenwärtig etwa 65\ MiB +Speicher. Es ist jedoch auch möglich, dass \fB.xz\fP\-Dateien mehrere Gigabyte +an Speicher zur Dekompression erfordern. +.PP +Insbesondere für Benutzer älterer Systeme wird eventuell ein sehr großer +Speicherbedarf ärgerlich sein. Um unangenehme Überraschungen zu vermeiden, +verfügt \fBxz\fP über eine eingebaute Begrenzung des Speicherbedarfs, die +allerdings in der Voreinstellung deaktiviert ist. Zwar verfügen einige +Betriebssysteme über eingebaute Möglichkeiten zur prozessabhängigen +Speicherbegrenzung, doch diese sind zu unflexibel (zum Beispiel kann +\fBulimit\fP(1) beim Begrenzen des virtuellen Speichers \fBmmap\fP(2) +beeinträchtigen). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +Die Begrenzung des Speicherbedarfs kann mit der Befehlszeilenoption +\fB\-\-memlimit=\fP\fIBegrenzung\fP aktiviert werden. Oft ist es jedoch bequemer, +die Begrenzung durch Setzen der Umgebungsvariable \fBXZ_DEFAULTS\fP +standardmäßig zu aktivieren, zum Beispiel +\fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP. Die Begrenzungen können getrennt für +Kompression und Dekompression mittels \fB\-\-memlimit\-compress=\fP\fIBegrenzung\fP +und \fB\-\-memlimit\-decompress=\fP\fIBegrenzung\fP festgelegt werden. Die Verwendung +einer solchen Option außerhalb der Variable \fBXZ_DEFAULTS\fP ist kaum +sinnvoll, da \fBxz\fP in einer einzelnen Aktion nicht gleichzeitig Kompression +und Dekompression ausführen kann und \fB\-\-memlimit=\fP\fIBegrenzung\fP (oder \fB\-M\fP +\fIBegrenzung\fP) lässt sich einfacher in der Befehlszeile eingeben. +.PP +Wenn die angegebene Speicherbegrenzung bei der Dekompression überschritten +wird, schlägt der Vorgang fehl und \fBxz\fP zeigt eine Fehlermeldung an. Wird +die Begrenzung bei der Kompression überschritten, dann versucht \fBxz\fP die +Einstellungen entsprechend anzupassen, außer wenn \fB\-\-format=raw\fP oder +\fB\-\-no\-adjust\fP angegeben ist. Auf diese Weise schlägt die Aktion nicht fehl, +es sei denn, die Begrenzung wurde sehr niedrig angesetzt. Die Anpassung der +Einstellungen wird schrittweise vorgenommen, allerdings entsprechen die +Schritte nicht den Voreinstellungen der Kompressionsstufen. Das bedeutet, +wenn beispielsweise die Begrenzung nur geringfügig unter den Anforderungen +für \fBxz \-9\fP liegt, werden auch die Einstellungen nur wenig angepasst und +nicht vollständig herunter zu den Werten für \fBxz \-8\fP +. +.SS "Verkettung und Auffüllung von .xz\-Dateien" +Es ist möglich, \fB.xz\fP\-Dateien direkt zu verketten. Solche Dateien werden +von \fBxz\fP genauso dekomprimiert wie eine einzelne \fB.xz\fP\-Datei. +.PP +Es ist weiterhin möglich, eine Auffüllung zwischen den verketteten Teilen +oder nach dem letzten Teil einzufügen. Die Auffüllung muss aus Null\-Bytes +bestehen und deren Größe muss ein Vielfaches von vier Byte sein. Dies kann +zum Beispiel dann vorteilhaft sein, wenn die \fB.xz\fP\-Datei auf einem +Datenträger gespeichert wird, dessen Dateisystem die Dateigrößen in +512\-Byte\-Blöcken speichert. +.PP +Verkettung und Auffüllung sind für \fB.lzma\fP\-Dateien oder Rohdatenströme +nicht erlaubt. +. +.SH OPTIONEN +. +.SS "Ganzzahlige Suffixe und spezielle Werte" +An den meisten Stellen, wo ein ganzzahliges Argument akzeptiert wird, kann +ein optionales Suffix große Ganzzahlwerte einfacher darstellen. Zwischen +Ganzzahl und dem Suffix dürfen sich keine Leerzeichen befinden. +.TP +\fBKiB\fP +multipliziert die Ganzzahl mit 1.024 (2^10). \fBKi\fP, \fBk\fP, \fBkB\fP, \fBK\fP und +\fBKB\fP werden als Synonyme für \fBKiB\fP akzeptiert. +.TP +\fBMiB\fP +multipliziert die Ganzzahl mit 1.048.576 (2^20). \fBMi\fP, \fBm\fP, \fBM\fP und \fBMB\fP +werden als Synonyme für \fBMiB\fP akzeptiert. +.TP +\fBGiB\fP +multipliziert die Ganzzahl mit 1.073.741.824 (2^30). \fBGi\fP, \fBg\fP, \fBG\fP und +\fBGB\fP werden als Synonyme für \fBGiB\fP akzeptiert. +.PP +Der spezielle Wert \fBmax\fP kann dazu verwendet werden, um den von der +jeweiligen Option akzeptierten maximalen Ganzzahlwert anzugeben. +. +.SS Aktionsmodus +Falls mehrere Aktionsmodi angegeben sind, wird der zuletzt angegebene +verwendet. +.TP +\fB\-z\fP, \fB\-\-compress\fP +Kompression. Dies ist der voreingestellte Aktionsmodus, sofern keiner +angegeben ist und auch kein bestimmter Modus aus dem Befehlsnamen abgeleitet +werden kann (der Befehl \fBunxz\fP impliziert zum Beispiel \fB\-\-decompress\fP). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Nach erfolgreicher Kompression wird die Quelldatei gelöscht, außer wenn in +die Standardausgabe geschrieben wird oder \fB\-\-keep\fP angegeben wurde. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Dekomprimieren. Nach erfolgreicher Dekompression wird die Quelldatei +gelöscht, außer wenn in die Standardausgabe geschrieben wird oder \fB\-\-keep\fP +angegeben wurde. +.TP +\fB\-t\fP, \fB\-\-test\fP +prüft die Integrität der komprimierten \fIDateien\fP. Diese Option ist +gleichbedeutend mit \fB\-\-decompress \-\-stdout\fP, außer dass die dekomprimierten +Daten verworfen werden, anstatt sie in die Standardausgabe zu leiten. Es +werden keine Dateien erstellt oder entfernt. +.TP +\fB\-l\fP, \fB\-\-list\fP +gibt Informationen zu den komprimierten \fIDateien\fP aus. Es werden keine +unkomprimierten Dateien ausgegeben und keine Dateien angelegt oder +entfernt. Im Listenmodus kann das Programm keine komprimierten Daten aus der +Standardeingabe oder anderen nicht durchsuchbaren Quellen lesen. +.IP "" +Die Liste zeigt in der Standardeinstellung grundlegende Informationen zu den +\fIDateien\fP an, zeilenweise pro Datei. Detailliertere Informationen erhalten +Sie mit der Option \fB\-\-verbose\fP. Wenn Sie diese Option zweimal angeben, +werden noch ausführlichere Informationen ausgegeben. Das kann den Vorgang +allerdings deutlich verlangsamen, da die Ermittlung der zusätzlichen +Informationen zahlreiche Suchvorgänge erfordert. Die Breite der +ausführlichen Ausgabe übersteigt 80 Zeichen, daher könnte die Weiterleitung +in beispielsweise\& \fBless\ \-S\fP sinnvoll sein, falls das Terminal nicht +breit genug ist. +.IP "" +Die exakte Ausgabe kann in verschiedenen \fBxz\fP\-Versionen und +Spracheinstellungen unterschiedlich sein. Wenn eine maschinell auswertbare +Ausgabe gewünscht ist, dann sollten Sie \fB\-\-robot \-\-list\fP verwenden. +. +.SS Aktionsattribute +.TP +\fB\-k\fP, \fB\-\-keep\fP +verhindert das Löschen der Eingabedateien. +.IP "" +Seit der \fBxz\fP\-Version 5.2.6 wird die Kompression oder Dekompression auch +dann ausgeführt, wenn die Eingabe ein symbolischer Link zu einer regulären +Datei ist, mehr als einen harten Link hat oder das »setuid«\-, »setgid«\- oder +»sticky«\-Bit gesetzt ist. Die genannten Bits werden nicht in die Zieldatei +kopiert. In früheren Versionen geschah dies nur mit \fB\-\-force\fP. +.TP +\fB\-f\fP, \fB\-\-force\fP +Diese Option hat verschiedene Auswirkungen: +.RS +.IP \(bu 3 +Wenn die Zieldatei bereits existiert, wird diese vor der Kompression oder +Dekompression gelöscht. +.IP \(bu 3 +Die Kompression oder Dekompression wird auch dann ausgeführt, wenn die +Eingabe ein symbolischer Link zu einer regulären Datei ist, mehr als einen +harten Link hat oder das »setuid«\-, »setgid«\- oder »sticky«\-Bit gesetzt +ist. Die genannten Bits werden nicht in die Zieldatei kopiert. +.IP \(bu 3 +Wenn es zusammen mit \fB\-\-decompress\fP und \fB\-\-stdout\fP verwendet wird und +\fBxz\fP den Typ der Quelldatei nicht ermitteln kann, wird die Quelldatei +unverändert in die Standardausgabe kopiert. Dadurch kann \fBxzcat\fP \fB\-\-force\fP +für Dateien, die nicht mit \fBxz\fP komprimiert wurden, wie \fBcat\fP(1) verwendet +werden. Zukünftig könnte \fBxz\fP neue Dateikompressionsformate unterstützen, +wodurch \fBxz\fP mehr Dateitypen dekomprimieren kann, anstatt sie unverändert +in die Standardausgabe zu kopieren. Mit der Option \fB\-\-format=\fP\fIFormat\fP +können Sie \fBxz\fP anweisen, nur ein einzelnes Dateiformat zu dekomprimieren. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +schreibt die komprimierten oder dekomprimierten Daten in die Standardausgabe +anstatt in eine Datei. Dies impliziert \fB\-\-keep\fP. +.TP +\fB\-\-single\-stream\fP +dekomprimiert nur den ersten \fB.xz\fP\-Datenstrom und ignoriert stillschweigend +weitere Eingabedaten, die möglicherweise dem Datenstrom +folgen. Normalerweise führt solcher anhängender Datenmüll dazu, dass \fBxz\fP +eine Fehlermeldung ausgibt. +.IP "" +\fBxz\fP dekomprimiert niemals mehr als einen Datenstrom aus \fB.lzma\fP\-Dateien +oder Rohdatenströmen, aber dennoch wird durch diese Option möglicherweise +vorhandener Datenmüll nach der \fB.lzma\fP\-Datei oder dem Rohdatenstrom +ignoriert. +.IP "" +Diese Option ist wirkungslos, wenn der Aktionsmodus nicht \fB\-\-decompress\fP +oder \fB\-\-test\fP ist. +.IP "" +Seit der Programmversion \fBxz\fP 5.7.1alpha impliziert \fB\-\-single\-stream\fP +zusätzlich die Option \fB\-\-keep\fP. +.TP +\fB\-\-no\-sparse\fP +verhindert die Erzeugung von Sparse\-Dateien. In der Voreinstellung versucht +\fBxz\fP, bei der Dekompression in eine reguläre Datei eine Sparse\-Datei zu +erzeugen, wenn die dekomprimierten Daten lange Abfolgen von binären Nullen +enthalten. Dies funktioniert auch beim Schreiben in die Standardausgabe, +sofern diese in eine reguläre Datei weitergeleitet wird und bestimmte +Zusatzbedingungen erfüllt sind, die die Aktion absichern. Die Erzeugung von +Sparse\-Dateien kann Plattenplatz sparen und beschleunigt die Dekompression +durch Verringerung der Ein\-/Ausgaben der Platte. +.TP +\fB\-S\fP \fI.suf\fP, \fB\-\-suffix=\fP\fI.suf\fP +verwendet \fI.suf\fP bei der Dekompression anstelle von \fB.xz\fP oder \fB.lzma\fP +als Suffix für die Zieldatei. Falls nicht in die Standardausgabe geschrieben +wird und die Quelldatei bereits das Suffix \fI.suf\fP hat, wird eine Warnung +angezeigt und die Datei übersprungen. +.IP "" +berücksichtigt bei der Dekompression zusätzlich zu Dateien mit den Suffixen +\&\fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP oder \fB.lz\fP auch jene mit dem Suffix +\&\fI.suf\fP. Falls die Quelldatei das Suffix \fI.suf\fP hat, wird dieses entfernt +und so der Name der Zieldatei abgeleitet. +.IP "" +Beim Komprimieren oder Dekomprimieren von Rohdatenströmen mit +\fB\-\-format=raw\fP muss das Suffix stets angegeben werden, außer wenn die +Ausgabe in die Standardausgabe erfolgt. Der Grund dafür ist, dass es kein +vorgegebenes Suffix für Rohdatenströme gibt. +.TP +\fB\-\-files\fP[\fB=\fP\fIDatei\fP] +liest die zu verarbeitenden Dateinamen aus \fIDatei\fP. Falls keine \fIDatei\fP +angegeben ist, werden die Dateinamen aus der Standardeingabe +gelesen. Dateinamen müssen mit einem Zeilenumbruch beendet werden. Ein +Bindestrich (\fB\-\fP) wird als regulärer Dateiname angesehen und nicht als +Standardeingabe interpretiert. Falls Dateinamen außerdem als +Befehlszeilenargumente angegeben sind, werden diese vor den Dateinamen aus +der \fIDatei\fP verarbeitet. +.TP +\fB\-\-files0\fP[\fB=\fP\fIDatei\fP] +Dies ist gleichbedeutend mit \fB\-\-files\fP[\fB=\fP\fIDatei\fP], außer dass jeder +Dateiname mit einem Null\-Zeichen abgeschlossen werden muss. +. +.SS "Grundlegende Dateiformat\- und Kompressionsoptionen" +.TP +\fB\-F\fP \fIFormat\fP, \fB\-\-format=\fP\fIFormat\fP +gibt das \fIFormat\fP der zu komprimierenden oder dekomprimierenden Datei an: +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +Dies ist die Voreinstellung. Bei der Kompression ist \fBauto\fP gleichbedeutend +mit \fBxz\fP. Bei der Dekompression wird das Format der Eingabedatei +automatisch erkannt. Beachten Sie, dass Rohdatenströme, wie sie mit +\fB\-\-format=raw\fP erzeugt werden, nicht automatisch erkannt werden können. +.TP +\fBxz\fP +Die Kompression erfolgt in das \fB.xz\fP\-Dateiformat oder akzeptiert nur +\&\fB.xz\fP\-Dateien bei der Dekompression. +.TP +\fBlzma\fP, \fBalone\fP +Die Kompression erfolgt in das veraltete \fB.lzma\fP\-Dateiformat oder +akzeptiert nur \fB.lzma\fP\-Dateien bei der Dekompression. Der alternative Name +\fBalone\fP dient der Abwärtskompatibilität zu den LZMA\-Dienstprogrammen. +.TP +\fBlzip\fP +Akzeptiert nur \fB.lz\fP\-Dateien bei der Dekompression. Kompression wird nicht +unterstützt. +.IP "" +The \fB.lz\fP format versions 0 and 1 are supported. Version 0 files were +produced by \fBlzip\fP 1.3 and older. Such files aren't common but may be +found from file archives as a few source packages were released in this +format. People might have old personal files in this format too. +Decompression support for the format version 0 was removed in \fBlzip\fP 1.18. +\fBlzip\fP 1.4 and later create files in the format version 1. +.TP +\fBraw\fP +Komprimiert oder dekomprimiert einen Rohdatenstrom (ohne Header). Diese +Option ist nur für fortgeschrittene Benutzer bestimmt. Zum Dekodieren von +Rohdatenströmen müssen Sie die Option \fB\-\-format=raw\fP verwenden und die +Filterkette ausdrücklich angeben, die normalerweise in den (hier fehlenden) +Container\-Headern gespeichert worden wäre. +.RE +.TP +\fB\-C\fP \fIPrüfung\fP, \fB\-\-check=\fP\fIPrüfung\fP +gibt den Typ der Integritätsprüfung an. Die Prüfsumme wird aus den +unkomprimierten Daten berechnet und in der \fB.xz\fP\-Datei gespeichert. Diese +Option wird nur bei der Kompression in das \fB.xz\fP\-Format angewendet, da das +\&\fB.lzma\fP\-Format keine Integritätsprüfungen unterstützt. Die eigentliche +Integritätsprüfung erfolgt (falls möglich), wenn die \fB.xz\fP\-Datei +dekomprimiert wird. +.IP "" +Folgende Typen von \fIPrüfungen\fP werden unterstützt: +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +führt keine Integritätsprüfung aus. Dies ist eine eher schlechte +Idee. Dennoch kann es nützlich sein, wenn die Integrität der Daten auf +andere Weise sichergestellt werden kann. +.TP +\fBcrc32\fP +berechnet die CRC32\-Prüfsumme anhand des Polynoms aus IEEE\-802.3 (Ethernet). +.TP +\fBcrc64\fP +berechnet die CRC64\-Prüfsumme anhand des Polynoms aus ECMA\-182. Dies ist die +Voreinstellung, da beschädigte Dateien etwas besser als mit CRC32 erkannt +werden und die Geschwindigkeitsdifferenz unerheblich ist. +.TP +\fBsha256\fP +berechnet die SHA\-256\-Prüfsumme. Dies ist etwas langsamer als CRC32 und +CRC64. +.RE +.IP "" +Die Integrität der \fB.xz\fP\-Header wird immer mit CRC32 geprüft. Es ist nicht +möglich, dies zu ändern oder zu deaktivieren. +.TP +\fB\-\-ignore\-check\fP +verifiziert die Integritätsprüfsumme der komprimierten Daten bei der +Dekompression nicht. Die CRC32\-Werte in den \fB.xz\fP\-Headern werden weiterhin +normal verifiziert. +.IP "" +\fBVerwenden Sie diese Option nicht, außer Sie wissen, was Sie tun.\fP Mögliche +Gründe, diese Option zu verwenden: +.RS +.IP \(bu 3 +Versuchen, Daten aus einer beschädigten .xz\-Datei wiederherzustellen. +.IP \(bu 3 +Erhöhung der Geschwindigkeit bei der Dekompression. Dies macht sich meist +mit SHA\-256 bemerkbar, oder mit Dateien, die extrem stark komprimiert +sind. Wir empfehlen, diese Option nicht für diesen Zweck zu verwenden, es +sei denn, die Integrität der Datei wird extern auf andere Weise überprüft. +.RE +.TP +\fB\-0\fP … \fB\-9\fP +wählt eine der voreingestellten Kompressionsstufen, standardmäßig +\fB\-6\fP. Wenn mehrere Voreinstellungsstufen angegeben sind, ist nur die +zuletzt angegebene wirksam. Falls bereits eine benutzerdefinierte +Filterkette angegeben wurde, wird diese durch die Festlegung der +Voreinstellung geleert. +.IP "" +Die Unterschiede zwischen den Voreinstellungsstufen sind deutlicher als bei +\fBgzip\fP(1) und \fBbzip2\fP(1). Die gewählten Kompressionseinstellungen +bestimmen den Speicherbedarf bei der Dekompression, daher ist es auf älteren +Systemen mit wenig Speicher bei einer zu hoch gewählten Voreinstellung +schwer, eine Datei zu dekomprimieren. Insbesondere \fBist es keine gute Idee, blindlings \-9 für alles\fP zu verwenden, wie dies häufig mit \fBgzip\fP(1) und +\fBbzip2\fP(1) gehandhabt wird. +.RS +.TP +\fB\-0\fP … \fB\-3\fP +Diese Voreinstellungen sind recht schnell. \fB\-0\fP ist manchmal schneller als +\fBgzip \-9\fP, wobei aber die Kompression wesentlich besser ist. Die +schnelleren Voreinstellungen sind im Hinblick auf die Geschwindigkeit mit +\fBbzip2\fP(1) vergleichbar , mit einem ähnlichen oder besseren +Kompressionsverhältnis, wobei das Ergebnis aber stark vom Typ der zu +komprimierenden Daten abhängig ist. +.TP +\fB\-4\fP … \fB\-6\fP +Gute bis sehr gute Kompression, wobei der Speicherbedarf für die +Dekompression selbst auf alten Systemen akzeptabel ist. \fB\-6\fP ist die +Voreinstellung, welche üblicherweise eine gute Wahl für die Verteilung von +Dateien ist, die selbst noch auf Systemen mit nur 16\ MiB Arbeitsspeicher +dekomprimiert werden müssen (\fB\-5e\fP oder \fB\-6e\fP sind ebenfalls eine +Überlegung wert. Siehe \fB\-\-extreme\fP). +.TP +\fB\-7 … \-9\fP +Ähnlich wie \fB\-6\fP, aber mit einem höheren Speicherbedarf für die Kompression +und Dekompression. Sie sind nur nützlich, wenn Dateien komprimiert werden +sollen, die größer als 8\ MiB, 16\ MiB beziehungsweise 32\ MiB sind. +.RE +.IP "" +Auf der gleichen Hardware ist die Dekompressionsgeschwindigkeit ein nahezu +konstanter Wert in Bytes komprimierter Daten pro Sekunde. Anders +ausgedrückt: Je besser die Kompression, umso schneller wird üblicherweise +die Dekompression sein. Das bedeutet auch, dass die Menge der pro Sekunde +ausgegebenen unkomprimierten Daten stark variieren kann. +.IP "" +Die folgende Tabelle fasst die Eigenschaften der Voreinstellungen zusammen: +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Voreinst.;Wörtb.Gr;KomprCPU;KompSpeich;DekompSpeich +\-0;256 KiB;0;3 MiB;1 MiB +\-1;1 MiB;1;9 MiB;2 MiB +\-2;2 MiB;2;17 MiB;3 MiB +\-3;4 MiB;3;32 MiB;5 MiB +\-4;4 MiB;4;48 MiB;5 MiB +\-5;8 MiB;5;94 MiB;9 MiB +\-6;8 MiB;6;94 MiB;9 MiB +\-7;16 MiB;6;186 MiB;17 MiB +\-8;32 MiB;6;370 MiB;33 MiB +\-9;64 MiB;6;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Spaltenbeschreibungen: +.RS +.IP \(bu 3 +Wörtb.Größe ist die Größe des LZMA2\-Wörterbuchs. Es ist +Speicherverschwendung, ein Wörterbuch zu verwenden, das größer als die +unkomprimierte Datei ist. Daher ist es besser, die Voreinstellungen \fB\-7\fP … +\fB\-9\fP zu vermeiden, falls es keinen wirklichen Bedarf dafür gibt. Mit \fB\-6\fP +und weniger wird üblicherweise so wenig Speicher verschwendet, dass dies +nicht ins Gewicht fällt. +.IP \(bu 3 +KomprCPU ist eine vereinfachte Repräsentation der LZMA2\-Einstellungen, +welche die Kompressionsgeschwindigkeit beeinflussen. Die Wörterbuchgröße +wirkt sich ebenfalls auf die Geschwindigkeit aus. Während KompCPU für die +Stufen \fB\-6\fP bis \fB\-9\fP gleich ist, tendieren höhere Stufen dazu, etwas +langsamer zu sein. Um eine noch langsamere, aber möglicherweise bessere +Kompression zu erhalten, siehe \fB\-\-extreme\fP. +.IP \(bu 3 +KompSpeich enthält den Speicherbedarf des Kompressors im +Einzel\-Thread\-Modus. Dieser kann zwischen den \fBxz\fP\-Versionen leicht +variieren. +.IP \(bu 3 +DekompSpeich enthält den Speicherbedarf für die Dekompression. Das bedeutet, +dass die Kompressionseinstellungen den Speicherbedarf bei der Dekompression +bestimmen. Der exakte Speicherbedarf bei der Dekompression ist geringfügig +größer als die Größe des LZMA2\-Wörterbuchs, aber die Werte in der Tabelle +wurden auf ganze MiB aufgerundet. +.RE +.IP "" + Der Speicherbedarf einiger der zukünftigen Multithread\-Modi kann dramatisch +höher sein als im Einzel\-Thread\-Modus. Mit dem Standardwert von +\fB\-\-block\-size\fP benötigt jeder Thread 3*3*Wörtb.Gr plus KompSpeich oder +DekompSpeich. Beispielsweise benötigen vier Threads mit der Voreinstellung +\fB\-6\fP etwa 660 bis 670 MiB Speicher. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +verwendet eine langsamere Variante der gewählten +Kompressions\-Voreinstellungsstufe (\fB\-0\fP … \fB\-9\fP), um hoffentlich ein etwas +besseres Kompressionsverhältnis zu erreichen, das aber in ungünstigen Fällen +auch schlechter werden kann. Der Speicherverbrauch bei der Dekompression +wird dabei nicht beeinflusst, aber der Speicherverbrauch der Kompression +steigt in den Voreinstellungsstufen \fB\-0\fP bis \fB\-3\fP geringfügig an. +.IP "" +Da es zwei Voreinstellungen mit den Wörterbuchgrößen 4\ MiB und 8\ MiB gibt, +verwenden die Voreinstellungsstufen \fB\-3e\fP und \fB\-5e\fP etwas schnellere +Einstellungen (niedrigere KompCPU) als \fB\-4e\fP beziehungsweise \fB\-6e\fP. Auf +diese Weise sind zwei Voreinstellungen nie identisch. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Voreinst.;Wörtb.Gr;KomprCPU;KompSpeich;DekompSpeich +\-0e;256 KiB;8;4 MiB;1 MiB +\-1e;1 MiB;8;13 MiB;2 MiB +\-2e;2 MiB;8;25 MiB;3 MiB +\-3e;4 MiB;7;48 MiB;5 MiB +\-4e;4 MiB;8;48 MiB;5 MiB +\-5e;8 MiB;7;94 MiB;9 MiB +\-6e;8 MiB;8;94 MiB;9 MiB +\-7e;16 MiB;8;186 MiB;17 MiB +\-8e;32 MiB;8;370 MiB;33 MiB +\-9e;64 MiB;8;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Zum Beispiel gibt es insgesamt vier Voreinstellungen, die ein 8\ MiB großes +Wörterbuch verwenden, deren Reihenfolge von der schnellsten zur langsamsten +\fB\-5\fP, \fB\-6\fP, \fB\-5e\fP und \fB\-6e\fP ist. +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +sind etwas irreführende Aliase für \fB\-0\fP beziehungsweise \fB\-9\fP. Sie werden +nur zwecks Abwärtskompatibilität zu den LZMA\-Dienstprogrammen +bereitgestellt. Sie sollten diese Optionen besser nicht verwenden. +.TP +\fB\-\-block\-size=\fP\fIGröße\fP +teilt beim Komprimieren in das \fB.xz\fP\-Format die Eingabedaten in Blöcke der +angegebenen \fIGröße\fP in Byte. Die Blöcke werden unabhängig voneinander +komprimiert, was dem Multi\-Threading entgegen kommt und Zufallszugriffe bei +der Dekompression begrenzt. Diese Option wird typischerweise eingesetzt, um +die vorgegebene Blockgröße im Multi\-Thread\-Modus außer Kraft zu setzen, aber +sie kann auch im Einzel\-Thread\-Modus angewendet werden. +.IP "" +Im Multi\-Thread\-Modus wird etwa die dreifache \fIGröße\fP in jedem Thread zur +Pufferung der Ein\- und Ausgabe belegt. Die vorgegebene \fIGröße\fP ist das +Dreifache der Größe des LZMA2\-Wörterbuchs oder 1 MiB, je nachdem, was mehr +ist. Typischerweise ist das Zwei\- bis Vierfache der Größe des +LZMA2\-Wörterbuchs oder wenigstens 1 MB ein guter Wert. Eine \fIGröße\fP, die +geringer ist als die des LZMA2\-Wörterbuchs, ist Speicherverschwendung, weil +dann der LZMA2\-Wörterbuchpuffer niemals vollständig genutzt werden würde. Im +Multi\-Thread\-Modus wird die Größe der Blöcke wird in den Block\-Headern +gespeichert. Die Größeninformation wird für eine Multi\-Thread\-Dekompression +genutzt. +.IP "" +Im Einzel\-Thread\-Modus werden die Blöcke standardmäßig nicht geteilt. Das +Setzen dieser Option wirkt sich nicht auf den Speicherbedarf aus. In den +Block\-Headern werden keine Größeninformationen gespeichert, daher werden im +Einzel\-Thread\-Modus erzeugte Dateien nicht zu den im Multi\-Thread\-Modus +erzeugten Dateien identisch sein. Das Fehlen der Größeninformation bedingt +auch, dass \fBxz\fP nicht in der Lage sein wird, die Dateien im +Multi\-Thread\-Modus zu dekomprimieren. +.TP +\fB\-\-block\-list=\fP\fIBlöcke\fP +beginnt bei der Kompression in das \fB.xz\fP\-Format nach den angegebenen +Intervallen unkomprimierter Daten einen neuen Block, optional mit einer +benutzerdefinierten Filterkette. +.IP "" +Die \fIBlöcke\fP werden in einer durch Kommata getrennten Liste +angegeben. Jeder Block besteht aus einer optionalen Filterkettennummer +zwischen 0 und 9, gefolgt von einem Doppelpunkt (\fB:\fP) und der Größe der +unkomprimierten Daten (diese Angabe ist erforderlich). Überspringen eines +Blocks (zwei oder mehr aufeinander folgende Kommata) ist ein Kürzel dafür, +die Größe und die Filter des vorherigen Blocks zu verwenden. +.IP "" +Falls die Eingabedatei größer ist als die Summe der \fIBlöcke\fP, dann wird der +letzte in \fIVBlöcke\fP angegebene Wert bis zum Ende der Datei wiederholt. Mit +dem speziellen Wert \fB0\fP können Sie angeben, dass der Rest der Datei als +einzelner Block kodiert werden soll. +.IP "" +Eine alternative Filterkette für jeden Block kann in Kombination mit den +Optionen \fB\-\-filters1=\fP\fIFilter\fP \&…\& \fB\-\-filters9=\fP\fIFilter\fP angegeben +werden. Diese Optionen definieren Filterketten mit einem Bezeichner zwischen +1 und 9. Die Filterkette 0 bezeichnet hierbei die voreingestellte +Filterkette, was dem Nichtangeben einer Filterkette gleichkommt. Der +Filterkettenbezeichner kann vor der unkomprimierten Größe verwendet werden, +gefolgt von einem Doppelpunkt (\fB:\fP). Falls Sie beispielsweise +\fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP angeben, werden die Blöcke +folgendermaßen erstellt: +.RS +.IP \(bu 3 +Die durch \fB\-\-filters1\fP angegebene Filterkette und 2 MiB Eingabe +.IP \(bu 3 +Die durch \fB\-\-filters3\fP angegebene Filterkette und 2 MiB Eingabe +.IP \(bu 3 +Die durch \fB\-\-filters2\fP angegebene Filterkette und 4 MiB Eingabe +.IP \(bu 3 +Die durch \fB\-\-filters2\fP angegebene Filterkette und 4 MiB Eingabe +.IP \(bu 3 +Die vorgegebene Filterkette und 2 MiB Eingabe +.IP \(bu 3 +Die vorgegebene Filterkette und 4 MiB Eingabe für jeden Block bis zum Ende +der Eingabe. +.RE +.IP "" +Falls Sie eine Größe angeben, welche die Blockgröße des Encoders übersteigen +(entweder den Vorgabewert im Thread\-Modus oder den mit +\fB\-\-block\-size=\fP\fIGröße\fP angegebenen Wert), wird der Encoder zusätzliche +Blöcke erzeugen, wobei die in den \fIBlöcke\fP angegebenen Grenzen eingehalten +werden. Wenn Sie zum Beispiel \fB\-\-block\-size=10MiB\fP +\fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP angeben und die Eingabedatei 80 +MiB groß ist, erhalten Sie 11 Blöcke: 5, 10, 8, 10, 2, 10, 10, 4, 10, 10 und +1 MiB. +.IP "" +Im Multi\-Thread\-Modus werden die Blockgrößen in den Block\-Headern +gespeichert. Dies geschieht im Einzel\-Thread\-Modus nicht, daher wird die +kodierte Ausgabe zu der im Multi\-Thread\-Modus nicht identisch sein. +.TP +\fB\-\-flush\-timeout=\fP\fIZeit\fP +löscht bei der Kompression die ausstehenden Daten aus dem Encoder und macht +sie im Ausgabedatenstrom verfügbar, wenn mehr als die angegebene \fIZeit\fP in +Millisekunden (als positive Ganzzahl) seit dem vorherigen Löschen vergangen +ist und das Lesen weiterer Eingaben blockieren würde. Dies kann nützlich +sein, wenn \fBxz\fP zum Komprimieren von über das Netzwerk eingehenden Daten +verwendet wird. Kleine \fIZeit\fP\-Werte machen die Daten unmittelbar nach dem +Empfang nach einer kurzen Verzögerung verfügbar, während große \fIZeit\fP\-Werte +ein besseres Kompressionsverhältnis bewirken. +.IP "" +Dieses Funktionsmerkmal ist standardmäßig deaktiviert. Wenn diese Option +mehrfach angegeben wird, ist die zuletzt angegebene wirksam. Für die Angabe +der \fIZeit\fP kann der spezielle Wert \fB0\fP verwendet werden, um dieses +Funktionsmerkmal explizit zu deaktivieren. +.IP "" +Dieses Funktionsmerkmal ist außerhalb von POSIX\-Systemen nicht verfügbar. +.IP "" +.\" FIXME +\fBDieses Funktionsmerkmal ist noch experimentell.\fP Gegenwärtig ist \fBxz\fP +aufgrund der Art und Weise, wie \fBxz\fP puffert, für Dekompression in Echtzeit +ungeeignet. +.TP +\fB\-\-no\-sync\fP +synchronisiert die Zieldatei und deren Verzeichnis auf dem Speichergerät +nicht, bevor die Quelldatei gelöscht wird. So kann die Performance beim +Komprimieren oder Dekomprimieren vieler kleiner Dateien verbessert +werden. Jedoch wäre es möglich, falls es kurz nach dem Löschen zu einem +Systemabsturz kommt, dass die Zieldatei noch nicht auf dem Speichergerät +geschrieben, aber der Löschvorgang bereits ausgeführt wurde. In diesem Fall +gehen sowohl die Quelldatei als auch die Zieldatei verloren. +.IP "" +Diese Option ist nur wirksam, wenn \fBxz\fP die Quelldatei löscht. In anderen +Fällen wird niemals synchronisiert. +.IP "" +Die Synchronisierung und \fB\-\-no\-sync\fP wurden in Version \fBxz\fP 5.7.1alpha +hinzugefügt. +.TP +\fB\-\-memlimit\-compress=\fP\fIGrenze\fP +legt eine Grenze für die Speichernutzung bei der Kompression fest. Wenn +diese Option mehrmals angegeben wird, ist die zuletzt angegebene wirksam. +.IP "" +Falls die Kompressionseinstellungen die \fIGrenze\fP überschreiten, versucht +\fBxz\fP, die Einstellungen nach unten anzupassen, so dass die Grenze nicht +mehr überschritten wird und zeigt einen Hinweis an, dass eine automatische +Anpassung vorgenommen wurde. Die Anpassungen werden in folgender Reihenfolge +angewendet: Reduzierung der Anzahl der Threads, Wechsel in den +Einzelthread\-Modus, falls sogar ein einziger Thread im Multithread\-Modus die +\fIGrenze\fP überschreitet, und schlussendlich die Reduzierung der Größe des +LZMA2\-Wörterbuchs. +.IP "" +Beim Komprimieren mit \fB\-\-format=raw\fP oder falls \fB\-\-no\-adjust\fP angegeben +wurde, wird nur die Anzahl der Threads reduziert, da nur so die komprimierte +Ausgabe nicht beeinflusst wird. +.IP "" +Falls die \fIGrenze\fP nicht anhand der vorstehend beschriebenen Anpassungen +gesetzt werden kann, wird ein Fehler angezeigt und \fBxz\fP wird mit dem +Exit\-Status 1 beendet. +.IP "" +Die \fIGrenze\fP kann auf verschiedene Arten angegeben werden: +.RS +.IP \(bu 3 +Die \fIGrenze\fP kann ein absoluter Wert in Byte sein. Ein Suffix wie \fBMiB\fP +kann dabei hilfreich sein. Beispiel: \fB\-\-memlimit\-compress=80MiB\fP. +.IP \(bu 3 +Die \fIGrenze\fP kann als Prozentsatz des physischen Gesamtspeichers (RAM) +angegeben werden. Dies ist insbesondere nützlich, wenn in einem +Shell\-Initialisierungsskript, das mehrere unterschiedliche Rechner gemeinsam +verwenden, die Umgebungsvariable \fBXZ_DEFAULTS\fP gesetzt ist. Auf diese Weise +ist die Grenze auf Systemen mit mehr Speicher höher. Beispiel: +\fB\-\-memlimit\-compress=70%\fP +.IP \(bu 3 +Mit \fB0\fP kann die \fIGrenze\fP auf den Standardwert zurückgesetzt werden. Dies +ist gegenwärtig gleichbedeutend mit dem Setzen der \fIGrenze\fP auf \fBmax\fP +(keine Speicherbegrenzung). +.RE +.IP "" +Für die 32\-Bit\-Version von \fBxz\fP gibt es einen Spezialfall: Falls die Grenze +über \fB4020\ MiB\fP liegt, wird die \fIGrenze\fP auf \fB4020\ MiB\fP gesetzt. Auf +MIPS32 wird stattdessen \fB2000\ MB\fP verwendet (die Werte \fB0\fP und \fBmax\fP +werden hiervon nicht beeinflusst; für die Dekompression gibt es keine +vergleichbare Funktion). Dies kann hilfreich sein, wenn ein +32\-Bit\-Executable auf einen 4\ GiB großen Adressraum (2 GiB auf MIPS32) +zugreifen kann, wobei wir hoffen wollen, dass es in anderen Situationen +keine negativen Effekte hat. +.IP "" +Siehe auch den Abschnitt \fBSpeicherbedarf\fP. +.TP +\fB\-\-memlimit\-decompress=\fP\fIGrenze\fP +legt eine Begrenzung des Speicherverbrauchs für die Dekompression fest. Dies +beeinflusst auch den Modus \fB\-\-list\fP. Falls die Aktion nicht ausführbar ist, +ohne die \fIGrenze\fP zu überschreiten, gibt \fBxz\fP eine Fehlermeldung aus und +die Dekompression wird fehlschlagen. Siehe \fB\-\-memlimit\-compress=\fP\fIGrenze\fP +zu möglichen Wegen, die \fIGrenze\fP anzugeben. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fIGrenze\fP +legt eine Begrenzung des Speicherverbrauchs für Multithread\-Dekompression +fest. Dies beeinflusst lediglich die Anzahl der Threads; \fBxz\fP wird dadurch +niemals die Dekompression einer Datei verweigern. Falls die \fIGrenze\fP für +jegliches Multithreading zu niedrig ist, wird sie ignoriert und \fBxz\fP setzt +im Einzelthread\-modus fort. Beachten Sie auch, dass bei der Verwendung von +\fB\-\-memlimit\-decompress\fP dies stets sowohl auf den Einzelthread\-als auch auf +den Multithread\-Modus angewendet wird und so die effektive \fIGrenze\fP für den +Multithread\-Modus niemals höher sein wird als die mit +\fB\-\-memlimit\-decompress\fP gesetzte Grenze. +.IP "" +Im Gegensatz zu anderen Optionen zur Begrenzung des Speicherverbrauchs hat +\fB\-\-memlimit\-mt\-decompress=\fP\fIGrenze\fP eine systemspezifisch vorgegebene +\fIGrenze\fP. Mit \fBxz \-\-info\-memory\fP können Sie deren aktuellen Wert anzeigen +lassen. +.IP "" +Diese Option und ihr Standardwert existieren, weil die unbegrenzte +threadbezogene Dekompression bei einigen Eingabedateien zu unglaublich +großem Speicherverbrauch führen würde. Falls die vorgegebene \fIGrenze\fP auf +Ihrem System zu niedrig ist, können Sie die \fIGrenze\fP durchaus erhöhen, aber +setzen Sie sie niemals auf einen Wert größer als die Menge des nutzbaren +Speichers, da \fBxz\fP bei entsprechenden Eingabedateien versuchen wird, diese +Menge an Speicher auch bei einer geringen Anzahl von Threads zu +verwnden. Speichermangel oder Auslagerung verbessern die +Dekomprimierungsleistung nicht. +.IP "" +Siehe \fB\-\-memlimit\-compress=\fP\fIGrenze\fP für mögliche Wege zur Angabe der +\fIGrenze\fP. Sezen der \fIGrenze\fP auf \fB0\fP setzt die \fIGrenze\fP auf den +vorgegebenen systemspezifischen Wert zurück. +.TP +\fB\-M\fP \fIGrenze\fP, \fB\-\-memlimit=\fP\fIGrenze\fP, \fB\-\-memory=\fP\fIGrenze\fP +Dies ist gleichbedeutend mit \fB\-\-memlimit\-compress=\fP\fIGrenze\fP +\fB\-\-memlimit\-decompress=\fP\fIGrenze\fP \fB\-\-memlimit\-mt\-decompress=\fP\fIGrenze\fP. +.TP +\fB\-\-no\-adjust\fP +zeigt einen Fehler an und beendet, falls die Grenze der Speichernutzung +nicht ohne Änderung der Einstellungen, welche die komprimierte Ausgabe +beeinflussen, berücksichtigt werden kann. Das bedeutet, dass \fBxz\fP daran +gehindert wird, den Encoder vom Multithread\-Modus in den Einzelthread\-Modus +zu versetzen und die Größe des LZMA2\-Wörterbuchs zu reduzieren. Allerdings +kann bei Verwendung dieser Option dennoch die Anzahl der Threads reduziert +werden, um die Grenze der Speichernutzung zu halten, sofern dies die +komprimierte Ausgabe nicht beeinflusst. +.IP "" +Die automatische Anpassung ist beim Erzeugen von Rohdatenströmen +(\fB\-\-format=raw\fP) immer deaktiviert. +.TP +\fB\-T\fP \fIThreads\fP, \fB\-\-threads=\fP\fIThreads\fP +gibt die Anzahl der zu verwendenden Arbeits\-Threads an. Wenn Sie \fIThreads\fP +auf einen speziellen Wert \fB0\fP setzen, verwendet \fBxz\fP maximal so viele +Threads, wie der/die Prozessor(en) im System untestützen. Die tatsächliche +Anzahl kann geringer sein als die angegebenen \fIThreads\fP, wenn die +Eingabedatei nicht groß genug für Threading mit den gegebenen Einstellungen +ist oder wenn mehr Threads die Speicherbegrenzung übersteigen würden. +.IP "" +Die Multithread\- bzw. Einzelthread\-Kompressoren erzeugen unterschiedliche +Ausgaben. Der Einzelthread\-Kompressor erzeugt die geringste Dateigröße, aber +nur die Ausgabe des Multithread\-Kompressors kann mit mehreren Threads wieder +dekomprimiert werden. Das Setzen der Anzahl der \fIThreads\fP auf \fB1\fP wird den +Einzelthread\-Modus verwenden. Das Setzen der Anzahl der \fIThreads\fP auf +einen anderen Wert einschließlich \fB0\fP verwendet den Multithread\-Kompressor, +und zwar sogar dann, wenn das System nur einen einzigen Hardware\-Thread +unterstützt (\fBxz\fP 5.2.x verwendete in diesem Fall noch den +Einzelthread\-Modus). +.IP "" +Um den Multithread\-Modus mit nur einem einzigen Thread zu verwenden, setzen +Sie die Anzahl der \fIThreads\fP auf \fB+1\fP. Das Präfix \fB+\fP hat mit Werten +verschieden von \fB1\fP keinen Effekt. Eine Begrenzung des Speicherverbrauchs +kann \fBxz\fP dennoch veranlassen, den Einzelthread\-Modus zu verwenden, außer +wenn \fB\-\-no\-adjust\fP verwendet wird. Die Unterstützung für das Präfix \fB+\fP +wurde in \fBxz\fP 5.4.0 hinzugefügt. +.IP "" +Falls das automatische Setzen der Anzahl der Threads angefordert und keine +Speicherbegrenzung angegeben wurde, dann wird eine systemspezifisch +vorgegebene weiche Grenze verwendet, um eventuell die Anzahl der Threads zu +begrenzen. Es ist eine weiche Grenze im Sinne davon, dass sie ignoriert +wird, falls die Anzahl der Threads 1 ist; daher wird eine weiche Grenze +\fBxz\fP niemals an der Kompression oder Dekompression hindern. Diese +vorgegebene weiche Grenze veranlasst \fBxz\fP nicht, vom Multithread\-Modus in +den Einzelthread\-Modus zu wechseln. Die aktiven Grenzen können Sie mit dem +Befehl \fBxz \-\-info\-memory\fP anzeigen lassen. +.IP "" +Die gegenwärtig einzige Threading\-Methode teilt die Eingabe in Blöcke und +komprimiert diese unabhängig voneinander. Die vorgegebene Blockgröße ist von +der Kompressionsstufe abhängig und kann mit der Option +\fB\-\-block\-size=\fP\fIGröße\fP außer Kraft gesetzt werden. +.IP "" +Eine thread\-basierte Dekompression wird nur bei Dateien funktionieren, die +mehrere Blöcke mit Größeninformationen in deren Headern enthalten. Alle im +Multi\-Thread\-Modus komprimierten Dateien, die groß genug sind, erfüllen +diese Bedingung, im Einzel\-Thread\-Modus komprimierte Dateien dagegen nicht, +selbst wenn \fB\-\-block\-size=\fP\fIGröße\fP verwendet wurde. +.IP "" +Der Vorgabewert für \fIThreads\fP is \fB0\fP. In \fBxz\fP 5.4.x und älteren Versionen +ist der Vorgabewert \fB1\fP. +. +.SS "Benutzerdefinierte Filterketten für die Kompression" +Eine benutzerdefinierte Filterkette ermöglicht die Angabe detaillierter +Kompressionseinstellungen, anstatt von den Voreinstellungen auszugehen. Wenn +eine benutzerdefinierte Filterkette angegeben wird, werden die vorher in der +Befehlszeile angegebenen Voreinstellungsoptionen (\fB\-0\fP … \fB\-9\fP und +\fB\-\-extreme\fP) außer Kraft gesetzt. Wenn eine Voreinstellungsoption nach +einer oder mehreren benutzerdefinierten Filterkettenoptionen angegeben wird, +dann wird die neue Voreinstellung wirksam und die zuvor angegebenen +Filterkettenoptionen werden außer Kraft gesetzt. +.PP +Eine Filterkette ist mit dem Piping (der Weiterleitung) in der Befehlszeile +vergleichbar. Bei der Kompression gelangt die unkomprimierte Eingabe in den +ersten Filter, dessen Ausgabe wiederum in den zweiten Filter geleitet wird +(sofern ein solcher vorhanden ist). Die Ausgabe des letzten Filters wird in +die komprimierte Datei geschrieben. In einer Filterkette sind maximal vier +Filter zulässig, aber typischerweise besteht eine Filterkette nur aus einem +oder zwei Filtern. +.PP +Bei vielen Filtern ist die Positionierung in der Filterkette eingeschränkt: +Einige Filter sind nur als letzte in der Kette verwendbar, einige können +nicht als letzte Filter gesetzt werden, und andere funktionieren an +beliebiger Stelle. Abhängig von dem Filter ist diese Beschränkung entweder +auf das Design des Filters selbst zurückzuführen oder ist aus +Sicherheitsgründen vorhanden. +.PP +Eine benutzerdefinierte Filterkette kann auf zwei verschiedene Arten +angegeben werden. Die Optionen \fB\-\-filters=\fP\fIFilter\fP und +\fB\-\-filters1=\fP\fIFilter\fP \&…\& \fB\-\-filters9=\fP\fIFilter\fP ermöglichen die Angabe +einer ganzen Filterkette in einer einzelnen Option gemäß der +Liblzma\-Filterzeichenkettensyntax. Alternativ können Sie eine Filterkette +mit einer oder mehreren individuellen Filteroptionen in der Reihenfolge +angeben, in der sie in der Filterkette verwendet werden sollen. Daher ist +die Reihenfolge der individuellen Filteroptionen wichtig! Beim Dekodieren +von Rohdatenströmen (\fB\-\-format=raw\fP) muss die Filterkette in der gleichen +Reihenfolge wie bei der Komprimierung angegeben werden. Alle individuellen +Filter\- oder Voreinstellungsoptionen, die \fIvor\fP der vollen +Filterkettenoption (\fB\-\-filters=\fP\fIFilter\fP) angegeben werden, werden +verworfen. Individuelle Filter, die \fInach\fP der vollen Filterkettenoption +angegeben werden, setzen die Filterkette zurück +.PP +Sowohl vollständige als auch individuelle Filteroptionen akzeptieren +filterspezifische \fIOptionen\fP in einer durch Kommata getrennten +Liste. Zusätzliche Kommata in den \fIOptionen\fP werden ignoriert. Jede Option +hat einen Standardwert, daher brauchen Sie nur jene anzugeben, die Sie +ändern wollen. +.PP +Um die gesamte Filterkette und die \fIOptionen\fP anzuzeigen, rufen Sie \fBxz \-vv\fP auf (was gleichbedeutend mit der zweimaligen Angabe von \fB\-\-verbose\fP +ist). Dies funktioniert auch zum Betrachten der von den Voreinstellungen +verwendeten Filterkettenoptionen. +.TP +\fB\-\-filters=\fP\fIFilter\fP +gibt die vollständige Filterkette oder eine Voreinstellung in einer +einzelnen Option an. Mehrere Filter können durch Leerzeichen oder zwei +Minuszeichen (\fB\-\-\fP) voneinander getrennt werden. Es kann notwendig sein, +die \fIFilter\fP in der Shell\-Befehlszeile zu maskieren, so dass diese als +einzelne Option ausgewertet werden. Um Optionen Werte zuzuordnen, verwenden +Sie \fB:\fP oder \fB=\fP. Einer Voreinstellung kann ein \fB\-\fP vorangestellt werden, +dem keiner oder mehrere Schalter folgen. Der einzige unterstützte Schalter +ist \fBe\fP zum Anwenden der gleichen Optionen wie \fB\-\-extreme\fP. +.TP +\fB\-\-filters1\fP=\fIFilter\fP … \fB\-\-filters9\fP=\fIFilter\fP +gibt bis zu neun optionale Filterketten an, die mit \fB\-\-block\-list\fP +verwendet werden können. +.IP "" +Wenn Sie beispielsweise ein Archiv mit ausführbaren Dateien gefolgt von +Textdateien komprimieren, könnte der Teil mit den ausführbaren Dateien eine +Filterkette mit einem BCJ\-Filter und der Textdateiteil lediglich den +LZMA2\-Filter verwenden. +.TP +\fB\-\-filters\-help\fP +zeigt eine Hilfemeldung an, welche beschreibt, wie Voreinstellungen und +benutzerdefinierte Filterketten in den Optionen \fB\-\-filters\fP und +\fB\-\-filters1=\fP\fIFilter\fP \&… \& \fB\-\-filters9=\fP\fIFilter\fP angegeben werden und +beendet das Programm. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fIOptionen\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fIOptionen\fP] +.PD +fügt LZMA1\- oder LZMA2\-Filter zur Filterkette hinzu. Diese Filter können nur +als letzte Filter in der Kette verwendet werden. +.IP "" +LZMA1 ist ein veralteter Filter, welcher nur wegen des veralteten +\&\fB.lzma\fP\-Dateiformats unterstützt wird, welches nur LZMA1 unterstützt. LZMA2 +ist eine aktualisierte Version von LZMA1, welche einige praktische Probleme +von LZMA1 behebt. Das \fB.xz\fP\-Format verwendet LZMA2 und unterstützt LZMA1 +gar nicht. Kompressionsgeschwindigkeit und \-verhältnis sind bei LZMA1 und +LZMA2 praktisch gleich. +.IP "" +LZMA1 und LZMA2 haben die gleichen \fIOptionen\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fIVoreinstellung\fP +setzt alle LZMA1\- oder LZMA2\-\fIOptionen\fP auf die \fIVoreinstellung\fP +zurück. Diese \fIVoreinstellung\fP wird in Form einer Ganzzahl angegeben, der +ein aus einem einzelnen Buchstaben bestehender Voreinstellungsmodifikator +folgen kann. Die Ganzzahl kann \fB0\fP bis \fB9\fP sein, entsprechend den +Befehlszeilenoptionen \fB\-0\fP … \fB\-9\fP. Gegenwärtig ist \fBe\fP der einzige +unterstützte Modifikator, was \fB\-\-extreme\fP entspricht. Wenn keine +\fBVoreinstellung\fP angegeben ist, werden die Standardwerte der LZMA1\- oder +LZMA2\-\fIOptionen\fP der Voreinstellung \fB6\fP entnommen. +.TP +\fBdict=\fP\fIGröße\fP +Die \fIGröße\fP des Wörterbuchs (Chronikpuffers) gibt an, wie viel Byte der +kürzlich verarbeiteten unkomprimierten Daten im Speicher behalten werden +sollen. Der Algorithmus versucht, sich wiederholende Byte\-Abfolgen +(Übereinstimmungen) in den unkomprimierten Daten zu finden und diese durch +Referenzen zu den Daten zu ersetzen, die sich gegenwärtig im Wörterbuch +befinden. Je größer das Wörterbuch, umso größer ist die Chance, eine +Übereinstimmung zu finden. Daher bewirkt eine Erhöhung der \fIGröße\fP des +Wörterbuchs üblicherweise ein besseres Kompressionsverhältnis, aber ein +Wörterbuch, das größer ist als die unkomprimierte Datei, wäre +Speicherverschwendung. +.IP "" +Typische Wörterbuch\-\fIGrößen\fP liegen im Bereich von 64\ KiB bis 64\ MiB. Das +Minimum ist 4\ KiB. Das Maximum für die Kompression ist gegenwärtig 1.5\ GiB +(1536\ MiB). Bei der Dekompression wird bereits eine Wörterbuchgröße bis zu +4\ GiB minus 1 Byte unterstützt, welche das Maximum für die LZMA1\- und +LZMA2\-Datenstromformate ist. +.IP "" +Die \fIGröße\fP des Wörterbuchs und der Übereinstimmungsfinder (\fIÜf\fP) +bestimmen zusammen den Speicherverbrauch des LZMA1\- oder +LZMA2\-Kodierers. Bei der Dekompression ist ein Wörterbuch der gleichen +\fIGröße\fP (oder ein noch größeres) wie bei der Kompression erforderlich, +daher wird der Speicherverbrauch des Dekoders durch die Größe des bei der +Kompression verwendeten Wörterbuchs bestimmt. Die \fB.xz\fP\-Header speichern +die \fIGröße\fP des Wörterbuchs entweder als 2^\fIn\fP oder 2^\fIn\fP + 2^(\fIn\fP\-1), +so dass diese \fIGrößen\fP für die Kompression etwas bevorzugt werden. Andere +\fIGrößen\fP werden beim Speichern in den \fB.xz\fP\-Headern aufgerundet. +.TP +\fBlc=\fP\fIlc\fP +gibt die Anzahl der literalen Kontextbits an. Das Minimum ist 0 und das +Maximum 4; der Standardwert ist 3. Außerdem darf die Summe von \fIlc\fP und +\fIlp\fP nicht größer als 4 sein. +.IP "" +Alle Bytes, die nicht als Übereinstimmungen kodiert werden können, werden +als Literale kodiert. Solche Literale sind einfache 8\-bit\-Bytes, die jeweils +für sich kodiert werden. +.IP "" +Bei der Literalkodierung wird angenommen, dass die höchsten \fIlc\fP\-Bits des +zuvor unkomprimierten Bytes mit dem nächsten Byte in Beziehung stehen. Zum +Beispiel folgt in typischen englischsprachigen Texten auf einen +Großbuchstaben ein Kleinbuchstabe und auf einen Kleinbuchstaben +üblicherweise wieder ein Kleinbuchstabe. Im US\-ASCII\-Zeichensatz sind die +höchsten drei Bits 010 für Großbuchstaben und 011 für Kleinbuchstaben. Wenn +\fIlc\fP mindestens 3 ist, kann die literale Kodierung diese Eigenschaft der +unkomprimierten Daten ausnutzen. +.IP "" +Der Vorgabewert (3) ist üblicherweise gut. Wenn Sie die maximale Kompression +erreichen wollen, versuchen Sie \fBlc=4\fP. Manchmal hilft es ein wenig, doch +manchmal verschlechtert es die Kompression. Im letzteren Fall versuchen Sie +zum Beispiel auch\& \fBlc=2\fP. +.TP +\fBlp=\fP\fIlp\fP +gibt die Anzahl der literalen Positionsbits an. Das Minimum ist 0 und das +Maximum 4; die Vorgabe ist 0. +.IP "" +\fILp\fP beeinflusst, welche Art der Ausrichtung der unkomprimierten Daten beim +Kodieren von Literalen angenommen wird. Siehe \fIpb\fP weiter unten für weitere +Informationen zur Ausrichtung. +.TP +\fBpb=\fP\fIAnzahl\fP +legt die Anzahl der Positions\-Bits fest. Das Minimum ist 0 und das Maximum +4; Standard ist 2. +.IP "" +\fIPb\fP beeinflusst, welche Art der Ausrichtung der unkomprimierten Daten +generell angenommen wird. Standardmäßig wird eine Vier\-Byte\-Ausrichtung +angenommen (2^\fIpb\fP=2^2=4), was oft eine gute Wahl ist, wenn es keine +bessere Schätzung gibt. +.IP "" +Wenn die Ausrichtung bekannt ist, kann das entsprechende Setzen von \fIpb\fP +die Dateigröße ein wenig verringern. Wenn Textdateien zum Beispiel eine +Ein\-Byte\-Ausrichtung haben (US\-ASCII, ISO\-8859\-*, UTF\-8), kann das Setzen +von \fBpb=0\fP die Kompression etwas verbessern. Für UTF\-16\-Text ist \fBpb=1\fP +eine gute Wahl. Wenn die Ausrichtung eine ungerade Zahl wie beispielsweise 3 +Byte ist, könnte \fBpb=0\fP die beste Wahl sein. +.IP "" +Obwohl die angenommene Ausrichtung mit \fIpb\fP und \fIlp\fP angepasst werden +kann, bevorzugen LZMA1 und LZMA2 noch etwas die 16\-Byte\-Ausrichtung. Das +sollten Sie vielleicht beim Design von Dateiformaten berücksichtigen, die +wahrscheinlich oft mit LZMA1 oder LZMA2 komprimiert werden. +.TP +\fBmf=\fP\fIÜf\fP +Der Übereinstimmungsfinder hat einen großen Einfluss auf die Geschwindigkeit +des Kodierers, den Speicherbedarf und das +Kompressionsverhältnis. Üblicherweise sind auf Hash\-Ketten basierende +Übereinstimmungsfinder schneller als jene, die mit Binärbäumen arbeiten. Die +Vorgabe hängt von der \fIVoreinstellungsstufe\fP ab: 0 verwendet \fBhc3\fP, 1\-3 +verwenden \fBhc4\fP und der Rest verwendet \fBbt4\fP. +.IP "" +Die folgenden Übereinstimmungsfinder werden unterstützt. Die Formeln zur +Ermittlung des Speicherverbrauchs sind grobe Schätzungen, die der Realität +am nächsten kommen, wenn \fIWörterbuch\fP eine Zweierpotenz ist. +.RS +.TP +\fBhc3\fP +Hash\-Kette mit 2\- und 3\-Byte\-Hashing +.br +Minimalwert für \fInice\fP: 3 +.br +Speicherbedarf: +.br +\fIdict\fP * 7,5 (falls \fIdict\fP <= 16 MiB); +.br +\fIdict\fP * 5,5 + 64 MiB (falls \fIdict\fP > 16 MiB) +.TP +\fBhc4\fP +Hash\-Kette mit 2\-, 3\- und 4\-Byte\-Hashing +.br +Minimaler Wert für \fInice\fP: 4 +.br +Speicherbedarf: +.br +\fIdict\fP * 7,5 (falls \fIdict\fP <= 32 MiB ist); +.br +\fIdict\fP * 6,5 (falls \fIdict\fP > 32 MiB ist) +.TP +\fBbt2\fP +Binärbaum mit 2\-Byte\-Hashing +.br +Minimaler Wert für \fInice\fP: 2 +.br +Speicherverbrauch: \fIdict\fP * 9.5 +.TP +\fBbt3\fP +Binärbaum mit 2\- und 3\-Byte\-Hashing +.br +Minimalwert für \fInice\fP: 3 +.br +Speicherbedarf: +.br +\fIdict\fP * 11,5 (falls \fIdict\fP <= 16 MiB ist); +.br +\fIdict\fP * 9,5 + 64 MiB (falls \fIdict\fP > 16 MiB ist) +.TP +\fBbt4\fP +Binärbaum mit 2\-, 3\- und 4\-Byte\-Hashing +.br +Minimaler Wert für \fInice\fP: 4 +.br +Speicherbedarf: +.br +\fIdict\fP * 11,5 (falls \fIdict\fP <= 32 MiB ist); +.br +\fIdict\fP * 10,5 (falls \fIdict\fP > 32 MiB ist) +.RE +.TP +\fBmode=\fP\fIModus\fP +gibt die Methode zum Analysieren der vom Übereinstimmungsfinder gelieferten +Daten an. Als \fIModi\fP werden \fBfast\fP und \fBnormal\fP unterstützt. Die Vorgabe +ist \fBfast\fP für die \fIVoreinstellungsstufen\fP 0\-3 und \fBnormal\fP für die +\fIVoreinstellungsstufen\fP 4\-9. +.IP "" +Üblicherweise wird \fBfast\fP mit Hashketten\-basierten Übereinstimmungsfindern +und \fBnormal\fP mit Binärbaum\-basierten Übereinstimmungsfindern verwendet. So +machen es auch die \fIVoreinstellungsstufen\fP. +.TP +\fBnice=\fP\fInice\fP +gibt an, was als annehmbarer Wert für eine Übereinstimmung angesehen werden +kann. Wenn eine Übereinstimmung gefunden wird, die mindestens diesen +\fInice\fP\-Wert hat, sucht der Algorithmus nicht weiter nach besseren +Übereinstimmungen. +.IP "" +Der \fInice\fP\-Wert kann 2\-273 Byte sein. Höhere Werte tendieren zu einem +besseren Kompressionsverhältnis, aber auf Kosten der Geschwindigkeit. Die +Vorgabe hängt von der \fIVoreinstellungsstufe\fP ab. +.TP +\fBdepth=\fP\fITiefe\fP +legt die maximale Suchtiefe im Übereinstimmungsfinder fest. Vorgegeben ist +der spezielle Wert 0, der den Kompressor veranlasst, einen annehmbaren Wert +für \fITiefe\fP aus \fIÜf\fP und \fInice\fP\-Wert zu bestimmen. +.IP "" +Die angemessene \fITiefe\fP für Hash\-Ketten ist 4\-100 und 16\-1000 für +Binärbäume. Hohe Werte für die \fITiefe\fP können den Kodierer bei einigen +Dateien extrem verlangsamen. Vermeiden Sie es, die \fITiefe\fP über einen Wert +von 100 zu setzen, oder stellen Sie sich darauf ein, die Kompression +abzubrechen, wenn sie zu lange dauert. +.RE +.IP "" +Beim Dekodieren von Rohdatenströmen (\fB\-\-format=raw\fP) benötigt LZMA2 nur die +Wörterbuch\-\fIGröße\fP. LZMA1 benötigt außerdem \fIlc\fP, \fIlp\fP und \fIpb\fP. +.TP +\fB\-\-x86\fP[\fB=\fP\fIOptionen\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fIOptionen\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fIOptionen\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fIOptionen\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fIOptionen\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fIOptionen\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fIOptionen\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIOptionen\fP] +.PD +fügt ein »Branch/Call/Jump«\-(BCJ\-)Filter zur Filterkette hinzu. Diese Filter +können nicht als letzter Filter in der Filterkette verwendet werden. +.IP "" +Ein BCJ\-Filter wandelt relative Adressen im Maschinencode in deren absolute +Gegenstücke um. Die Datengröße wird dadurch nicht geändert, aber die +Redundanz erhöht, was LZMA2 dabei helfen kann, eine um 10 bis 15% kleinere +\&\fB.xz\fP\-Datei zu erstellen. Die BCJ\-Filter sind immer reversibel, daher +verursacht die Anwendung eines BCJ\-Filters auf den falschen Datentyp keinen +Datenverlust, wobei aber das Kompressionsverhältnis etwas schlechter werden +könnte. Die BCJ\-Filter sind sehr schnell und verbrauchen nur wenig mehr +Speicher. +.IP "" +Diese BCJ\-Filter haben bekannte Probleme mit dem Kompressionsverhältnis: +.RS +.IP \(bu 3 +In einigen Dateitypen, die ausführbaren Code enthalten (zum Beispiel +Objektdateien, statische Bibliotheken und Linux\-Kernelmodule), sind die +Adressen in den Anweisungen mit Füllwerten gefüllt. Diese BCJ\-Filter führen +dennoch die Adressumwandlung aus, wodurch die Kompression bei diesen Dateien +schlechter wird. +.IP \(bu 3 +Falls ein BCJ\-Filter auf ein Archiv angewendet wird, ist es möglich, dass +das Kompressionsverhältnis schlechter als ohne Filter wird. Falls es +beispielsweise ähnliche oder sogar identische ausführbare Dateien gibt, dann +werden diese durch die Filterung wahrscheinlich »unähnlicher« und +verschlechtern dadurch das Kompressionsverhältnis. Der Inhalt +nicht\-ausführbarer Dateien im gleichen Archiv kann sich ebenfalls darauf +auswirken. In der Praxis werden Sie durch Versuche mit oder ohne BCJ\-Filter +selbst herausfinden müssen, was situationsbezogen besser ist. +.RE +.IP "" +Verschiedene Befehlssätze haben unterschiedliche Ausrichtungen: Die +ausführbare Datei muss in den Eingabedateien einem Vielfachen dieses Wertes +entsprechen, damit dieser Filter funktioniert. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +Filter;Ausrichtung;Hinweise +x86;1;32\-Bit oder 64\-Bit x86 +ARM;4; +ARM\-Thumb;2; +ARM64;4;4096\-Byte\-Ausrichtung ist optimal +PowerPC;4;Nur Big Endian +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +Da die BCJ\-gefilterten Daten üblicherweise mit LZMA2 komprimiert sind, kann +das Kompressionsverhältnis dadurch etwas verbessert werden, dass die +LZMA2\-Optionen so gesetzt werden, dass sie der Ausrichtung des gewählten +BCJ\-Filters entsprechen. Beispiele: +.RS +.IP \(bu 3 +Der IA\-64\-Filter hat eine 16\-Byte\-Ausrichtung, daher ist \fBpb=4,lp=4,lc=0\fP +für LZMA2 passend (2^4=16). +.IP \(bu 3 +RISC\-V\-Code hat eine 2\-Byte\- oder 4\-Byte\-Ausrichtung, abhängig davon, ob die +Datei 16\-bit\-komprimierte Instruktionen enthält (die C\-Erweiterung). Wenn +16\-bit\-Instruktionen verwendet werden, ist \fBpb=2,lp=1,lc=3\fP oder +\fBpb=1,lp=1,lc=3\fP passend. Wenn keine 16\-bit\-Instruktionen vorhanden sind, +ist \fBpb=2,lp=2,lc=2\fP am besten. Mit \fBreadelf \-h\fP können Sie überprüfen, ob +»RVC« in der »Flags«\-Zeile auftritt. +.IP \(bu 3 +ARM64 hat stets eine 4\-Byte\-Ausrichtung, daher ist \fBpb=2,lp=2,lc=2\fP am +besten. +.IP \(bu 3 +Der x86\-Filter stellt eine Ausnahme dar. Es ist üblicherweise eine gute +Wahl, bei den Voreinstellungen von LZMA2 (\fBpb=2,lp=0,lc=3\fP) zu bleiben, +wenn Sie ausführbare x86\-Dateien komprimieren +.RE +.IP "" +Alle BCJ\-Filter unterstützen die gleichen \fIOptionen\fP: +.RS +.TP +\fBstart=\fP\fIVersatz\fP +gibt den Start\-\fIVersatz\fP an, der bei der Umwandlung zwischen relativen und +absoluten Adressen verwendet wird. Der \fIVersatz\fP muss ein Vielfaches der +Filterausrichtung sein (siehe die Tabelle oben). Der Standardwert ist 0. In +der Praxis ist dieser Standardwert gut; die Angabe eines benutzerdefinierten +\fIVersatzes\fP ist fast immer unnütz. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fIOptionen\fP] +fügt den Delta\-Filter zur Filterkette hinzu. Der Delta\-Filter kann nicht als +letzter Filter in der Filterkette verwendet werden. +.IP "" +Gegenwärtig wird nur eine einfache, Byte\-bezogene Delta\-Berechnung +unterstützt. Beim Komprimieren von zum Beispiel unkomprimierten +Bitmap\-Bildern oder unkomprimierten PCM\-Audiodaten kann es jedoch sinnvoll +sein. Dennoch können für spezielle Zwecke entworfene Algorithmen deutlich +bessere Ergebnisse als Delta und LZMA2 liefern. Dies trifft insbesondere auf +Audiodaten zu, die sich zum Beispiel mit \fBflac\fP(1) schneller und besser +komprimieren lassen. +.IP "" +Unterstützte \fIOptionen\fP: +.RS +.TP +\fBdist=\fP\fIAbstand\fP +gibt den \fIAbstand\fP der Delta\-Berechnung in Byte an. Zulässige Werte für den +\fIAbstand\fP sind 1 bis 256. Der Vorgabewert ist 1. +.IP "" +Zum Beispiel wird mit \fBdist=2\fP und der 8\-Byte\-Eingabe A1 B1 A2 B3 A3 B5 A4 +B7 die Ausgabe A1 B1 01 02 01 02 01 02 sein. +.RE +. +.SS "Andere Optionen" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +unterdrückt Warnungen und Hinweise. Geben Sie dies zweimal an, um auch +Fehlermeldungen zu unterdrücken. Diese Option wirkt sich nicht auf den +Exit\-Status aus. Das bedeutet, das selbst bei einer unterdrückten Warnung +der Exit\-Status zur Anzeige einer Warnung dennoch verwendet wird. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +bewirkt ausführliche Ausgaben. Wenn die Standardfehlerausgabe mit einem +Terminal verbunden ist, zeigt \fBxz\fP den Fortschritt an. Durch zweimalige +Angabe von \fB\-\-verbose\fP wird die Ausgabe noch ausführlicher. +.IP "" +Der Fortschrittsanzeiger stellt die folgenden Informationen dar: +.RS +.IP \(bu 3 +Der Prozentsatz des Fortschritts wird angezeigt, wenn die Größe der +Eingabedatei bekannt ist. Das bedeutet, dass der Prozentsatz in +Weiterleitungen (Pipes) nicht angezeigt werden kann. +.IP \(bu 3 +Menge der erzeugten komprimierten Daten (bei der Kompression) oder der +verarbeiteten Daten (bei der Dekompression). +.IP \(bu 3 +Menge der verarbeiteten unkomprimierten Daten (bei der Kompression) oder der +erzeugten Daten (bei der Dekompression). +.IP \(bu 3 +Kompressionsverhältnis, das mittels Dividieren der Menge der bisher +komprimierten Daten durch die Menge der bisher verarbeiteten unkomprimierten +Daten ermittelt wird. +.IP \(bu 3 +Kompressions\- oder Dekompressionsgeschwindigkeit. Diese wird anhand der +Menge der unkomprimierten verarbeiteten Daten (bei der Kompression) oder der +Menge der erzeugten Daten (bei der Dekompression) pro Sekunde gemessen. Die +Anzeige startet einige Sekunden nachdem \fBxz\fP mit der Verarbeitung der Datei +begonnen hat. +.IP \(bu 3 +Die vergangene Zeit im Format M:SS oder H:MM:SS. +.IP \(bu 3 +Die geschätzte verbleibende Zeit wird nur angezeigt, wenn die Größe der +Eingabedatei bekannt ist und bereits einige Sekunden vergangen sind, nachdem +\fBxz\fP mit der Verarbeitung der Datei begonnen hat. Die Zeit wird in einem +weniger präzisen Format ohne Doppelpunkte angezeigt, zum Beispiel 2 min 30 +s. +.RE +.IP "" +Wenn die Standardfehlerausgabe kein Terminal ist, schreibt \fBxz\fP mit +\fB\-\-verbose\fP nach dem Komprimieren oder Dekomprimieren der Datei in einer +einzelnen Zeile den Dateinamen, die komprimierte Größe, die unkomprimierte +Größe, das Kompressionsverhältnis und eventuell auch die Geschwindigkeit und +die vergangene Zeit in die Standardfehlerausgabe. Die Geschwindigkeit und +die vergangene Zeit werden nur angezeigt, wenn der Vorgang mindestens ein +paar Sekunden gedauert hat. Wurde der Vorgang nicht beendet, zum Beispiel +weil ihn der Benutzer abgebrochen hat, wird außerdem der Prozentsatz des +erreichten Verarbeitungsfortschritts aufgenommen, sofern die Größe der +Eingabedatei bekannt ist. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +setzt den Exit\-Status nicht auf 2, selbst wenn eine Bedingung erfüllt ist, +die eine Warnung gerechtfertigt hätte. Diese Option wirkt sich nicht auf die +Ausführlichkeitsstufe aus, daher müssen sowohl \fB\-\-quiet\fP als auch +\fB\-\-no\-warn\fP angegeben werden, um einerseits keine Warnungen anzuzeigen und +andererseits auch den Exit\-Status nicht zu ändern. +.TP +\fB\-\-robot\fP +gibt Meldungen in einem maschinenlesbaren Format aus. Dadurch soll das +Schreiben von Frontends erleichtert werden, die \fBxz\fP anstelle von Liblzma +verwenden wollen, was in verschiedenen Skripten der Fall sein kann. Die +Ausgabe mit dieser aktivierten Option sollte über mehrere +\fBxz\fP\-Veröffentlichungen stabil sein. Details hierzu finden Sie im Abschnitt +\fBROBOTER\-MODUS\fP. +.TP +\fB\-\-info\-memory\fP +zeigt in einem menschenlesbaren Format an, wieviel physischen Speicher (RAM) +und wie viele Prozessor\-Threads das System nach Annahme von \fBxz\fP hat, sowie +die Speicherbedarfsbegrenzung für Kompression und Dekompression, und beendet +das Programm erfolgreich. +.TP +\fB\-h\fP, \fB\-\-help\fP +zeigt eine Hilfemeldung mit den am häufigsten genutzten Optionen an und +beendet das Programm erfolgreich. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +zeigt eine Hilfemeldung an, die alle Funktionsmerkmale von \fBxz\fP beschreibt +und beendet das Programm erfolgreich. +.TP +\fB\-V\fP, \fB\-\-version\fP +zeigt die Versionsnummer von \fBxz\fP und Liblzma in einem menschenlesbaren +Format an. Um eine maschinell auswertbare Ausgabe zu erhalten, geben Sie +\fB\-\-robot\fP vor \fB\-\-version\fP an. +. +.SH ROBOTER\-MODUS +Der Roboter\-Modus wird mit der Option \fB\-\-robot\fP aktiviert. Er bewirkt, dass +die Ausgabe von \fBxz\fP leichter von anderen Programmen ausgewertet werden +kann. Gegenwärtig wird \fB\-\-robot\fP nur zusammen mit \fB\-\-list\fP, +\fB\-\-filters\-help\fP, \fB\-\-info\-memory\fP und \fB\-\-version\fP unterstützt. In der +Zukunft wird dieser Modus auch für Kompression und Dekompression +unterstützt. +. +.SS Listenmodus +\fBxz \-\-robot \-\-list\fP verwendet eine durch Tabulatoren getrennte Ausgabe. In +der ersten Spalte jeder Zeile bezeichnet eine Zeichenkette den Typ der +Information, die in dieser Zeile enthalten ist: +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP +Dies ist stets die erste Zeile, wenn eine Datei aufgelistet wird. Die zweite +Spalte in der Zeile enthält den Dateinamen. +.TP +\fBfile\fP +Diese Zeile enthält allgemeine Informationen zur \fB.xz\fP\-Datei. Diese Zeile +wird stets nach der \fBname\fP\-Zeile ausgegeben. +.TP +\fBstream\fP +Dieser Zeilentyp wird nur verwendet, wenn \fB\-\-verbose\fP angegeben wurde. Es +gibt genau so viele \fBstream\fP\-Zeilen, wie Datenströme in der \fB.xz\fP\-Datei +enthalten sind. +.TP +\fBblock\fP +Dieser Zeilentyp wird nur verwendet, wenn \fB\-\-verbose\fP angegeben wurde. Es +gibt so viele \fBblock\fP\-Zeilen, wie Blöcke in der \fB.xz\fP\-Datei. Die +\fBblock\fP\-Zeilen werden nach allen \fBstream\fP\-Zeilen angezeigt; verschiedene +Zeilentypen werden nicht verschachtelt. +.TP +\fBsummary\fP +Dieser Zeilentyp wird nur verwendet, wenn \fB\-\-verbose\fP zwei Mal angegeben +wurde. Diese Zeile wird nach allen \fBblock\fP\-Zeilen ausgegeben. Wie die +\fBfile\fP\-Zeile enthält die \fBsummary\fP\-Zeile allgemeine Informationen zur +\&\fB.xz\fP\-Datei. +.TP +\fBtotals\fP +Diese Zeile ist immer die letzte der Listenausgabe. Sie zeigt die +Gesamtanzahlen und \-größen an. +.PP +Die Spalten der \fBfile\fP\-Zeilen: +.PD 0 +.RS +.IP 2. 4 +Anzahl der Datenströme in der Datei +.IP 3. 4 +Gesamtanzahl der Blöcke in den Datenströmen +.IP 4. 4 +Komprimierte Größe der Datei +.IP 5. 4 +Unkomprimierte Größe der Datei +.IP 6. 4 +Das Kompressionsverhältnis, zum Beispiel \fB0.123\fP. Wenn das Verhältnis über +9.999 liegt, werden drei Minuszeichen (\fB\-\-\-\fP) anstelle des +Kompressionsverhältnisses angezeigt. +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +Durch Kommata getrennte Liste der Namen der Integritätsprüfungen. Für die +bekannten Überprüfungstypen werden folgende Zeichenketten verwendet: +\fBNone\fP, \fBCRC32\fP, \fBCRC64\fP und \fBSHA\-256\fP. \fBUnknown\-\fP\fIN\fP wird verwendet, +wobei \fIN\fP die Kennung der Überprüfung als Dezimalzahl angibt (ein\- oder +zweistellig). +.IP 8. 4 +Gesamtgröße der Datenstromauffüllung in der Datei +.RE +.PD +.PP +Die Spalten der \fBstream\fP\-Zeilen: +.PD 0 +.RS +.IP 2. 4 +Datenstromnummer (der erste Datenstrom ist 1) +.IP 3. 4 +Anzahl der Blöcke im Datenstrom +.IP 4. 4 +Komprimierte Startposition +.IP 5. 4 +Unkomprimierte Startposition +.IP 6. 4 +Komprimierte Größe (schließt die Datenstromauffüllung nicht mit ein) +.IP 7. 4 +Unkomprimierte Größe +.IP 8. 4 +Kompressionsverhältnis +.IP 9. 4 +Name der Integritätsprüfung +.IP 10. 4 +Größe der Datenstromauffüllung +.RE +.PD +.PP +Die Spalten der \fBblock\fP\-Zeilen: +.PD 0 +.RS +.IP 2. 4 +Anzahl der in diesem Block enthaltenen Datenströme +.IP 3. 4 +Blocknummer relativ zum Anfang des Datenstroms (der erste Block ist 1) +.IP 4. 4 +Blocknummer relativ zum Anfang der Datei +.IP 5. 4 +Komprimierter Startversatz relativ zum Beginn der Datei +.IP 6. 4 +Unkomprimierter Startversatz relativ zum Beginn der Datei +.IP 7. 4 +Komprimierte Gesamtgröße des Blocks (einschließlich Header) +.IP 8. 4 +Unkomprimierte Größe +.IP 9. 4 +Kompressionsverhältnis +.IP 10. 4 +Name der Integritätsprüfung +.RE +.PD +.PP +Wenn \fB\-\-verbose\fP zwei Mal angegeben wurde, werden zusätzliche Spalten in +die \fBblock\fP\-Zeilen eingefügt. Diese werden mit einem einfachen \fB\-\-verbose\fP +nicht angezeigt, da das Ermitteln dieser Informationen viele Suchvorgänge +erfordert und daher recht langsam sein kann: +.PD 0 +.RS +.IP 11. 4 +Wert der Integritätsprüfung in hexadezimaler Notation +.IP 12. 4 +Block\-Header\-Größe +.IP 13. 4 +Block\-Schalter: \fBc\fP gibt an, dass die komprimierte Größe verfügbar ist, und +\fBu\fP gibt an, dass die unkomprimierte Größe verfügbar ist. Falls der +Schalter nicht gesetzt ist, wird stattdessen ein Bindestrich (\fB\-\fP) +angezeigt, um die Länge der Zeichenkette beizubehalten. In Zukunft könnten +neue Schalter am Ende der Zeichenkette hinzugefügt werden. +.IP 14. 4 +Größe der tatsächlichen komprimierten Daten im Block. Ausgeschlossen sind +hierbei die Block\-Header, die Blockauffüllung und die Prüffelder. +.IP 15. 4 +Größe des Speichers (in Byte), der zum Dekomprimieren dieses Blocks mit +dieser \fBxz\fP\-Version benötigt wird. +.IP 16. 4 +Filterkette. Beachten Sie, dass die meisten der bei der Kompression +verwendeten Optionen nicht bekannt sein können, da in den \fB.xz\fP\-Headern nur +die für die Dekompression erforderlichen Optionen gespeichert sind. +.RE +.PD +.PP +Die Spalten der \fBsummary\fP\-Zeilen: +.PD 0 +.RS +.IP 2. 4 +Größe des Speichers (in Byte), der zum Dekomprimieren dieser Datei mit +dieser \fBxz\fP\-Version benötigt wird. +.IP 3. 4 +\fByes\fP oder \fBno\fP geben an, ob in allen Block\-Headern sowohl die +komprimierte als auch die unkomprimierte Größe gespeichert ist. +.PP +\fISeit\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +Minimale \fBxz\fP\-Version, die zur Dekompression der Datei erforderlich ist +.RE +.PD +.PP +Die Spalten der \fBtotals\fP\-Zeile: +.PD 0 +.RS +.IP 2. 4 +Anzahl der Datenströme +.IP 3. 4 +Anzahl der Blöcke +.IP 4. 4 +Komprimierte Größe +.IP 5. 4 +Unkomprimierte Größe +.IP 6. 4 +Durchschnittliches Kompressionsverhältnis +.IP 7. 4 +Durch Kommata getrennte Liste der Namen der Integritätsprüfungen, die in den +Dateien präsent waren. +.IP 8. 4 +Größe der Datenstromauffüllung +.IP 9. 4 +Anzahl der Dateien. Dies dient dazu, die Reihenfolge der vorigen Spalten an +die in den \fBfile\fP\-Zeilen anzugleichen. +.PD +.RE +.PP +Wenn \fB\-\-verbose\fP zwei Mal angegeben wird, werden zusätzliche Spalten in die +\fBtotals\fP\-Zeile eingefügt: +.PD 0 +.RS +.IP 10. 4 +Maximale Größe des Speichers (in Byte), der zum Dekomprimieren der Dateien +mit dieser \fBxz\fP\-Version benötigt wird. +.IP 11. 4 +\fByes\fP oder \fBno\fP geben an, ob in allen Block\-Headern sowohl die +komprimierte als auch die unkomprimierte Größe gespeichert ist. +.PP +\fISeit\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +Minimale \fBxz\fP\-Version, die zur Dekompression der Datei erforderlich ist +.RE +.PD +.PP +Zukünftige Versionen könnten neue Zeilentypen hinzufügen, weiterhin könnten +auch in den vorhandenen Zeilentypen weitere Spalten hinzugefügt werden, aber +die existierenden Spalten werden nicht geändert. +. +.SS Filterhilfe +\fBxz \-\-robot \-\-filters\-help\fP gibt die unterstützten Filter im folgenden +Format aus: +.PP +\fIFilter\fP\fB:\fP\fIOption\fP\fB=<\fP\fIWert\fP\fB>,\fP\fIOption\fP\fB=<\fP\fIWert\fP\fB>\fP +… +.TP +\fIFilter\fP +Name des Filters +.TP +\fIOption\fP +Name der filterspezifischen Option +.TP +\fIWert\fP +Der numerische \fIWert\fP erscheint als Bereich +\fB<\fP\fIMinimum\fP\fB\-\fP\fIMaximum\fP\fB>\fP. Die Auswahl des +Zeichenketten\-\fIWert\fPs wird in \fB< >\fP eingeschlossen und durch \fB|\fP +getrennt. +.PP +Jeder Filter wird in einer separaten Zeile ausgegeben. +. +.SS "Informationen zur Speicherbedarfsbegrenzung" +\fBxz \-\-robot \-\-info\-memory\fP gibt eine einzelne Zeile mit mehreren durch +Tabulatoren getrennten Spalten aus: +.IP 1. 4 +Gesamter physischer Speicher (RAM) in Byte. +.IP 2. 4 +Speicherbedarfsbegrenzung für die Kompression in Byte +(\fB\-\-memlimit\-compress\fP). Ein spezieller Wert von \fB0\fP bezeichnet die +Standardeinstellung, die im Einzelthread\-Modus bedeutet, dass keine +Begrenzung vorhanden ist. +.IP 3. 4 +Speicherbedarfsbegrenzung für die Dekompression in Byte +(\fB\-\-memlimit\-decompress\fP). Ein spezieller Wert von \fB0\fP bezeichnet die +Standardeinstellung, die im Einzelthread\-Modus bedeutet, dass keine +Begrenzung vorhanden ist. +.IP 4. 4 +Seit \fBxz\fP 5.3.4alpha: Die Speichernutzung für Multithread\-Dekompression in +Byte (\fB\-\-memlimit\-mt\-decompress\fP). Dies ist niemals \fB0\fP, da ein +systemspezifischer Vorgabewert (gezeigt in Spalte 5) verwendet wird, falls +keine Grenze ausdrücklich angegeben wurde. Dies ist außerdem niemals größer +als der Wert in in Spalte 3, selbst wenn mit \fB\-\-memlimit\-mt\-decompress\fP ein +größerer Wert angegeben wurde. +.IP 5. 4 +Seit \fBxz\fP 5.3.4alpha: Eine systemspezifisch vorgegebene Begrenzung des +Speicherverbrauchs, die zur Begrenzung der Anzahl der Threads beim +Komprimieren mit automatischer Anzahl der Threads (\fB\-\-threads=0\fP) und wenn +keine Speicherbedarfsbegrenzung angegeben wurde (\fB\-\-memlimit\-compress\fP) +verwendet wird. Dies wird auch als Standardwert für +\fB\-\-memlimit\-mt\-decompress\fP verwendet. +.IP 6. 4 +Seit \fBxz\fP 5.3.4alpha: Anzahl der verfügbaren Prozessorthreads. +.PP +In der Zukunft könnte die Ausgabe von \fBxz \-\-robot \-\-info\-memory\fP weitere +Spalten enthalten, aber niemals mehr als eine einzelne Zeile. +. +.SS Version +\fBxz \-\-robot \-\-version\fP gibt die Versionsnummern von \fBxz\fP und Liblzma im +folgenden Format aus: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +Hauptversion. +.TP +\fIYYY\fP +Unterversion. Gerade Zahlen bezeichnen eine stabile Version. Ungerade Zahlen +bezeichnen Alpha\- oder Betaversionen. +.TP +\fIZZZ\fP +Patch\-Stufe für stabile Veröffentlichungen oder einfach nur ein Zähler für +Entwicklungsversionen. +.TP +\fIS\fP +Stabilität. 0 ist Alpha, 1 ist Beta und 2 ist stabil. \fIS\fP sollte immer 2 +sein, wenn \fIYYY\fP eine gerade Zahl ist. +.PP +\fIXYYYZZZS\fP sind in beiden Zeilen gleich, sofern \fBxz\fP und Liblzma aus der +gleichen Veröffentlichung der XZ\-Utils stammen. +.PP +Beispiele: 4.999.9beta ist \fB49990091\fP und 5.0.0 is \fB50000002\fP. +. +.SH EXIT\-STATUS +.TP +\fB0\fP +Alles ist in Ordnung. +.TP +\fB1\fP +Ein Fehler ist aufgetreten. +.TP +\fB2\fP +Es ist etwas passiert, das eine Warnung rechtfertigt, aber es sind keine +tatsächlichen Fehler aufgetreten. +.PP +In die Standardausgabe geschriebene Hinweise (keine Warnungen oder Fehler), +welche den Exit\-Status nicht beeinflussen. +. +.SH UMGEBUNGSVARIABLEN +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP wertet eine durch Leerzeichen getrennte Liste von Optionen in den +Umgebungsvariablen \fBXZ_DEFAULTS\fP und \fBXZ_OPT\fP aus (in dieser Reihenfolge), +bevor die Optionen aus der Befehlszeile ausgewertet werden. Beachten Sie, +dass beim Auswerten der Umgebungsvariablen nur Optionen berücksichtigt +werden; alle Einträge, die keine Optionen sind, werden stillschweigend +ignoriert. Die Auswertung erfolgt mit \fBgetopt_long\fP(3), welches auch für +die Befehlszeilenargumente verwendet wird. +.PP +\fBWarnung:\fP Durch Setzen dieser Umgebungsvariablen könnte man effektiv +Programme und Skripte modifizieren, die \fBxz\fP ausführen. Meist ist es +sicher, die Speichernutzungsbegrenzung und Kompressionsoptionen über die +Umgebungsvariablen zu setzen. Dennoch können einige Optionen Skripte +beeinflussen. Ein typisches Beispiel ist die Option \fB\-\-help\fP, die einen +Hilfetext anzeigt, anstatt eine Datei zu komprimieren oder zu +dekomprimieren. Weniger augenfällige Beispiele sind die Optionen \fB\-\-quiet\fP +und \fB\-\-verbose\fP. In vielen Fällen funktioniert es gut, den +Fortschrittsindikator mit \fB\-\-verbose\fP zu aktivieren, aber in einigen +Situationen können die zusätzlichen Meldungen Probleme verursachen. Die +Ausführlichkeitsstufe beeinflusst auch das Verhalten von \fB\-\-list\fP. +.TP +\fBXZ_DEFAULTS\fP +Benutzerspezifische oder systemweite Standardoptionen. Typischerweise werden +diese in einem Shell\-Initialisierungsskript gesetzt, um die +Speicherbedarfsbegrenzung von \fBxz\fP standardmäßig zu aktivieren oder die +Anzahl der Threads festzulegen. Außer bei Shell\-Initialisierungsskripten und +in ähnlichen Spezialfällen sollte die Variable \fBXZ_DEFAULTS\fP in Skripten +niemals gesetzt oder außer Kraft gesetzt werden. +.TP +\fBXZ_OPT\fP +Dies dient der Übergabe von Optionen an \fBxz\fP, wenn es nicht möglich ist, +die Optionen direkt in der Befehlszeile von \fBxz\fP zu übergeben. Dies ist der +Fall, wenn \fBxz\fP von einem Skript oder Dienstprogramm ausgeführt wird, zum +Beispiel GNU \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +Skripte können \fBXZ_OPT\fP zum Beispiel zum Setzen skriptspezifischer +Standard\-Kompressionsoptionen verwenden. Es ist weiterhin empfehlenswert, +Benutzern die Außerkraftsetzung von \fBXZ_OPT\fP zu erlauben, falls dies +angemessen ist. Zum Beispiel könnte in \fBsh\fP(1)\-Skripten Folgendes stehen: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "KOMPATIBILITÄT ZU DEN LZMA\-UTILS" +Die Befehlszeilensyntax von \fBxz\fP ist praktisch eine Obermenge der von +\fBlzma\fP, \fBunlzma\fP und \fBlzcat\fP in den LZMA\-Utils der Versionen 4.32.x. In +den meisten Fällen sollte es möglich sein, die LZMA\-Utils durch die XZ\-Utils +zu ersetzen, ohne vorhandene Skripte ändern zu müssen. Dennoch gibt es +einige Inkompatibilitäten, die manchmal Probleme verursachen können. +. +.SS "Voreinstellungsstufen zur Kompression" +Die Nummerierung der Voreinstellungsstufen der Kompression ist in \fBxz\fP und +den LZMA\-Utils unterschiedlich. Der wichtigste Unterschied ist die Zuweisung +der Wörterbuchgrößen zu den verschiedenen Voreinstellungsstufen. Die +Wörterbuchgröße ist etwa gleich dem Speicherbedarf bei der Dekompression. +.RS +.PP +.TS +tab(;); +c c c +c n n. +Stufe;xz;LZMA\-Utils +\-0;256 KiB;nicht verfügbar +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +Die Unterschiede in der Wörterbuchgröße beeinflussen auch den Speicherbedarf +bei der Kompression, aber es gibt noch einige andere Unterschiede zwischen +den LZMA\-Utils und den XZ\-Utils, die die Kluft noch vergrößern: +.RS +.PP +.TS +tab(;); +c c c +c n n. +Stufe;xz;LZMA\-Utils 4.32.x +\-0;3 MiB;nicht verfügbar +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +Die standardmäßige Voreinstellungsstufe in den LZMA\-Utils ist \fB\-7\fP, während +diese in den XZ\-Utils \fB\-6\fP ist, daher verwenden beide standardmäßig ein 8 +MiB großes Wörterbuch. +. +.SS "Vor\- und Nachteile von .lzma\-Dateien als Datenströme" +Die unkomprimierte Größe der Datei kann in den \fB.lzma\fP\-Headern gespeichert +werden. Die LZMA\-Utils tun das beim Komprimieren gewöhnlicher Dateien. Als +Alternative kann die unkomprimierte Größe als unbekannt markiert und eine +Nutzdatenende\-Markierung (end\-of\-payload) verwendet werden, um anzugeben, wo +der Dekompressor stoppen soll. Die LZMA\-Utils verwenden diese Methode, wenn +die unkomprimierte Größe unbekannt ist, was beispielsweise in Pipes +(Befehlsverkettungen) der Fall ist. +.PP +\fBxz\fP unterstützt die Dekompression von \fB.lzma\fP\-Dateien mit oder ohne +Nutzdatenende\-Markierung, aber alle von \fBxz\fP erstellten \fB.lzma\fP\-Dateien +verwenden diesen Nutzdatenende\-Markierung, wobei die unkomprimierte Größe in +den \fB.lzma\fP\-Headern als unbekannt markiert wird. Das könnte in einigen +unüblichen Situationen ein Problem sein. Zum Beispiel könnte ein +\&\fB.lzma\fP\-Dekompressor in einem Gerät mit eingebettetem System nur mit +Dateien funktionieren, deren unkomprimierte Größe bekannt ist. Falls Sie auf +dieses Problem stoßen, müssen Sie die LZMA\-Utils oder das LZMA\-SDK +verwenden, um \fB.lzma\fP\-Dateien mit bekannter unkomprimierter Größe zu +erzeugen. +. +.SS "Nicht unterstützte .lzma\-Dateien" +Das \fB.lzma\fP\-Format erlaubt \fIlc\fP\-Werte bis zu 8 und \fIlp\fP\-Werte bis zu +4. Die LZMA\-Utils können Dateien mit beliebigem \fIlc\fP und \fIlp\fP +dekomprimieren, aber erzeugen immer Dateien mit \fBlc=3\fP und \fBlp=0\fP. Das +Erzeugen von Dateien mit anderem \fIlc\fP und \fIlp\fP ist mit \fBxz\fP und mit dem +LZMA\-SDK möglich. +.PP +Die Implementation des LZMA\-Filters in liblzma setzt voraus, dass die Summe +von \fIlc\fP und \fIlp\fP nicht größer als 4 ist. Daher können \fB.lzma\fP\-Dateien, +welche diese Begrenzung überschreiten, mit \fBxz\fP nicht dekomprimiert werden. +.PP +Die LZMA\-Utils erzeugen nur \fB.lzma\fP\-Dateien mit einer Wörterbuchgröße von +2^\fIn\fP (einer Zweierpotenz), aber akzeptieren Dateien mit einer beliebigen +Wörterbuchgröße. Liblzma akzeptiert nur \fB.lzma\fP\-Dateien mit einer +Wörterbuchgröße von 2^\fIn\fP oder 2^\fIn\fP + 2^(\fIn\fP\-1). Dies dient zum +Verringern von Fehlalarmen beim Erkennen von \fB.lzma\fP\-Dateien. +.PP +Diese Einschränkungen sollten in der Praxis kein Problem sein, da praktisch +alle \fB.lzma\fP\-Dateien mit Einstellungen komprimiert wurden, die Liblzma +akzeptieren wird. +. +.SS "Angehängter Datenmüll" +Bei der Dekompression ignorieren die LZMA\-Utils stillschweigend alles nach +dem ersten \fB.lzma\fP\-Datenstrom. In den meisten Situationen ist das ein +Fehler. Das bedeutet auch, dass die LZMA\-Utils die Dekompression verketteter +\&\fB.lzma\fP\-Dateien nicht unterstützen. +.PP +Wenn nach dem ersten \fB.lzma\fP\-Datenstrom Daten verbleiben, erachtet \fBxz\fP +die Datei als beschädigt, es sei denn, die Option \fB\-\-single\-stream\fP wurde +verwendet. Dies könnte die Ausführung von Skripten beeinflussen, die davon +ausgehen, dass angehängter Datenmüll ignoriert wird. +. +.SH ANMERKUNGEN +. +.SS "Die komprimierte Ausgabe kann variieren" +Die exakte komprimierte Ausgabe, die aus der gleichen unkomprimierten +Eingabedatei erzeugt wird, kann zwischen den Versionen der XZ\-Utils +unterschiedlich sein, selbst wenn die Kompressionsoptionen identisch +sind. Das kommt daher, weil der Kodierer verbessert worden sein könnte +(hinsichtlich schnellerer oder besserer Kompression), ohne das Dateiformat +zu beeinflussen. Die Ausgabe kann sogar zwischen verschiedenen Programmen +der gleichen Version der XZ\-Utils variieren, wenn bei der Erstellung des +Binärprogramms unterschiedliche Optionen verwendet wurden. +.PP +Sobald \fB\-\-rsyncable\fP implementiert wurde, bedeutet das, dass die sich +ergebenden Dateien nicht notwendigerweise mit Rsync abgeglichen werden +können, außer wenn die alte und neue Datei mit der gleichen \fBxz\fP\-Version +erzeugt wurden. Das Problem kann beseitigt werden, wenn ein Teil der +Encoder\-Implementierung eingefroren wird, um die mit Rsync abgleichbare +Ausgabe über \fBxz\fP\-Versionsgrenzen hinweg stabil zu halten. +. +.SS "Eingebettete .xz\-Dekompressoren" +Eingebettete \fB.xz\fP\-Dekompressor\-Implementierungen wie XZ Embedded +unterstützen nicht unbedingt Dateien, die mit anderen Integritätsprüfungen +(\fIPrüfung\fP\-Typen) als \fBnone\fP und \fBcrc32\fP erzeugt wurden. Da +\fB\-\-check=crc64\fP die Voreinstellung ist, müssen Sie \fB\-\-check=none\fP oder +\fB\-\-check=crc32\fP verwenden, wenn Sie Dateien für eingebettete Systeme +erstellen. +.PP +Außerhalb eingebetteter Systeme unterstützen die Dekompressoren des +\&\fB.xz\fP\-Formats alle \fIPrüfung\fP\-Typen oder sind mindestens in der Lage, die +Datei zu dekomprimieren, ohne deren Integrität zu prüfen, wenn die bestimmte +\fIPrüfung\fP nicht verfügbar ist. +.PP +XZ Embedded unterstützt BCJ\-Filter, aber nur mit dem vorgegebenen +Startversatz. +. +.SH BEISPIELE +. +.SS Grundlagen +Komprimiert die Datei \fIfoo\fP mit der Standard\-Kompressionsstufe (\fB\-6\fP) zu +\fIfoo.xz\fP und entfernt \fIfoo\fP nach erfolgreicher Kompression: +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +\fIbar.xz\fP in \fIbar\fP dekomprimieren und \fIbar.xz\fP selbst dann nicht löschen, +wenn die Dekompression erfolgreich war: +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +\fIbaz.tar.xz\fP mit der Voreinstellung \fB\-4e\fP (\fB\-4 \-\-extreme\fP) erzeugen, was +langsamer ist als die Vorgabe \fB\-6\fP, aber weniger Speicher für Kompression +und Dekompression benötigt (48\ MiB beziehungsweise 5\ MiB): +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +Eine Mischung aus komprimierten und unkomprimierten Dateien kann mit einem +einzelnen Befehl dekomprimiert in die Standardausgabe geschrieben werden: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "Parallele Kompression von vielen Dateien" +Auf GNU\- und *BSD\-Systemen können \fBfind\fP(1) und \fBxargs\fP(1) zum +Parallelisieren der Kompression vieler Dateien verwendet werden: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +Die Option \fB\-P\fP von \fBxargs\fP(1) legt die Anzahl der parallelen +\fBxz\fP\-Prozesse fest. Der beste Wert für die Option \fB\-n\fP hängt davon ab, wie +viele Dateien komprimiert werden sollen. Wenn es sich nur um wenige Dateien +handelt, sollte der Wert wahrscheinlich 1 sein; bei Zehntausenden von +Dateien kann 100 oder noch mehr angemessener sein, um die Anzahl der +\fBxz\fP\-Prozesse zu beschränken, die \fBxargs\fP(1) schließlich erzeugen wird. +.PP +Die Option \fB\-T1\fP für \fBxz\fP dient dazu, den Einzelthread\-Modus zu erzwingen, +da \fBxargs\fP(1) zur Steuerung des Umfangs der Parallelisierung verwendet +wird. +. +.SS Roboter\-Modus +Berechnen, wie viel Byte nach der Kompression mehrerer Dateien insgesamt +eingespart wurden: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +Ein Skript könnte abfragen wollen, ob es ein \fBxz\fP verwendet, das aktuell +genug ist. Das folgende \fBsh\fP(1)\-Skript prüft, ob die Versionsnummer des +Dienstprogramms \fBxz\fP mindestens 5.0.0 ist. Diese Methode ist zu alten +Beta\-Versionen kompatibel, welche die Option \fB\-\-robot\fP nicht unterstützen: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Ihre Version von Xz ist zu alt." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +Eine Speicherbedarfsbegrenzung für die Dekompression mit \fBXZ_OPT\fP setzen, +aber eine bereits gesetzte Begrenzung nicht erhöhen: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "Benutzerdefinierte Filterketten für die Kompression" +Der einfachste Anwendungsfall für benutzerdefinierte Filterketten ist die +Anpassung von LZMA2\-Voreinstellungsstufen. Das kann nützlich sein, weil die +Voreinstellungen nur einen Teil der potenziell sinnvollen Kombinationen aus +Kompressionseinstellungen abdecken. +.PP +Die KompCPU\-Spalten der Tabellen aus den Beschreibungen der Optionen \fB\-0\fP … +\fB\-9\fP und \fB\-\-extreme\fP sind beim Anpassen der LZMA2\-Voreinstellungen +nützlich. Diese sind die relevanten Teile aus diesen zwei Tabellen: +.RS +.PP +.TS +tab(;); +c c +n n. +Voreinst.;KomprCPU +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +Wenn Sie wissen, dass eine Datei für eine gute Kompression ein etwas +größeres Wörterbuch benötigt (zum Beispiel 32 MiB), aber Sie sie schneller +komprimieren wollen, als dies mit \fBxz \-8\fP geschehen würde, kann eine +Voreinstellung mit einem niedrigen KompCPU\-Wert (zum Beispiel 1) dahingehend +angepasst werden, ein größeres Wörterbuch zu verwenden: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +Mit bestimmten Dateien kann der obige Befehl schneller sein als \fBxz \-6\fP, +wobei die Kompression deutlich besser wird. Dennoch muss betont werden, dass +nur wenige Dateien von einem größeren Wörterbuch profitieren, wenn der +KompCPU\-Wert niedrig bleibt. Der offensichtlichste Fall, in dem ein größeres +Wörterbuch sehr hilfreich sein kann, ist ein Archiv, das einander sehr +ähnliche Dateien enthält, die jeweils wenigstens einige Megabyte groß +sind. Das Wörterbuch muss dann deutlich größer sein als die einzelne Datei, +damit LZMA2 den größtmöglichen Vorteil aus den Ähnlichkeiten der aufeinander +folgenden Dateien zieht. +.PP +Wenn hoher Speicherbedarf für Kompression und Dekompression kein Problem ist +und die zu komprimierende Datei mindestens einige Hundert Megabyte groß ist, +kann es sinnvoll sein, ein noch größeres Wörterbuch zu verwenden, als die 64 +MiB, die mit \fBxz \-9\fP verwendet werden würden: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +Die Verwendung von \fB\-vv\fP (\fB\-\-verbose \-\-verbose\fP) wie im obigen Beispiel +kann nützlich sein, um den Speicherbedarf für Kompressor und Dekompressor zu +sehen. Denken Sie daran, dass ein Wörterbuch, das größer als die +unkomprimierte Datei ist, Speicherverschwendung wäre. Daher ist der obige +Befehl für kleine Dateien nicht sinnvoll. +.PP +Manchmal spielt die Kompressionszeit keine Rolle, aber der Speicherbedarf +bei der Dekompression muss gering gehalten werden, zum Beispiel um die Datei +auf eingebetteten Systemen dekomprimieren zu können. Der folgende Befehl +verwendet \fB\-6e\fP (\fB\-6 \-\-extreme\fP) als Basis und setzt die Wörterbuchgröße +auf nur 64\ KiB. Die sich ergebende Datei kann mit XZ Embedded (aus diesem +Grund ist dort \fB\-\-check=crc32\fP) mit nur etwa 100\ KiB Speicher +dekomprimiert werden. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +Wenn Sie so viele Byte wie möglich herausquetschen wollen, kann die +Anpassung der Anzahl der literalen Kontextbits (\fIlc\fP) und der Anzahl der +Positionsbits (\fIpb\fP) manchmal hilfreich sein. Auch die Anpassung der Anzahl +der literalen Positionsbits (\fIlp\fP) könnte helfen, aber üblicherweise sind +\fIlc\fP und \fIpb\fP wichtiger. Wenn ein Quellcode\-Archiv zum Beispiel +hauptsächlich ASCII\-Text enthält, könnte ein Aufruf wie der folgende eine +etwas kleinere Datei (etwa 0,1\ %) ergeben als mit \fBxz \-6e\fP (versuchen Sie +es auch \fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar\fR +.fi +.RE +.PP +Die Verwendung eines anderen Filters mit LZMA2 kann die Kompression bei +verschiedenen Dateitypen verbessern. So könnten Sie eine gemeinsam genutzte +Bibliothek der Architekturen x86\-32 oder x86\-64 mit dem BCJ\-Filter für x86 +komprimieren: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +Beachten Sie, dass die Reihenfolge der Filteroptionen von Bedeutung +ist. Falls \fB\-\-x86\fP nach \fB\-\-lzma2\fP angegeben wird, gibt \fBxz\fP einen Fehler +aus, weil nach LZMA2 kein weiterer Filter sein darf und auch weil der +BCJ\-Filter für x86 nicht als letzter Filter in der Filterkette gesetzt +werden darf. +.PP +Der Delta\-Filter zusammen mit LZMA2 kann bei Bitmap\-Bildern gute Ergebnisse +liefern. Er sollte üblicherweise besser sein als PNG, welches zwar einige +fortgeschrittene Filter als ein simples delta bietet, aber für die +eigentliche Kompression »Deflate« verwendet. +.PP +Das Bild muss in einem unkomprimierten Format gespeichert werden, zum +Beispiel als unkomprimiertes TIFF. Der Abstandsparameter des Delta\-Filters +muss so gesetzt werden, dass er der Anzahl der Bytes pro Pixel im Bild +entspricht. Zum Beispiel erfordert ein 24\-Bit\-RGB\-Bitmap \fBdist=3\fP, außerdem +ist es gut, \fBpb=0\fP an LZMA2 zu übergeben, um die 3\-Byte\-Ausrichtung zu +berücksichtigen: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +Wenn sich mehrere Bilder in einem einzelnen Archiv befinden (zum Beispiel\& +\&\fB.tar\fP), funktioniert der Delta\-Filter damit auch, sofern alle Bilder im +Archiv die gleiche Anzahl Bytes pro Pixel haben. +. +.SH "SIEHE AUCH" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ Utils: +.br +XZ Embedded: +.br +LZMA\-SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/de/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/de/xzdec.1 new file mode 100644 index 000000000..e2812d181 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/de/xzdec.1 @@ -0,0 +1,88 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" German translation for xz-man. +.\" Mario Blättermann , 2015, 2019-2020, 2022-2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 "8. August 2024" Tukaani XZ\-Dienstprogramme +.SH BEZEICHNUNG +xzdec, lzmadec \- Kleine Dekompressoren für .xz und .lzma +.SH ÜBERSICHT +\fBxzdec\fP [\fIOption…\fP] [\fIDatei…\fP] +.br +\fBlzmadec\fP [\fIOption…\fP] [\fIDatei…\fP] +.SH BESCHREIBUNG +\fBxzdec\fP ist ein auf Liblzma basierendes Nur\-Dekompressionswerkzeug für +\&\fB.xz\fP\-Dateien (und \fBnur\fP für \fB.xz\fP\-Dateien). \fBxzdec\fP ist als direkter +Ersatz für \fBxz\fP(1) in jenen Situationen konzipiert, wo ein Skript \fBxz \-\-decompress \-\-stdout\fP (und eventuelle einige andere höufig genutzte +Optionen) zum Dekomprimieren von \fB.xz\fP\-Dateien. \fBlzmadec\fP ist weitgehend +identisch zu \fBxzdec\fP, mit der Ausnahme, dass \fBlzmadec\fP \fB.lzma\fP\-Dateien +anstelle von \fB.xz\fP\-Dateien unterstützt. +.PP +Um die Größe der ausführbaren Datei zu reduzieren, unterstützt \fBxzdec\fP +weder Multithreading noch Lokalisierung. Außerdem liest es keine Optionen +aus den Umgebungsvariablen \fBXZ_DEFAULTS\fP und \fBXZ_OPT\fP. \fBxzdec\fP +unterstützt keine zwischenzeitlichen Fortschrittsinformationen: Das Senden +von \fBSIGINFO\fP an \fBxzdec\fP hat keine Auswirkungen, jedoch beendet \fBSIGUSR1\fP +den Prozess, anstatt Fortschrittsinformationen anzuzeigen. +.SH OPTIONEN +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +ist zwecks Kompatibilität zu \fBxz\fP(1) vorhanden; wird ignoriert. \fBxzdec\fP +unterstützt nur Dekompression. +.TP +\fB\-k\fP, \fB\-\-keep\fP +ist zwecks Kompatibilität zu \fBxz\fP(1) vorhanden; wird ignoriert. \fBxzdec\fP +erzeugt oder entfernt niemals Dateien. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +ist zwecks Kompatibilität zu \fBxz\fP(1) vorhanden; wird ignoriert. \fBxzdec\fP +schreibt die dekomprimierten Daten immer in die Standardausgabe. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +hat bei einmaliger Angabe keine Wirkung, da \fBxzdec\fP niemals Warnungen oder +sonstige Meldungen anzeigt. Wenn Sie dies zweimal angeben, werden +Fehlermeldungen unterdrückt. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +ist zwecks Kompatibilität zu \fBxz\fP(1) vorhanden; wird ignoriert. \fBxzdec\fP +verwendet niemals den Exit\-Status 2. +.TP +\fB\-h\fP, \fB\-\-help\fP +zeigt eine Hilfemeldung an und beendet das Programm erfolgreich. +.TP +\fB\-V\fP, \fB\-\-version\fP +zeigt die Versionsnummer von \fBxzdec\fP und liblzma an. +.SH EXIT\-STATUS +.TP +\fB0\fP +Alles ist in Ordnung. +.TP +\fB1\fP +Ein Fehler ist aufgetreten. +.PP +\fBxzdec\fP gibt keine Warnmeldungen wie \fBxz\fP(1) aus, daher wird der +Exit\-Status 2 von \fBxzdec\fP nicht verwendet. +.SH ANMERKUNGEN +Verwenden Sie \fBxz\fP(1) anstelle von \fBxzdec\fP oder \fBlzmadec\fP im normalen +täglichen Gebrauch. \fBxzdec\fP oder \fBlzmadec\fP sind nur für Situationen +gedacht, in denen ein kleinerer Dekompressor statt des voll ausgestatteten +\fBxz\fP(1) wichtig ist. +.PP +\fBxzdec\fP und \fBlzmadec\fP sind nicht wirklich extrem klein. Die Größe kann +durch Deaktivieren von Funktionen bei der Kompilierung von Liblzma weiter +verringert werden, aber das sollte nicht für ausführbare Dateien getan +werden, die in typischen Betriebssystemen ausgeliefert werden, außer in den +Distributionen für eingebettete Systeme. Wenn Sie einen wirklich winzigen +Dekompressor für \fB.xz\fP\-Dateien brauchen, sollten Sie stattdessen XZ +Embedded in Erwägung ziehen. +.SH "SIEHE AUCH" +\fBxz\fP(1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/de/xzdiff.1 b/cpp/third_party/xz-5.8.3/po4a/man/de/xzdiff.1 new file mode 100644 index 000000000..2e8792537 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/de/xzdiff.1 @@ -0,0 +1,59 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" German translation for xz-man. +.\" Mario Blättermann , 2015, 2019-2020, 2022-2025. +.\" +.\" (Note that this file is not based on gzip's zdiff.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDIFF 1 "6. März 2025" Tukaani XZ\-Dienstprogramme +.SH BEZEICHNUNG +xzcmp, xzdiff, lzcmp, lzdiff \- komprimierte Dateien vergleichen +. +.SH ÜBERSICHT +\fBxzcmp\fP [\fIOption …\fP] \fIDatei1\fP [\fIDatei2\fP] +.br +\fBxzdiff\fP \&… +.br +\fBlzcmp\fP \&… (VERALTET) +.br +\fBlzdiff\fP \&… (VERALTET) +. +.SH BESCHREIBUNG +\fBxzcmp\fP und \fBxzdiff\fP vergleichen den unkomprimierten Inhalt zweier +Dateien. Die unkomprimierten Daten und Optionen werden an \fBcmp\fP(1) oder +\fBdiff\fP(1) übergeben, sofern weder \fB\-\-help\fP noch \fB\-\-version\fP angegeben +wird. +.PP +Wenn sowohl \fIDatei1\fP als auch \fIDatei2\fP angegeben sind, können diese +unkomprimierte Dateien oder Dateien in Formaten sein, die \fBxz\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1) oder \fBlz4\fP(1) +dekomprimieren können. Die erforderlichen Dekomprimierungsbefehle werden aus +den Dateiendungen von \fIDatei1\fP und \fIDatei2\fP abgeleitet. Für eine Datei mit +einer unbekannten Endung wird angenommen, dass sie entweder unkomprimiert +ist oder von \fBxz\fP(1) dekomprimiert werden kann. +.PP +Falls nur ein Dateiname angegeben wird, muss \fIDatei1\fP eine Endung eines +unterstützten Kompressionsformat haben und der Name von \fIDatei2\fP wird aus +\fIDatei1\fP abgeleitet, indem die Endung des Kompressionsformats entfernt +wird. +.PP +Die Befehle \fBlzcmp\fP und \fBlzdiff\fP dienen der Abwärtskompatibilität zu den +LZMA\-Dienstprogrammen. Sie werden als veraltet angesehen und werden in einer +zukünftigen Version entfernt. +. +.SH EXIT\-STATUS +Falls ein Dekompressionsfehler auftritt, ist der Exit\-Status +\fB2\fP. Anderenfalls wird der Exit\-Status von \fBcmp\fP(1) oder \fBdiff\fP(1) +verwendet. +. +.SH "SIEHE AUCH" +\fBcmp\fP(1), \fBdiff\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), +\fBzstd\fP(1), \fBlz4\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/de/xzgrep.1 b/cpp/third_party/xz-5.8.3/po4a/man/de/xzgrep.1 new file mode 100644 index 000000000..5b3f06176 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/de/xzgrep.1 @@ -0,0 +1,97 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" German translation for xz-man. +.\" Mario Blättermann , 2015, 2019-2020, 2022-2025. +.\" +.\" (Note that this file is not based on gzip's zgrep.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZGREP 1 "6. März 2025" Tukaani XZ\-Dienstprogramme +.SH BEZEICHNUNG +xzgrep \- möglicherweise komprimierte Dateien nach Mustern durchsuchen +. +.SH ÜBERSICHT +\fBxzgrep\fP [\fIOption …\fP] [\fIMusterliste\fP] [\fIDatei …\fP] +.br +\fBxzegrep\fP … +.br +\fBxzfgrep\fP … +.br +\fBlzgrep\fP \&… (VERALTET) +.br +\fBlzegrep\fP \&… (VERALTET) +.br +\fBlzfgrep\fP \&… (VERALTET) +. +.SH BESCHREIBUNG +\fBxzgrep\fP ruft \fBgrep\fP(1) mit dem unkomprimierten Inhalt von Dateien +auf. Die Formate der \fIDateien\fP werden aus den Dateiendungen +abgeleitet. Jede \fIDatei\fP mit einer Endung, die von \fBxz\fP(1), \fBgzip\fP(1), +\fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1) oder \fBlz4\fP(1) unterstützt wird, wird +dekomprimiert; für andere Dateien wird angenommen, dass sie bereits in +unkomprimierter Form vorliegen. +.PP +Wenn keine \fIDateien\fP angegeben werden oder \fIDatei\fP als \fB\-\fP angegeben +wird, wird aus der Standardeingabe gelesen. Beim Lesen aus der +Standardeingabe werden nur die von \fBxz\fP(1) unterstützten Dateien +dekomprimiert. Für andere Dateien wird angenommen, dass sie bereits in +unkomprimierter Form vorliegen. +.PP +Die meisten \fIOptionen\fP von \fBgrep\fP(1) werden unterstützt, die folgenden +jedoch nicht: +.IP "" 4 +\fB\-r\fP, \fB\-\-recursive\fP +.IP "" 4 +\fB\-R\fP, \fB\-\-dereference\-recursive\fP +.IP "" 4 +\fB\-d\fP, \fB\-\-directories=\fP\fIAktion\fP +.IP "" 4 +\fB\-Z\fP, \fB\-\-null\fP +.IP "" 4 +\fB\-z\fP, \fB\-\-null\-data\fP +.IP "" 4 +\fB\-\-include=\fP\fIGlob\fP +.IP "" 4 +\fB\-\-exclude=\fP\fIGlob\fP +.IP "" 4 +\fB\-\-exclude\-from=\fP\fIDatei\fP +.IP "" 4 +\fB\-\-exclude\-dir=\fP\fIGlob\fP +.PP +\fBxzegrep\fP ist ein Alias für \fBxzgrep \-E\fP. \fBxzfgrep\fP ist ein Alias für +\fBxzgrep \-F\fP. +.PP +Die Befehle \fBlzgrep\fP, \fBlzegrep\fP und \fBlzfgrep\fP dienen der +Abwärtskompatibilität zu den LZMA\-Dienstprogrammen. Sie werden als veraltet +angesehen und werden in einer zukünftigen Version entfernt. +. +.SH EXIT\-STATUS +.TP +0 +In mindestens einer der Eingabedateien wurde mindestens ein Treffer +gefunden. Es sind keine Fehler aufgetreten. +.TP +1 +In keiner der Eingabedateien wurde ein Treffer gefunden. Es sind keine +Fehler aufgetreten. +.TP +>1 +Ein oder mehrere Fehler sind aufgetreten. Es ist unbekannt, ob Treffer +gefunden wurden. +. +.SH UMGEBUNGSVARIABLEN +.TP +\fBGREP\fP +Wenn die Umgebungsvariable \fBGREP\fP auf einen nicht\-leeren Wert gesetzt ist, +wird diese anstelle von \fBgrep\fP(1), \fBgrep \-E\fP oder \fBgrep \-F\fP verwendet. +. +.SH "SIEHE AUCH" +\fBgrep\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), +\fBlz4\fP(1), \fBzgrep\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/de/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/de/xzless.1 new file mode 100644 index 000000000..5dbd5fc07 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/de/xzless.1 @@ -0,0 +1,50 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" German translation for xz-man. +.\" Mario Blättermann , 2015, 2019-2020, 2022-2025. +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 "6. März 2025" Tukaani XZ\-Dienstprogramme +.SH BEZEICHNUNG +xzless, lzless \- mit xz oder lzma komprimierte (Text\-)Dateien betrachten +.SH ÜBERSICHT +\fBxzless\fP [\fIDatei\fP …] +.br +\fBlzless\fP [\fIDatei\fP …] (VERALTET) +.SH BESCHREIBUNG +\fBxzless\fP ist ein Filter, der Text aus komprimierten Dateien in einem +Terminal anzeigt. Von \fBxz\fP(1) unterstützte Dateien werden dekomprimiert; +für andere Dateien wird angenommen, dass sie bereits in unkomprimierter Form +vorliegen. Wenn keine \fIDateien\fP angegeben werden, liest \fBxzless\fP aus der +Standardeingabe. +.PP +\fBxzless\fP verwendet \fBless\fP(1) zur Darstellung der Ausgabe. Im Gegensatz zu +\fBxzmore\fP können Sie das zu verwendende Textanzeigeprogramm nicht durch +Setzen einer Umgebungsvariable ändern. Die Befehle basieren auf \fBmore\fP(1) +und \fBvi\fP(1) und ermöglichen Vorwärts\- und Rückwärtssprünge sowie +Suchvorgänge. In der Handbuchseite zu \fBless\fP(1) finden Sie weitere +Informationen. +.PP +Der Befehl \fBlzless\fP dient der Abwärtskompatibilität zu den +LZMA\-Dienstprogrammen. Er wird als veraltet angesehen und wird in einer +zukünftigen Version entfernt. +.SH UMGEBUNGSVARIABLEN +.TP +\fBLESSMETACHARS\fP +Dies enthält eine Zeichenliste mit Bezug zur Shell. Wenn diese Variable +nicht bereits gesetzt ist, wird sie durch \fBxzless\fP gesetzt. +.TP +\fBLESSOPEN\fP +Dies ist auf die Befehlszeile zum Aufruf von \fBxz\fP(1) gesetzt, die zur +Vorverarbeitung der Eingabedateien für \fBless\fP(1) nötig ist. +.SH "SIEHE AUCH" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/de/xzmore.1 b/cpp/third_party/xz-5.8.3/po4a/man/de/xzmore.1 new file mode 100644 index 000000000..91b850d83 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/de/xzmore.1 @@ -0,0 +1,52 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" German translation for xz-man. +.\" Mario Blättermann , 2015, 2019-2020, 2022-2025. +.\" +.\" (Note that this file is based on xzless.1 instead of gzip's zmore.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZMORE 1 "6. März 2025" Tukaani XZ\-Dienstprogramme +.SH BEZEICHNUNG +xzmore, lzmore \- mit xz oder lzma komprimierte (Text\-)Dateien lesen +. +.SH ÜBERSICHT +\fBxzmore\fP [\fIDatei\fP …] +.br +\fBlzmore\fP [\fIDatei\fP …] (VERALTET) +. +.SH BESCHREIBUNG +\fBxzmore\fP zeigt Text aus komprimierten Dateien mit Hilfe des Pagers +(Textanzeigeprogramms) \fBmore\fP(1) in einem Terminal an. Von \fBxz\fP(1) +unterstützte Dateien werden dekomprimiert; für andere Dateien wird +angenommen, dass sie bereits in unkomprimierter Form vorliegen. Wenn keine +\fIDateien\fP angegeben werden, liest \fBxzmore\fP aus der Standardeingabe. Im +\fBmore\fP(1)\-Handbuch finden Sie Informationen zu den Tastaturbefehlen. +.PP +Beachten Sie, dass Zurückrollen nicht möglich sein könnte, abhängig von der +Implementierung von \fBmore\fP(1). Das kommt daher, dass \fBxzmore\fP eine Pipe +verwendet, um die dekomprimierten Daten an \fBmore\fP(1) zu +übergeben. \fBxzless\fP(1) verwendet \fBless\fP(1), welches fortgeschrittenere +Funktionen bietet. +.PP +Der Befehl \fBlzmore\fP dient der Abwärtskompatibilität zu den +LZMA\-Dienstprogrammen. Er wird als veraltet angesehen und wird in einer +zukünftigen Version entfernt. +. +.SH UMGEBUNGSVARIABLEN +.TP +.\" TRANSLATORS: Don't translate the uppercase PAGER. +.\" It is a name of an environment variable. +\fBPAGER\fP +Falls die Umgebungsvariable \fBPAGER\fP gesetzt ist, wird deren Wert als Pager +(Textanzeigeprogramm) anstelle von \fBmore\fP(1) verwendet. +. +.SH "SIEHE AUCH" +\fBmore\fP(1), \fBxz\fP(1), \fBxzless\fP(1), \fBzmore\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/fr/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/fr/lzmainfo.1 new file mode 100644 index 000000000..bcba91850 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/fr/lzmainfo.1 @@ -0,0 +1,47 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" french translation of XZ Utils man +.\" Copyright (C) 2021 Debian French l10n team +.\" Translator +.\" bubu , 2021. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 30\-06\-2013 Tukaani "Utilitaires XZ" +.SH NOM +lzmainfo \- Afficher l'information stockée dans l'en\-tête du fichier .lzma +.SH SYNOPSIS +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fIfichier...\fP] +.SH DESCRIPTION +\fBlzmainfo\fP affiche l'information stockée dans l'en\-tête du fichier +\&\fB.lzma\fP. Il lit les 13 premiers octets du \fIfichier\fP indiqué, décode +l'en\-tête, et l'écrit sur la sortie standard dans un format lisible par un +humain. Si aucun \fIfichier\fP n'est spécifié ou si \fIfichier\fP est \fB\-\fP, +l'entrée standard est lue. +.PP +Habituellement l'information la plus interressante est la taille non +compressée et la taille du dictionnaire. La taille ne peut être affichée que +si le fichier est dans la variante du format \fB.lzma\fP qui n'est pas en +flux. La quantité de mémoire requise pour décompresser le fichier est de +quelques douzaines de kilooctets en plus de la taille du dictionnaire. +.PP +\fBlzmainfo\fP est inclus dans les utilitaires XZ essentiellement pour des +besoins de rétrocompatibilité avec les utilitaires LZMA. +.SH "STATUT DE SORTIE" +.TP +\fB0\fP +Tout est bon. +.TP +\fB1\fP +Une erreur est survenue. +.SH BOGUES +\fBlzmainfo\fP utilise \fBMB\fP alors que le suffixe correct devrait être +\fBMiB\fP(2^20 octets). Cela pour garder la sortie compatible avec les +utilitaires LZMA. +.SH "VOIR AUSSI" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/fr/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/fr/xz.1 new file mode 100644 index 000000000..297dc7c0d --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/fr/xz.1 @@ -0,0 +1,2027 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" french translation of XZ Utils man +.\" Copyright (C) 2021 Debian French l10n team +.\" Translator +.\" bubu , 2021. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 2025\-03\-08 Tukaani "Utilitaires XZ" +. +.SH NOM +xz, unxz, xzcat, lzma, unlzma, lzcat \- Compresser ou décompresser des +fichiers .xz et .lzma +. +.SH SYNOPSIS +\fBxz\fP [\fIoption...\fP] [\fIfichier...\fP] +. +.SH "ALIAS DES COMMANDES" +\fBunxz\fP est équivalent à \fBxz \-\-decompress\fP. +.br +\fBxzcat\fP est équivalent à \fBxz \-\-decompress \-\-stdout\fP +.br +\fBlzma\fP est équivalent à \fBxz \-\-format=lzma\fP +.br +\fBunlzma\fP est équivalent à \fBxz \-\-format=lzma \-\-decompress\fP +.br +\fBlzcat\fP est équivalent à \fBxz \-\-format=lzma \-\-decompress \-\- stdout\fP +.PP +Lors de l'écriture de scripts qui nécessitent de décompresser des fichiers, +il est recommandé de toujours utiliser la commande \fBxz\fP avec les arguments +appropriés (\fBxz \-d\fP ou \fBxz \-dc\fP) au lieu des commandes \fBunxz\fP et +\fBxzcat\fP. +. +.SH DESCRIPTION +\fBxz\fP is a general\-purpose data compression tool with command line syntax +similar to \fBgzip\fP(1) and \fBbzip2\fP(1). The native file format is the +\&\fB.xz\fP format, but the legacy \fB.lzma\fP format used by LZMA Utils and raw +compressed streams with no container format headers are also supported. In +addition, decompression of the \fB.lz\fP format used by \fBlzip\fP is supported. +.PP +\fBxz\fP compresse ou décompresse chaque \fIfichier\fP en fonction du mode +d'opération choisi. Si aucun \fIfichier\fP n'est donné ou \fIfichier\fP est \fB\-\fP, +\fBxz\fP lit depuis l'entrée standard et écrit les données traitées sur la +sortie standard. \fBxz\fP refusera (affichera une erreur et ignorera le +\fIfichier\fP) d'écrire les données compressées sur la sortie standard si c'est +un terminal. De même, \fBxz\fP refusera de lire des données compressées depuis +l'entrée standard si c'est un terminal. +.PP +A moins que \fB\-\-sdout\fP ne soit indiqué, les \fIfichiers\fP autres que \fB\-\fP sont +écrits dans un nouveau fichier dont le nom est dérivé du nom de \fIfichier\fP +source : +.IP \(bu 3 +Lors de la compression, le suffixe du format de fichier cible (\fB.xz\fP ou +\&\fB.lzma\fP) est ajouté au nom de fichier source pour obtenir le nom de fichier +cible. +.IP \(bu 3 +When decompressing, the \fB.xz\fP, \fB.lzma\fP, or \fB.lz\fP suffix is removed from +the filename to get the target filename. \fBxz\fP also recognizes the suffixes +\&\fB.txz\fP and \fB.tlz\fP, and replaces them with the \fB.tar\fP suffix. +.PP +Si le fichier cible existe déjà, une erreur est affichée et le \fIfichier\fP +est ignoré. +.PP +Sauf s'il écrit dans la sortie standard, \fBxz\fP affichera un avertissement et +ignorera le \fIfichier\fP dans les cas suivants : +.IP \(bu 3 +\fIfichier\fP n'est pas un fichier normal. Les liens symboliques ne sont pas +suivis et donc ne sont pas considérés comme des fichiers normaux. +.IP \(bu 3 +\fIfichier\fP a plusieurs liens physiques. +.IP \(bu 3 +\fIfichier\fP a un setuid, setgid ou sticky bit positionné. +.IP \(bu 3 +Le mode d'opération est défini pour compresser et le \fIfichier\fP a déjà un +suffixe du format de fichier cible (\fB.xz\fP ou \fB.txz\fP lors d'une compression +en format \fB.xz\fP, et \fB.lzma\fP ou \fB.tlz\fP lors d'une compression en format +\&\fB.lzma\fP). +.IP \(bu 3 +The operation mode is set to decompress and the \fIfile\fP doesn't have a +suffix of any of the supported file formats (\fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, +\&\fB.tlz\fP, or \fB.lz\fP). +.PP +Après la compression ou la décompression réussie du \fIfichier\fP, \fBxz\fP copie +les permissions du propriétaire, du groupe, la date d'accès, et les +modifications d'heure depuis le \fIfichier\fP source du fichier cible. Si la +copie du groupe échoue, les permissions sont modifiées pour que le fichier +cible ne soit pas accessible aux utilisateurs qui n'ont pas les droits +d'accès au \fIfichier\fP source. \fBxz\fP ne prend actuellement pas en charge la +copie d'autres métadonnées telles que les listes de contrôle d'accès ou les +attributs étendus. +.PP +Once the target file has been successfully closed, the source \fIfile\fP is +removed unless \fB\-\-keep\fP was specified. The source \fIfile\fP is never removed +if the output is written to standard output or if an error occurs. +.PP +Envoyer \fBSIGINFO\fP ou \fBSIGURSR1\fP au processus \fBxz\fP, lui fait afficher +l'information de progression sur l'erreur standard. Cela a un intérêt limité +car lorsque l'erreur standard est un terminal, utiliser \fB\-\-verbose\fP +affichera automatiquement un indicateur de progression du processus. +. +.SS "Utilisation de la mémoire" +L'utilisation de la mémoire par \fBxz\fP varie de quelques centaines de +kilo\-octets à plusieurs gigaoctects en fonction des paramètres de +compression. Les réglages utilisés lors de la compression d'un fichier +déterminent les besoins en mémoire pour la décompression. Habituellement la +décompression nécessite 5\% à 20\% de la quantité de mémoire utilisée pour +la compression du fichier. Par exemple, décompresser un fichier créé avec +\fBxz\-9\fP recquiert habituellement 65\ Mio de mémoire. Bien qu'il soit +possible d'avoir des fichiers \fB.xz\fP nécessitant plusieurs gigaoctets de +mémoire pour être décompressés. +.PP +Especially users of older systems may find the possibility of very large +memory usage annoying. To prevent uncomfortable surprises, \fBxz\fP has a +built\-in memory usage limiter, which is disabled by default. While some +operating systems provide ways to limit the memory usage of processes, +relying on it wasn't deemed to be flexible enough (for example, using +\fBulimit\fP(1) to limit virtual memory tends to cripple \fBmmap\fP(2)). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +The memory usage limiter can be enabled with the command line option +\fB\-\-memlimit=\fP\fIlimit\fP. Often it is more convenient to enable the limiter +by default by setting the environment variable \fBXZ_DEFAULTS\fP, for example, +\fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP. It is possible to set the limits +separately for compression and decompression by using +\fB\-\-memlimit\-compress=\fP\fIlimit\fP and \fB\-\-memlimit\-decompress=\fP\fIlimit\fP. +Using these two options outside \fBXZ_DEFAULTS\fP is rarely useful because a +single run of \fBxz\fP cannot do both compression and decompression and +\fB\-\-memlimit=\fP\fIlimit\fP (or \fB\-M\fP \fIlimit\fP) is shorter to type on the +command line. +.PP +If the specified memory usage limit is exceeded when decompressing, \fBxz\fP +will display an error and decompressing the file will fail. If the limit is +exceeded when compressing, \fBxz\fP will try to scale the settings down so that +the limit is no longer exceeded (except when using \fB\-\-format=raw\fP or +\fB\-\-no\-adjust\fP). This way the operation won't fail unless the limit is very +small. The scaling of the settings is done in steps that don't match the +compression level presets, for example, if the limit is only slightly less +than the amount required for \fBxz \-9\fP, the settings will be scaled down only +a little, not all the way down to \fBxz \-8\fP. +. +.SS "Concaténation et remplissage avec des fichiers .xz" +Il est possible de concaténer les fichiers \fB.xz\fP tels quel. \fBxz\fP +décompressera de tels fichiers comme s'ils étaient un unique fichier \fB.xz\fP. +.PP +It is possible to insert padding between the concatenated parts or after the +last part. The padding must consist of null bytes and the size of the +padding must be a multiple of four bytes. This can be useful, for example, +if the \fB.xz\fP file is stored on a medium that measures file sizes in +512\-byte blocks. +.PP +La concaténation et le remplissage ne sont pas autorisés avec les fichiers +\&\fB.lzma\fP ou les flux bruts. +. +.SH OPTIONS +. +.SS "Suffixes entiers et valeurs spéciales." +Dans la plupart des endroits où un argument entier est attendu, un suffixe +optionel permet d'indiquer facilement les grands entiers. Il ne doit pas y +avoir d'espace entre l'entier et le suffixe. +.TP +\fBKiB\fP +Multiplier l'entier par 1024 (2^10). \fBKi\fP, \fBk\fP, \fBkB\fP, \fBK\fP et \fBKB\fP sont +acceptés comme synonymes de \fBKiB\fP. +.TP +\fBMiB\fP +Multiplier l'entier par 1 048 576 (2^20). \fBMi\fP, \fBm\fP, \fBM\fP et \fBMB\fP sont +acceptés comme synonymes de \fBMiB\fP. +.TP +\fBGiB\fP +Multiplier l'entier par 1 073 741 824 (2^30). \fBGi\fP, \fBg\fP, \fBG\fP et \fBGB\fP +sont acceptés comme synonymes de \fBGiB\fP. +.PP +La valeur spéciale \fBmax\fP peut être utilisée pour indiquer la valeur +maximale de l'entier prise en charge par l'option. +. +.SS "Mode d'opération" +Si plusieurs options de mode d'opération sont données, la dernière prend +effet. +.TP +\fB\-z\fP, \fB\-\-compress\fP +Compresser. C'est le mode d'opération par défaut lorsque aucune option de +mode opératoire n'est spécifiée ou qu'aucun autre mode d'opération n'est +sous\-entendu par le nom de la commande (par exemple \fBunxz\fP sous\-entend +\fB\-\-decompress\fP). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +After successful compression, the source file is removed unless writing to +standard output or \fB\-\-keep\fP was specified. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Decompress. After successful decompression, the source file is removed +unless writing to standard output or \fB\-\-keep\fP was specified. +.TP +\fB\-t\fP, \fB\-\-test\fP +Tester l'intégrité des \fIfichiers\fP compressés. Cette option est équivalente +à \fB\-\-decompress \-\-stdout\fP sauf que les données décompressées sont rejetées +au lieu d'être écrites sur la sortie standard. Aucun fichier n'est créé ou +supprimé. +.TP +\fB\-l\fP, \fB\-\-list\fP +Afficher l'information sur les \fIfichiers\fP compressés. Aucune sortie +non\-compressée n'est produite et aucun fichier n'est créé ou supprimé. En +mode liste, le programme ne peut pas lire les données compressées depuis +l'entrée standard ou depuis d'autres sources non adressables. +.IP "" +The default listing shows basic information about \fIfiles\fP, one file per +line. To get more detailed information, use also the \fB\-\-verbose\fP option. +For even more information, use \fB\-\-verbose\fP twice, but note that this may be +slow, because getting all the extra information requires many seeks. The +width of verbose output exceeds 80 characters, so piping the output to, for +example, \fBless\ \-S\fP may be convenient if the terminal isn't wide enough. +.IP "" +La sortie exacte peut varier suivant les versions de \fBxz\fP et les différents +paramètres régionaux. Pour une sortie lisible par la machine, utiliser +\fB\-\-robot \-\-list\fP. +. +.SS "Modificateurs d'opération" +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ne pas effacer les fichiers d'entrée. +.IP "" +Since \fBxz\fP 5.2.6, this option also makes \fBxz\fP compress or decompress even +if the input is a symbolic link to a regular file, has more than one hard +link, or has the setuid, setgid, or sticky bit set. The setuid, setgid, and +sticky bits are not copied to the target file. In earlier versions this was +only done with \fB\-\-force\fP. +.TP +\fB\-f\fP, \fB\-\-force\fP +Cette option a plusieurs effets : +.RS +.IP \(bu 3 +Si le fichier cible existe déjà, l'effacer avant de compresser ou +décompresser. +.IP \(bu 3 +Compresser ou décompresser même si l'entrée est un lien symbolique vers un +fichier normal, a plus qu'un lien physique, ou a le bit setuid, setgid ou +sticky défini. Les bits setuid, setgid et sticky bits ne sont pas copiés +dans le fichier cible. +.IP \(bu 3 +Lorsque \fBxz\fP est utilisé avec \fB\-\-decompress\fP \fB\-\-stdout\fP et qu'il ne peut +pas reconnaitre le type du fichier source, copier le fichier source tel quel +dans la sortie standard. Celà permet à \fBxzcat\fP \fB\-\-force\fP d'être utilisé +comme \fBcat\fP(1) pour les fichiers qui n'ont pas été compressé avec +\fBxz\fP. Remarquez que dans le futur, \fBxz\fP devrait prendre en charge de +nouveaux formats de fichiers compressés, ce qui permettra à \fBxz\fP de +décompresser plus de types de fichiers au lieu de les copier tels quels dans +la sortie standard. \fB\-\-format=\fP\fIformat\fP peut être utilisé pour contraindre +\fBxz\fP à décompresser seulement un format de fichier. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Écrire les données compressées ou décompressées sur la sortie standard +plutôt que dans un fichier. Cela necessite \fB\-\-keep\fP. +.TP +\fB\-\-single\-stream\fP +Décompresser seulement le premier flux \fB.xz\fP et ignorer silencieusement les +possibles données d'entrée résiduelles qui suivent le flux. Normalement ces +déchets excédentaires provoquent l'affichage d'une erreur par \fBxz\fP. +.IP "" +\fBxz\fP ne décompresse jamais plus d'un flux à partir de fichiers \fB.lzma\fP ou +de flux bruts, mais cette option fait aussi que \fBxz\fP ignorera les données +résiduelles après le fichier \fB.lzma\fP ou le flux brut. +.IP "" +Cette option n'a aucun effet si le mode d'opération n'est pas +\fB\-\-decompress\fP ou \fB\-\-test\fP. +.IP "" +Since \fBxz\fP 5.7.1alpha, \fB\-\-single\-stream\fP implies \fB\-\-keep\fP. +.TP +\fB\-\-no\-sparse\fP +Désactiver la création de fichiers peu denses. Par défaut, lors de la +décompression en un fichier normal, \fBxz\fP essaie d'en faire un fichier creux +si les données décompressées contiennent de longues séquences de zéros +binaires. Cela fonctionne aussi lors de l'écriture sur la sortie standard +aussi longtemps que la sortie standard est connectée à un fichier normal et +que certaines conditions supplémentaires sont satisfaites pour le faire de +manière sécurisée. Créer des fichiers creux peut épargner de l'espace disque +et accélérer la décompression en réduisant la quantité d'entrées/sorties sur +le disque. +.TP +\fB\-S\fP \fI.suf\fP, \fB\-\-suffix=\fP\fI.suf\fP +Lors de la compression, utiliser \fB.suf\fP comme suffixe du fichier cible au +lieu de \fB.xz\fP ou \fB.lzma\fP. Si \fBxz\fP n'écrit pas sur la sortie standard et +si le fichier source a déja le suffixe \fB.suf\fP, un avertissement est affiché +et le fichier est ignoré. +.IP "" +When decompressing, recognize files with the suffix \fI.suf\fP in addition to +files with the \fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP, or \fB.lz\fP suffix. If the +source file has the suffix \fI.suf\fP, the suffix is removed to get the target +filename. +.IP "" +Lors de la compression ou décompression de flux bruts (\fB\-\-fomat=raw\fP), le +suffixe doit toujours être spécifié à moins d'écrire sur la sortie standard, +car il n'y a pas de suffixe par défaut pour les flux bruts. +.TP +\fB\-\-files\fP[\fB=\fP\fIfichier\fP] +Lire les noms de fichier à traiter depuis \fIfichier\fP ; si \fIfichier\fP est +omis , les noms de fichier sont lus sur l'entrée standard. Les noms de +fichier doivent se terminer avec le caractère de nouvelle ligne. Un tiret +(\fB\-\fP) est considéré comme un nom de fichier normal ; ce qui ne signifie pas +entrée standard. Si les noms de fichier sont aussi donnés comme arguments de +ligne de commande, ils sont traités avant les noms de fichier lus depuis +\fIfichier\fP. +.TP +\fB\-\-files0\fP[\fB=\fP\fIfichier\fP] +Cela est identique à \fB\-\-files\fP[\fB=\fP\fIfichier\fP] sauf que chaque nom de +fichier doit se terminer par le caractère null. +. +.SS "Format de fichier basique et options de compression" +.TP +\fB\-F\fP \fIformat\fP, \fB\-\-format=\fP\fIformat\fP +Indiquer le \fIformat\fP de fichier à compresser ou décompresser : +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +C'est celui par défaut. Lors de la compression, \fBauto\fP est équivalent à +\fBxz\fP. Lors de la décompression, le format du fichier en entrée est détecté +automatiquement. Notez que les flux bruts (créés avec \fB\-\-format=raw\fP) ne +peuvent pas être détectés automatiquement. +.TP +\fBxz\fP +Compresser dans le format de fichier \fB.xz\fP ou n'accepter que les fichiers +\&\fB.xz\fP à décompresser. +.TP +\fBlzma\fP, \fBalone\fP +Compresser au format de fichier \fB.lzma\fP historique, ou n'accepter que les +fichiers \fB.lzma\fP lors de la décompression. Le nom alternatif \fBalone\fP est +fourni pour la rétrocompatibilité avec les utilitaires LZMA. +.TP +\fBlzip\fP +Accept only \fB.lz\fP files when decompressing. Compression is not supported. +.IP "" +The \fB.lz\fP format versions 0 and 1 are supported. Version 0 files were +produced by \fBlzip\fP 1.3 and older. Such files aren't common but may be +found from file archives as a few source packages were released in this +format. People might have old personal files in this format too. +Decompression support for the format version 0 was removed in \fBlzip\fP 1.18. +\fBlzip\fP 1.4 and later create files in the format version 1. +.TP +\fBraw\fP +Compresser ou décompresser un flux brut (sans en\-têtes). Cela est réservé +seulement aux utilisateurs aguerris. Pour décoder des flux bruts, vous devez +utiliser \fB\-\-format=raw\fP et spécifier explicitement la chaîne de filtre, qui +normalement aurait du être stockée dans les en\-têtes du conteneur. +.RE +.TP +\fB\-C\fP \fIvérif.\fP, \fB\-\-check=\fP\fIvérif.\fP +Spécifier le type d'intégrité à vérifier. La vérification est calculée à +partir des données non\-compressées et stockées dans le fichier \fB.xz\fP. Cette +option n'a effet que si la compression a été faite dans le format \fB.xz\fP ; +le format \fB.lzma\fP ne gère pas les vérifications d'intégrité. Le contrôle +d'intégrité (s'il y en a) est vérifié lorsque le fichier \fB.xz\fP est +décompressé. +.IP "" +Types de \fIvérification\fP pris en charge : +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +Ne pas calculer de vérification d'intégrité du tout. C'est généralement une +mauvaise idée. Cela peut être utile lorsque l'intégrité des données est +vérifiée de toute façon par d'autres manières. +.TP +\fBcrc32\fP +Calculer CRC32 en utilisant le polynôme de IEEE\-802.3 (Ethernet). +.TP +\fBcrc64\fP +Calculer CRC64 en utilisant le polynôme de ECMA\-182. C'est la manière +utilisée par défaut, car c'est légèrement mieux que CRC32 pour détecter les +fichiers endommagés et la différence de vitesse est négligeable. +.TP +\fBsha256\fP +Calculer SHA\-256. C'est quelque peu plus lent que CRC32 et CRC64. +.RE +.IP "" +L'intégrité des en\-têtes \fB.xz\fP est toujours vérifiée avec CRC32. Il n'est +pas possible de le changer ou de le désactiver. +.TP +\fB\-\-ignore\-check\fP +Ne pas contrôler la vérification d'intégrité des données lors de la +décompression. Les valeurs CRC32 dans les en\-têtes \fB.xz\fP seront normalement +toujours vérifiées. +.IP "" +\fBN'utilisez pas cette option à moins de savoir ce que vous faites.\fP Les +raisons possibles pour utiliser cette option : +.RS +.IP \(bu 3 +Essayer de récupérer des données d'un fichier .xz corrompu. +.IP \(bu 3 +Accélérer la décompression. Cela importe surtout avec SHA\-256 ou avec les +fichiers qui ont été compressés extrêmement bien. Il est recommandé de ne +pas utiliser cette option dans ce but à moins que l'intégrité du fichier ne +soit vérifiée extérieurement d'une autre manière. +.RE +.TP +\fB\-0\fP ... \fB\-9\fP +Choisir un niveau de compression prédéfini. La valeur par défaut est +\fB6\fP. Si plusieurs niveaux de préréglage sont spécifiés, c'est le dernier +qui sera pris en compte. Si une chaîne de filtres personnalisée a déjà été +choisie, définir un niveau de compression préréglé efface la chaîne de +filtres personnalisée. +.IP "" +Les différences entre les préréglages sont plus significatives qu'avec +\fBgzip\fP(1) et \fBbzip2\fP(1). les réglages de compression sélectionnés +déterminent les exigences en mémoire pour la décompression, ainsi, utiliser +un niveau de préréglage trop élevé peut rendre difficile à décompresser un +fichier sur un vieux système avec peu de RAM. Clairement, \fBce n'est pas une bonne idée d'utiliser \-9 aveuglément pour tout\fP comme ça l'est souvent avec +\fBgzip\fP(1) et \fBbzip2\fP(1). +.RS +.TP +\fB\-0\fP ... \fB\-3\fP +Ce sont des préréglages relativement rapides. \fB0\fP est parfois plus rapide +que \fBgzip \-9\fP tout en compressant bien mieux. Les réglages plus élevés ont +souvent une rapidité comparable à celle de \fBbzip2\fP(1) avec un taux de +compression comparable ou meilleur, même si les résultats dépendent beaucoup +du genre de données compressées. +.TP +\fB\-4\fP ... \fB\-6\fP +Good to very good compression while keeping decompressor memory usage +reasonable even for old systems. \fB\-6\fP is the default, which is usually a +good choice for distributing files that need to be decompressible even on +systems with only 16\ MiB RAM. (\fB\-5e\fP or \fB\-6e\fP may be worth considering +too. See \fB\-\-extreme\fP.) +.TP +\fB\-7 ... \-9\fP +C'est comme \fB\-6\fP mais avec des besoins en mémoire plus élevés pour la +compression et la décompression. Ce n'est utile que lorsque les fichiers +sont plus gros que 8\ Mio, 16\ Mio et 32\ Mio respectivement. +.RE +.IP "" +Sur le même matériel, la vitesse de décompression est sensiblement un nombre +constant d'octets de données compressées par seconde. En d'autres termes, +meilleure est la compression, plus rapide sera en général la +décompression. Cela signifie aussi que la quantité de sortie non compressée +produite par seconde peut varier beaucoup. +.IP "" +Le tableau suivant résume les caractéristiques des préréglages : +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Préréglage;DictSize;CompCPU;CompMem;DecMem +\-0;256 KiB;0;3 MiB;1 MiB +\-1;1 MiB;1;9 MiB;2 MiB +\-2;2 MiB;2;17 MiB;3 MiB +\-3;4 MiB;3;32 MiB;5 MiB +\-4;4 MiB;4;48 MiB;5 MiB +\-5;8 MiB;5;94 MiB;9 MiB +\-6;8 MiB;6;94 MiB;9 MiB +\-7;16 MiB;6;186 MiB;17 MiB +\-8;32 MiB;6;370 MiB;33 MiB +\-9;64 MiB;6;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Descriptions des colonnes : +.RS +.IP \(bu 3 +DictSize est la taille du dictionnaire de LZMA2. Utiliser un dictionnaire +plus gros que la taille du fichier non compressé est un gaspillage de +mémoire. C'est pourquoi il est bon d'éviter d'utiliser les préréglages de +\fB\-7\fP à \fB\-9\fP lorsqu'il n'y en a pas vraiment besoin. A \fB\-6\fP et plus bas, +la quantité de mémoire gaspillée est généralement assez basse pour ne pas +être un problème. +.IP \(bu 3 +CompCPU est une représentation des préréglages de LZMA2 qui affectent la +vitesse de compression. La taille du dictionnaire aussi affecte la vitesse, +alors comme CompCPU est le même pour les niveaux de \fB\-6\fP à \fB\-9\fP, les plus +haut niveaux tendent à être un peu moins rapides. Pour être encore moins +rapide et du coup obtenir peut être une meilleure compression, consultez +\fB\-\-extreme\fP. +.IP \(bu 3 +CompMem contains the compressor memory requirements in the single\-threaded +mode. It may vary slightly between \fBxz\fP versions. +.IP \(bu 3 +DecMem contient les besoins en mémoire du décompresseur. Ce sont les +réglages de la compression qui déterminent les besoins en mémoire de la +décompression. L'exacte utilisation de la mémoire est légèrement supérieure +à la taille du dictionnaire LZMA2, mais les valeurs dans la table ont été +arrondies au prochain Mio supérieur. +.RE +.IP "" +Memory requirements of the multi\-threaded mode are significantly higher than +that of the single\-threaded mode. With the default value of +\fB\-\-block\-size\fP, each thread needs 3*3*DictSize plus CompMem or DecMem. For +example, four threads with preset \fB\-6\fP needs 660\(en670\ MiB of memory. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +Utilisez un variant plus lent que les préréglages (\fB\-0\fP à \fB\-9\fP) pour +espérer avoir un taux de compression légèrement meilleur, mais en cas de +malchance cela peut être pire. L'utilisation mémoire du décompresseur n'est +pas affectée, mais l'utilisation mémoire du compresseur augmente un peu aux +niveaux de préréglages de \fB\-0\fP à \fB\-3\fP. +.IP "" +Depuis qu'il y a deux préréglages avec des tailles de dictionnaire de 4\ Mio +et 8 \Mio, les préréglages \fB\-3e\fP et \fB\-5e\fP utilisent des réglages +légèrement plus rapides que \fB\-4e\fP et \fB\-6e\fP, respectivement. De cette +manière, il n'y a pas deux préréglages identiques. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Préréglage;DictSize;CompCPU;CompMem;DecMem +\-0e;256 KiB;8;4 MiB;1 MiB +\-1e;1 MiB;8;13 MiB;2 MiB +\-2e;2 MiB;8;25 MiB;3 MiB +\-3e;4 MiB;7;48 MiB;5 MiB +\-4e;4 MiB;8;48 MiB;5 MiB +\-5e;8 MiB;7;94 MiB;9 MiB +\-6e;8 MiB;8;94 MiB;9 MiB +\-7e;16 MiB;8;186 MiB;17 MiB +\-8e;32 MiB;8;370 MiB;33 MiB +\-9e;64 MiB;8;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Par exemple, il y a un total de quatre préréglages qui utilisent un +dictionnaire de 8 Mio et qui sont dans l'ordre du plus rapide au plus lent : +\fB\-5\fP, \fB\-6\fP, \fB\-5e\fP et \fB\-6e\fP. +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +Il y a néanmoins des alias trompeurs pour \fB\-0\fP et \fB\-9\fP, +respectivement. Ils ne sont fournis que pour des besoins de +rétro\-compatibilité avec les utilitaires LZMA. Evitez d'utiliser ces +options. +.TP +\fB\-\-block\-size=\fP\fItaille\fP +Lors de la compression dans le format \fB.xz\fP, les données de l'entrée sont +réparties en blocs de \fItaille\fP octets. Les blocs sont compressés +indépendamment les un des autres, ce qui aide avec le mode multithread +(multi\-threading) et rend possible la décompression à accès aléatoire +limité. Cette option est typiquement utilisée pour outrepasser la taille de +bloc en mode multithread, mais cette option peut aussi être utilisée en mode +single\-thread. +.IP "" +In multi\-threaded mode about three times \fIsize\fP bytes will be allocated in +each thread for buffering input and output. The default \fIsize\fP is three +times the LZMA2 dictionary size or 1 MiB, whichever is more. Typically a +good value is 2\(en4 times the size of the LZMA2 dictionary or at least 1 +MiB. Using \fIsize\fP less than the LZMA2 dictionary size is waste of RAM +because then the LZMA2 dictionary buffer will never get fully used. In +multi\-threaded mode, the sizes of the blocks are stored in the block +headers. This size information is required for multi\-threaded +decompression. +.IP "" +In single\-threaded mode no block splitting is done by default. Setting this +option doesn't affect memory usage. No size information is stored in block +headers, thus files created in single\-threaded mode won't be identical to +files created in multi\-threaded mode. The lack of size information also +means that \fBxz\fP won't be able decompress the files in multi\-threaded mode. +.TP +\fB\-\-block\-list=\fP\fIitems\fP +When compressing to the \fB.xz\fP format, start a new block with an optional +custom filter chain after the given intervals of uncompressed data. +.IP "" +The \fIitems\fP are a comma\-separated list. Each item consists of an optional +filter chain number between 0 and 9 followed by a colon (\fB:\fP) and a +required size of uncompressed data. Omitting an item (two or more +consecutive commas) is a shorthand to use the size and filters of the +previous item. +.IP "" +If the input file is bigger than the sum of the sizes in \fIitems\fP, the last +item is repeated until the end of the file. A special value of \fB0\fP may be +used as the last size to indicate that the rest of the file should be +encoded as a single block. +.IP "" +An alternative filter chain for each block can be specified in combination +with the \fB\-\-filters1=\fP\fIfilters\fP \&...\& \fB\-\-filters9=\fP\fIfilters\fP options. +These options define filter chains with an identifier between 1\(en9. +Filter chain 0 can be used to refer to the default filter chain, which is +the same as not specifying a filter chain. The filter chain identifier can +be used before the uncompressed size, followed by a colon (\fB:\fP). For +example, if one specifies \fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP +then blocks will be created using: +.RS +.IP \(bu 3 +The filter chain specified by \fB\-\-filters1\fP and 2 MiB input +.IP \(bu 3 +The filter chain specified by \fB\-\-filters3\fP and 2 MiB input +.IP \(bu 3 +The filter chain specified by \fB\-\-filters2\fP and 4 MiB input +.IP \(bu 3 +The filter chain specified by \fB\-\-filters2\fP and 4 MiB input +.IP \(bu 3 +The default filter chain and 2 MiB input +.IP \(bu 3 +The default filter chain and 4 MiB input for every block until end of input. +.RE +.IP "" +If one specifies a size that exceeds the encoder's block size (either the +default value in threaded mode or the value specified with +\fB\-\-block\-size=\fP\fIsize\fP), the encoder will create additional blocks while +keeping the boundaries specified in \fIitems\fP. For example, if one specifies +\fB\-\-block\-size=10MiB\fP \fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP and the +input file is 80 MiB, one will get 11 blocks: 5, 10, 8, 10, 2, 10, 10, 4, +10, 10, and 1 MiB. +.IP "" +En mode multi\-threadé les tailles de blocs sont stockées dans les en\-têtes +du bloc. Cela ne se fait pas en mode mono\-threadé, la sortie encodée ne sera +donc pas identique à celle faite en mode multi\-threadé. +.TP +\fB\-\-flush\-timeout=\fP\fItemps_d'attente\fP +Lors de la compression, si plus que \fItemps_d'attente\fP millisecondes (un +entier positif) se sont écoulées depuis le précédent vidage et que lire plus +de données bloquerait, toutes les données d'entrée en attente sont vidées de +l'encodeur et mises à disposition dans le flux de sortie. Cela peut être +utile si \fBxz\fP est utilisé pour compresser les données qui sont diffusées +sur un réseau. Des petites valeurs de \fItemps_d'attente\fP rendent les données +disponibles à l'extrémité réceptrice avec un léger retard, mais les grandes +valeurs de \fItemps_d'attente\fP donnent un meilleur taux de compression. +.IP "" +Cette option est désactivée par défaut. Si cette option est indiquée plus +d'une fois, la dernière prend effet. La valeur spéciale de +\fItemps_d'attente\fP de \fB0\fP peut être utilisée pour explicitement désactiver +cette option. +.IP "" +Cette option n'est pas disponible sur les systèmes qui ne sont pas POSIX. +.IP "" +.\" FIXME +\fBCette option est encore expérimentale.\fP Actuellement, \fBxz\fP ne convient +pas pour décompresser le flux en temps réel en raison de la façon dont \fBxz\fP +effectue la mise en mémoire tampon. +.TP +\fB\-\-no\-sync\fP +Do not synchronize the target file and its directory to the storage device +before removing the source file. This can improve performance if +compressing or decompressing many small files. However, if the system +crashes soon after the deletion, it is possible that the target file was not +written to the storage device but the delete operation was. In that case +neither the original source file nor the target file is available. +.IP "" +This option has an effect only when \fBxz\fP is going to remove the source +file. In other cases synchronization is never done. +.IP "" +The synchronization and \fB\-\-no\-sync\fP were added in \fBxz\fP 5.7.1alpha. +.TP +\fB\-\-memlimit\-compress=\fP\fIlimite\fP +Indiquer une limite d'utilisation de la mémoire pour la compression. Si +cette option est indiquée plusieurs fois, c'est la dernière qui est prise en +compte. +.IP "" +If the compression settings exceed the \fIlimit\fP, \fBxz\fP will attempt to +adjust the settings downwards so that the limit is no longer exceeded and +display a notice that automatic adjustment was done. The adjustments are +done in this order: reducing the number of threads, switching to +single\-threaded mode if even one thread in multi\-threaded mode exceeds the +\fIlimit\fP, and finally reducing the LZMA2 dictionary size. +.IP "" +When compressing with \fB\-\-format=raw\fP or if \fB\-\-no\-adjust\fP has been +specified, only the number of threads may be reduced since it can be done +without affecting the compressed output. +.IP "" +If the \fIlimit\fP cannot be met even with the adjustments described above, an +error is displayed and \fBxz\fP will exit with exit status 1. +.IP "" +La \fIlimite\fP peut être indiquée de plusieurs façons : +.RS +.IP \(bu 3 +La \fIlimite\fP peut être une valeur absolue en octets. Utiliser un suffixe +d'entier comme \fBMiB\fP peut être utile. Exemple : +\fB\-\-memlimit\-compress=80MiB\fP +.IP \(bu 3 +La \fIlimite\fP peut être indiquée sous forme d'un pourcentage de la mémoire +physique totale (RAM). Cela peut être particulièrement utile quand la +variable d'environnement \fBXZ_DEFAULTS\fP est indiquée dans un script +d'initialisation de l'interpréteur partagé entre différents ordinateurs. De +cette façon la limite est automatiquement plus grande sur les systèmes avec +plus de mémoire. Exemple : \fB\-\-memlimit=70%\fP +.IP \(bu 3 +The \fIlimit\fP can be reset back to its default value by setting it to \fB0\fP. +This is currently equivalent to setting the \fIlimit\fP to \fBmax\fP (no memory +usage limit). +.RE +.IP "" +For 32\-bit \fBxz\fP there is a special case: if the \fIlimit\fP would be over +\fB4020\ MiB\fP, the \fIlimit\fP is set to \fB4020\ MiB\fP. On MIPS32 \fB2000\ MiB\fP +is used instead. (The values \fB0\fP and \fBmax\fP aren't affected by this. A +similar feature doesn't exist for decompression.) This can be helpful when +a 32\-bit executable has access to 4\ GiB address space (2 GiB on MIPS32) +while hopefully doing no harm in other situations. +.IP "" +Voir aussi la section \fButilisation de la mémoire\fP. +.TP +\fB\-\-memlimit\-decompress=\fP\fIlimite\fP +Régler une limite d'utilisation de la mémoire pour la décompression. Cela a +un effet sur le mode \fB\-\-list\fP. Si l'opération n'est pas possible sans +dépasser la \fIlimite\fP, \fBxz\fP affichera une erreur et la décompression +échouera. Voir \fB\-\-memlimit\-compress=\fP\fIlimite\fP pour les manières possibles +d'indiquer la \fIlimite\fP. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fIlimit\fP +Set a memory usage limit for multi\-threaded decompression. This can only +affect the number of threads; this will never make \fBxz\fP refuse to +decompress a file. If \fIlimit\fP is too low to allow any multi\-threading, the +\fIlimit\fP is ignored and \fBxz\fP will continue in single\-threaded mode. Note +that if also \fB\-\-memlimit\-decompress\fP is used, it will always apply to both +single\-threaded and multi\-threaded modes, and so the effective \fIlimit\fP for +multi\-threading will never be higher than the limit set with +\fB\-\-memlimit\-decompress\fP. +.IP "" +In contrast to the other memory usage limit options, +\fB\-\-memlimit\-mt\-decompress=\fP\fIlimit\fP has a system\-specific default +\fIlimit\fP. \fBxz \-\-info\-memory\fP can be used to see the current value. +.IP "" +This option and its default value exist because without any limit the +threaded decompressor could end up allocating an insane amount of memory +with some input files. If the default \fIlimit\fP is too low on your system, +feel free to increase the \fIlimit\fP but never set it to a value larger than +the amount of usable RAM as with appropriate input files \fBxz\fP will attempt +to use that amount of memory even with a low number of threads. Running out +of memory or swapping will not improve decompression performance. +.IP "" +See \fB\-\-memlimit\-compress=\fP\fIlimit\fP for possible ways to specify the +\fIlimit\fP. Setting \fIlimit\fP to \fB0\fP resets the \fIlimit\fP to the default +system\-specific value. +.TP +\fB\-M\fP \fIlimite\fP, \fB\-\-memlimit=\fP\fIlimite\fP, \fB\-\-memory=\fP\fIlimite\fP +This is equivalent to specifying \fB\-\-memlimit\-compress=\fP\fIlimit\fP +\fB\-\-memlimit\-decompress=\fP\fIlimit\fP \fB\-\-memlimit\-mt\-decompress=\fP\fIlimit\fP. +.TP +\fB\-\-no\-adjust\fP +Display an error and exit if the memory usage limit cannot be met without +adjusting settings that affect the compressed output. That is, this +prevents \fBxz\fP from switching the encoder from multi\-threaded mode to +single\-threaded mode and from reducing the LZMA2 dictionary size. Even when +this option is used the number of threads may be reduced to meet the memory +usage limit as that won't affect the compressed output. +.IP "" +Automatic adjusting is always disabled when creating raw streams +(\fB\-\-format=raw\fP). +.TP +\fB\-T\fP \fIthreads\fP, \fB\-\-threads=\fP\fIthreads\fP +Specify the number of worker threads to use. Setting \fIthreads\fP to a +special value \fB0\fP makes \fBxz\fP use up to as many threads as the processor(s) +on the system support. The actual number of threads can be fewer than +\fIthreads\fP if the input file is not big enough for threading with the given +settings or if using more threads would exceed the memory usage limit. +.IP "" +The single\-threaded and multi\-threaded compressors produce different +output. Single\-threaded compressor will give the smallest file size but +only the output from the multi\-threaded compressor can be decompressed using +multiple threads. Setting \fIthreads\fP to \fB1\fP will use the single\-threaded +mode. Setting \fIthreads\fP to any other value, including \fB0\fP, will use the +multi\-threaded compressor even if the system supports only one hardware +thread. (\fBxz\fP 5.2.x used single\-threaded mode in this situation.) +.IP "" +To use multi\-threaded mode with only one thread, set \fIthreads\fP to \fB+1\fP. +The \fB+\fP prefix has no effect with values other than \fB1\fP. A memory usage +limit can still make \fBxz\fP switch to single\-threaded mode unless +\fB\-\-no\-adjust\fP is used. Support for the \fB+\fP prefix was added in \fBxz\fP +5.4.0. +.IP "" +If an automatic number of threads has been requested and no memory usage +limit has been specified, then a system\-specific default soft limit will be +used to possibly limit the number of threads. It is a soft limit in sense +that it is ignored if the number of threads becomes one, thus a soft limit +will never stop \fBxz\fP from compressing or decompressing. This default soft +limit will not make \fBxz\fP switch from multi\-threaded mode to single\-threaded +mode. The active limits can be seen with \fBxz \-\-info\-memory\fP. +.IP "" +Actuellement, la seule méthode de gestion avec des threads consiste à +séparer l'entrée en blocs et de les compresser indépendamment les uns des +autres. La taille par défaut des blocs dépend du niveau de compression et +peut\-être remplacée avec l'option \fB\-\-block\-size=\fP\fItaille\fP. +.IP "" +Threaded decompression only works on files that contain multiple blocks with +size information in block headers. All large enough files compressed in +multi\-threaded mode meet this condition, but files compressed in +single\-threaded mode don't even if \fB\-\-block\-size=\fP\fIsize\fP has been used. +.IP "" +The default value for \fIthreads\fP is \fB0\fP. In \fBxz\fP 5.4.x and older the +default is \fB1\fP. +. +.SS "Chaînes de filtres de compresseur personnalisées" +A custom filter chain allows specifying the compression settings in detail +instead of relying on the settings associated to the presets. When a custom +filter chain is specified, preset options (\fB\-0\fP \&...\& \fB\-9\fP and +\fB\-\-extreme\fP) earlier on the command line are forgotten. If a preset +option is specified after one or more custom filter chain options, the new +preset takes effect and the custom filter chain options specified earlier +are forgotten. +.PP +Une chaîne de filtre est comparable à une redirection (pipe) sur la ligne de +commande. Lors de la compression, les entrées non compressées vont au +premier filtre, dont la sortie va au prochain filtre (s'il y en a). La +sortie du dernier filtre est écrite sur le fichier compressé. Le nombre +maximal de filtres dans la chaîne est quatre, mais habituellement, un chaîne +de filtre n'a qu'un ou deux filtres. +.PP +Beaucoup de filtres ont des limitations sur l'endroit où ils peuvent se +placer dans la chaîne de filtre : quelques filtres ne peuvent fonctionner +qu'en tant que dernier filtre dans la chaîne, quelques uns en tant que non +dernier filtre, et d'autres à n'importe quelle position dans la +chaîne. Suivant le filtre, cette limitation est soit inhérente au profil du +filtre, soit existe pour des raisons de sécurité. +.PP +A custom filter chain can be specified in two different ways. The options +\fB\-\-filters=\fP\fIfilters\fP and \fB\-\-filters1=\fP\fIfilters\fP \&...\& +\fB\-\-filters9=\fP\fIfilters\fP allow specifying an entire filter chain in one +option using the liblzma filter string syntax. Alternatively, a filter +chain can be specified by using one or more individual filter options in the +order they are wanted in the filter chain. That is, the order of the +individual filter options is significant! When decoding raw streams +(\fB\-\-format=raw\fP), the filter chain must be specified in the same order as +it was specified when compressing. Any individual filter or preset options +specified before the full chain option (\fB\-\-filters=\fP\fIfilters\fP) will be +forgotten. Individual filters specified after the full chain option will +reset the filter chain. +.PP +Both the full and individual filter options take filter\-specific \fIoptions\fP +as a comma\-separated list. Extra commas in \fIoptions\fP are ignored. Every +option has a default value, so specify those you want to change. +.PP +Pour voir l'entièreté de la chaîne de filtres et ses \fIoptions\fP, utilisez +\fBxz \-vv\fP (ce qui est comme utiliser \fB\-\-verbose\fP deux fois). Cela +fonctionne aussi pour voir les options de chaîne de filtres utilisées par +les préréglages. +.TP +\fB\-\-filters=\fP\fIfilters\fP +Specify the full filter chain or a preset in a single option. Each filter +can be separated by spaces or two dashes (\fB\-\-\fP). \fIfilters\fP may need to be +quoted on the shell command line so it is parsed as a single option. To +denote \fIoptions\fP, use \fB:\fP or \fB=\fP. A preset can be prefixed with a \fB\-\fP +and followed with zero or more flags. The only supported flag is \fBe\fP to +apply the same options as \fB\-\-extreme\fP. +.TP +\fB\-\-filters1\fP=\fIfilters\fP ... \fB\-\-filters9\fP=\fIfilters\fP +Specify up to nine additional filter chains that can be used with +\fB\-\-block\-list\fP. +.IP "" +For example, when compressing an archive with executable files followed by +text files, the executable part could use a filter chain with a BCJ filter +and the text part only the LZMA2 filter. +.TP +\fB\-\-filters\-help\fP +Display a help message describing how to specify presets and custom filter +chains in the \fB\-\-filters\fP and \fB\-\-filters1=\fP\fIfilters\fP \&...\& +\fB\-\-filters9=\fP\fIfilters\fP options, and exit successfully. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fIoptions\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fIoptions\fP] +.PD +Ajouter le filtre LZMA1 ou LZMA2 à la chaîne de filtres. Ces filtres ne +peuvent être utilisés que comme dernier filtre dans la chaîne. +.IP "" +LZMA1 est un filtre historique, qui n'est pris en charge presque uniquement +à cause de l'ancien format de fichier \fB.lzma\fP, qui ne prend en charge que +LZMA1. LZMA2 est une version mise à jour de LZMA1 pour régler certains +problèmes pratiques de LZMA1. Le format \fBxz\fP utilise LZMA2 et ne prend pas +du tout en charge LZMA1. Les taux et vitesses de compression de LZMA1 et +LZMA2 sont pratiquement identiques. +.IP "" +LZMA1 et LZMA2 partagent le même ensemble d'\fIoptions\fP : +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fIpréréglage\fP +Reset all LZMA1 or LZMA2 \fIoptions\fP to \fIpreset\fP. \fIPreset\fP consist of an +integer, which may be followed by single\-letter preset modifiers. The +integer can be from \fB0\fP to \fB9\fP, matching the command line options \fB\-0\fP +\&...\& \fB\-9\fP. The only supported modifier is currently \fBe\fP, which matches +\fB\-\-extreme\fP. If no \fBpreset\fP is specified, the default values of LZMA1 or +LZMA2 \fIoptions\fP are taken from the preset \fB6\fP. +.TP +\fBdict=\fP\fItaille\fP +La \fItaille\fP du dictionnaire (historique du tampon) indique combien d'octets +des données récement décompressées sont gardés en mémoire. L'algorithme +essaie de trouver les séquences d'octets répétées (identiques) dans les +données décompressées et les remplace par les données actuellement dans le +dictionnaire. Plus gros est le dictionnaire, plus grande est la chance de +trouver une correspondance. Ainsi, l'augmentation de la \fItaille\fP du +dictionnaire augmente habituellement le taux de compression, mais un +dictionnaire plus gros que le fichier non compressé est un gachis de +mémoire. +.IP "" +Généralement la \fItaille\fP du dictionnaire est entre 64\ Kio et 64\ Mio. Le +minimum étant 4\ Kio. La \fItaille\fP maximale pour la compression est +habituellement 1,5\ Gio (1536\ Mio). Le décompresseur prend en charge les +dictionnaires jusqu'à un octet de moins que 4\ Gio, ce qui est le maximum +pour les formats de flux LZMA1 et LZMA2. +.IP "" +La \fItaille\fP du dictionnaire et le chercheur de correspondance (match +finder) (\fImf\fP) déterminent ensemble l'utilisation de la mémoire de +l'encodeur LZMA1 ou LZMA2. La même (ou une plus grosse) \fItaille\fP de +dictionnaire est requise pour décompresser que ce qui a été utilisé pour la +compression, ainsi l'utilisation de la mémoire du décodeur est déterminée +par la taille du dictionnaire utilisée lors de la compression. Les en\-têtes +de \fB.xz\fP stockent la \fItaille\fP de dictionnaire sous la forme 2^\fIn\fP ou +2^\fIn\fP + 2^(\fIn\fP\-1), de sorte que ces \fItailles\fP sont quelque peu préférées +pour la compression. Les autres \fItailles\fP seront arrondies à la hausse +lorsque stockées dans les en\-têtes de \fB.xz\fP. +.TP +\fBlc=\fP\fIlc\fP +Spécifiez le nombre d'octets de contexte littéraux. Le minimum est \fB0\fP et +le maximum est \fB4\fP. La valeur par défaut est \fB3\fP. En plus, la somme de +\fIlc\fP et \fIlp\fP ne doit pas excéder \fB4\fP. +.IP "" +Tous les octets qui ne peuvent pas être codés comme des correspondances sont +codés comme des littéraux. C'est à dire que les littéraux sont simplement +des octets 8 bits encodés un à la fois. +.IP "" +The literal coding makes an assumption that the highest \fIlc\fP bits of the +previous uncompressed byte correlate with the next byte. For example, in +typical English text, an upper\-case letter is often followed by a lower\-case +letter, and a lower\-case letter is usually followed by another lower\-case +letter. In the US\-ASCII character set, the highest three bits are 010 for +upper\-case letters and 011 for lower\-case letters. When \fIlc\fP is at least +3, the literal coding can take advantage of this property in the +uncompressed data. +.IP "" +The default value (3) is usually good. If you want maximum compression, +test \fBlc=4\fP. Sometimes it helps a little, and sometimes it makes +compression worse. If it makes it worse, test \fBlc=2\fP too. +.TP +\fBlp=\fP\fIlp\fP +Indiquer le nombre de bits de position littérale. Le minimum est \fB0\fP et le +maximum \fB4\fP; par défaut c'est \fB0\fP. +.IP "" +\fILp\fP affecte le type d'alignement dans les données décompressées qui est +présumé lors de l'encodage des littéraux. Voir \fIpb\fP ci dessous pour plus +d'information sur l'alignement. +.TP +\fBpb=\fP\fIpb\fP +Indiquer le nombre de bits de position. Le minimum est \fB0\fP et le maximum +\fB4\fP; par défaut \fB2\fP. +.IP "" +\fIPb\fP affecte quel genre d'alignement est présumé en général dans les +données non compressées. Par défaut c'est un alignement de quatre octets +(2^\fIpb\fP=2^2=4), ce qui est généralement un bon choix lorsqu'il n'y a pas de +meilleure estimation. +.IP "" +When the alignment is known, setting \fIpb\fP accordingly may reduce the file +size a little. For example, with text files having one\-byte alignment +(US\-ASCII, ISO\-8859\-*, UTF\-8), setting \fBpb=0\fP can improve compression +slightly. For UTF\-16 text, \fBpb=1\fP is a good choice. If the alignment is +an odd number like 3 bytes, \fBpb=0\fP might be the best choice. +.IP "" +Même si l'alignement présumé peut être ajusté avec \fIpb\fP et \fIlp\fP, LZMA1 et +LZMA2 favorisent toujours légèrement l'alignement sur 16 octets. Il peut +être utile d'en tenir compte lors de la conception de formats de fichiers +susceptibles d'être souvent compressés avec LZMA1 ou LZMA2. +.TP +\fBmf=\fP\fImf\fP +Match finder has a major effect on encoder speed, memory usage, and +compression ratio. Usually Hash Chain match finders are faster than Binary +Tree match finders. The default depends on the \fIpreset\fP: 0 uses \fBhc3\fP, +1\(en3 use \fBhc4\fP, and the rest use \fBbt4\fP. +.IP "" +Les chercheurs de correspondance suivants sont pris en charge. Les formules +d'utilisation de la mémoire ci\-dessous sont des approximations grossières +qui sont les plus proches de la réalité lorsque \fIdict\fP est une puissance de +deux. +.RS +.TP +\fBhc3\fP +Chaîne de hachage avec hachage de 2 et 3 octets +.br +Valeur minimale pour \fInice\fP : \fB3\fP +.br +Utilisation de la mémoire : +.br +\fIdict\fP * 7.5 (if \fIdict\fP <= 16 Mio); +.br +\fIdict\fP * 5.5 + 64 MiB (si \fIdict\fP > 16 Mio) +.TP +\fBhc4\fP +Chaîne de hachage avec hachage de 2, 3 et 4 octets +.br +Valeur minimale pour \fInice\fP : \fB4\fP +.br +Utilisation de la mémoire : +.br +\fIdict\fP * 7.5 (si \fIdict\fP <= 32 Mio); +.br +\fIdict\fP * 6.5 (si \fIdict\fP > 32 Mio) +.TP +\fBbt2\fP +Arbre binaire avec hachage de 2 octets +.br +Valeur minimale pour \fInice\fP : \fB2\fP +.br +Utilisation de la mémoire : \fIdict\fP * 9.5 +.TP +\fBbt3\fP +Arbre binaire avec hachage de 2 et 3 octets +.br +Valeur minimale pour \fInice\fP : \fB3\fP +.br +Utilisation de la mémoire : +.br +\fIdict\fP * 11.5 (si \fIdict\fP <= 16 Mio); +.br +\fIdict\fP * 9.5 + 64 MiB (si \fIdict\fP > 16 Mio) +.TP +\fBbt4\fP +Arbre binaire avec hachage 2, 3 et 4 octets +.br +Valeur minimale pour \fInice\fP : \fB4\fP +.br +Utilisation de la mémoire : +.br +\fIdict\fP * 11.5 (si \fIdict\fP <= 32 Mio); +.br +\fIdict\fP * 10.5 (si \fIdict\fP > 32 Mio) +.RE +.TP +\fBmode=\fP\fImode\fP +Compression \fImode\fP specifies the method to analyze the data produced by the +match finder. Supported \fImodes\fP are \fBfast\fP and \fBnormal\fP. The default is +\fBfast\fP for \fIpresets\fP 0\(en3 and \fBnormal\fP for \fIpresets\fP 4\(en9. +.IP "" +Habituellement, \fBfast\fP est utilisé avec les chercheurs de correspondance de +chaîne de hachage et \fBnormal\fP avec les chercheurs de correspondance d'arbre +binaire. C'est aussi ce que font les \fIpréréglages\fP. +.TP +\fBnice=\fP\fInice\fP +Spécifier ce qui est considéré comme une bonne longueur pour une +correspondance. Une fois que la correspondance d'au moins \fInice\fP octets est +trouvée, l'algorithme arrête de chercher de meilleures correspondances +possibles. +.IP "" +\fINice\fP can be 2\(en273 bytes. Higher values tend to give better +compression ratio at the expense of speed. The default depends on the +\fIpreset\fP. +.TP +\fBdepth=\fP\fIprofondeur\fP +Spécifier la profondeur de recherche maximale dans l'outil de recherche de +correspondances. La valeur par défaut est \fB0\fP, ce qui fait que le +compresseur détermine une \fIprofondeur\fP raisonnable en fonction de \fImf\fP et +\fInice\fP. +.IP "" +Reasonable \fIdepth\fP for Hash Chains is 4\(en100 and 16\(en1000 for Binary +Trees. Using very high values for \fIdepth\fP can make the encoder extremely +slow with some files. Avoid setting the \fIdepth\fP over 1000 unless you are +prepared to interrupt the compression in case it is taking far too long. +.RE +.IP "" +Lors du décodage des flux bruts (\fB\-\-format=raw\fP), LZMA2 nécessite seulement +la \fItaille\fP du dictionnaire. LZMA1 nécessite aussi \fIlc\fP, \fIlp\fP et \fIpb\fP. +.TP +\fB\-\-x86\fP[\fB=\fP\fIoptions\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fIoptions\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fIoptions\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fIoptions\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fIoptions\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fIoptions\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fIoptions\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIoptions\fP] +.PD +Ajouter un filtre branch/call/jump (BCJ) à la chaîne de filtres. Ces filtres +ne peuvent être utilisés que s'ils ne sont pas le dernier filtre de la +chaîne de filtrage. +.IP "" +A BCJ filter converts relative addresses in the machine code to their +absolute counterparts. This doesn't change the size of the data but it +increases redundancy, which can help LZMA2 to produce 0\(en15\ % smaller +\&\fB.xz\fP file. The BCJ filters are always reversible, so using a BCJ filter +for wrong type of data doesn't cause any data loss, although it may make the +compression ratio slightly worse. The BCJ filters are very fast and use an +insignificant amount of memory. +.IP "" +Ces filtres BCJ présentent des problèmes connus liés au taux de +compression : +.RS +.IP \(bu 3 +Some types of files containing executable code (for example, object files, +static libraries, and Linux kernel modules) have the addresses in the +instructions filled with filler values. These BCJ filters will still do the +address conversion, which will make the compression worse with these files. +.IP \(bu 3 +If a BCJ filter is applied on an archive, it is possible that it makes the +compression ratio worse than not using a BCJ filter. For example, if there +are similar or even identical executables then filtering will likely make +the files less similar and thus compression is worse. The contents of +non\-executable files in the same archive can matter too. In practice one +has to try with and without a BCJ filter to see which is better in each +situation. +.RE +.IP "" +Different instruction sets have different alignment: the executable file +must be aligned to a multiple of this value in the input data to make the +filter work. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +Filtre;Alignement;Notes +x86;1;32 bits ou 64 bits x86 +ARM;4; +ARM\-Thumb;2; +ARM64;4;4096\-byte alignment is best +PowerPC;4;Grand boutiste seulement +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +Since the BCJ\-filtered data is usually compressed with LZMA2, the +compression ratio may be improved slightly if the LZMA2 options are set to +match the alignment of the selected BCJ filter. Examples: +.RS +.IP \(bu 3 +IA\-64 filter has 16\-byte alignment so \fBpb=4,lp=4,lc=0\fP is good with LZMA2 +(2^4=16). +.IP \(bu 3 +RISC\-V code has 2\-byte or 4\-byte alignment depending on whether the file +contains 16\-bit compressed instructions (the C extension). When 16\-bit +instructions are used, \fBpb=2,lp=1,lc=3\fP or \fBpb=1,lp=1,lc=3\fP is good. When +16\-bit instructions aren't present, \fBpb=2,lp=2,lc=2\fP is the best. +\fBreadelf \-h\fP can be used to check if "RVC" appears on the "Flags" line. +.IP \(bu 3 +ARM64 is always 4\-byte aligned so \fBpb=2,lp=2,lc=2\fP is the best. +.IP \(bu 3 +The x86 filter is an exception. It's usually good to stick to LZMA2's +defaults (\fBpb=2,lp=0,lc=3\fP) when compressing x86 executables. +.RE +.IP "" +Tous les filtres BCJ prennent en charge les mêmes \fIoptions\fP : +.RS +.TP +\fBstart=\fP\fIdécalage\fP +Spécifier le \fIdécalage\fP de départ qui est utilisé lors de la conversion +entre les adresses relatives et absolues. Le \fIdécalage\fP doit être un +multiple de l'alignement du filtre (voir la table ci\-dessus). Sa valeur par +défaut est zéro. En pratique, cette dernière convient ; indiquer un +\fIdécalage\fP personnalisé est la plupart du temps inutile. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fIoptions\fP] +Ajouter le filtre Delta à la chaîne de filtres. Le filtre Delta ne peut être +utilisé que s'il n'est pas le dernier filtre dans la chaîne. +.IP "" +Currently only simple byte\-wise delta calculation is supported. It can be +useful when compressing, for example, uncompressed bitmap images or +uncompressed PCM audio. However, special purpose algorithms may give +significantly better results than Delta + LZMA2. This is true especially +with audio, which compresses faster and better, for example, with +\fBflac\fP(1). +.IP "" +\fIoptions\fP prises en charge : +.RS +.TP +\fBdist=\fP\fIdistance\fP +Specify the \fIdistance\fP of the delta calculation in bytes. \fIdistance\fP must +be 1\(en256. The default is 1. +.IP "" +Par exemple, avec \fBdist=2\fP et une entrée huit octets A1 B1 A2 B3 A3 B5 A4 +B7, la sortie sera A1 B1 01 02 01 02 01 02. +.RE +. +.SS "Autres options" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Supprimer les avertissements et les notifications. Indiquer cela deux fois +supprimera aussi les erreurs. Cette option n'a aucun effet sur le statut de +sortie. Cela dit, même si un avertissement était supprimé, le statut de +sortie indiquant un avertissement sera encore utilisé. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +Être bavard. Si l'erreur standard est connectée à un terminal, \fBxz\fP +affichera une barre de progression. Indiquer \fB\-\-verbose\fP deux fois donnera +une sortie encore plus bavarde. +.IP "" +La barre de progression montre l'information suivante : +.RS +.IP \(bu 3 +Le pourcentage de complétion est montré si la taille du fichier en entrée +est connue. Néanmoins, le pourcentage ne peut pas être montré en cas de +redirection. +.IP \(bu 3 +Quantité de données compressées produites (compression) ou consommées +(décompression). +.IP \(bu 3 +Quantité de données non compressées consommées (compression) ou produites +(décompression). +.IP \(bu 3 +Le taux de compression, calculé en divisant la quantité de données +compréssées déjà traitées par la quantité de données décompressées déjà +traitées. +.IP \(bu 3 +Vitesse de compression ou de décompression. Elle correspond à la quantité de +données non compressées consommées (compression) ou produites +(décompression) par seconde. Elle apparait quelques secondes après le début +du traitement du fichier par \fBxz\fP. +.IP \(bu 3 +Temps écoulé dans le format M:SS ou H:MM:SS. +.IP \(bu 3 +Estimated remaining time is shown only when the size of the input file is +known and a couple of seconds have already passed since \fBxz\fP started +processing the file. The time is shown in a less precise format which never +has any colons, for example, 2 min 30 s. +.RE +.IP "" +When standard error is not a terminal, \fB\-\-verbose\fP will make \fBxz\fP print +the filename, compressed size, uncompressed size, compression ratio, and +possibly also the speed and elapsed time on a single line to standard error +after compressing or decompressing the file. The speed and elapsed time are +included only when the operation took at least a few seconds. If the +operation didn't finish, for example, due to user interruption, also the +completion percentage is printed if the size of the input file is known. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Ne pas mettre l'état de sortie à \fB2\fP même si une condition méritant un +avertissement a été détectée. Cette option n'affecte pas le niveau de +verbosité, néanmoins, les deux options \fB\-\-quiet\fP et \fB\-\-no\-warn\fP doivent +être utilisées pour ne pas afficher d'avertissements, ni altérer le statut +de sortie. +.TP +\fB\-\-robot\fP +Afficher les messages dans un format analysable par une machine. Ceci est +destiné à faciliter l'écriture des frontaux qui voudraient utiliser \fBxz\fP +plutôt que liblzma, ce qui pourrait être le cas pour différents scripts. La +sortie avec cette option activée est destinée à rester stable sur les +différentes versions de \fBxz\fP. Consulter le paragraphe \fBROBOT MODE\fP pour +les détails. +.TP +\fB\-\-info\-memory\fP +Display, in human\-readable format, how much physical memory (RAM) and how +many processor threads \fBxz\fP thinks the system has and the memory usage +limits for compression and decompression, and exit successfully. +.TP +\fB\-h\fP, \fB\-\-help\fP +Afficher un message d'aide décrivant les options les plus couramment +utilisées et quitter. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +Afficher un message d'aide décrivant toutes les options de \fBxz\fP et quitter. +.TP +\fB\-V\fP, \fB\-\-version\fP +Afficher le numéro de version de \fBxz\fP et de liblzma dans un format lisible +par un humain. Pour obtenir une sortie analysable par la machine, spécifiez +\fB\-\-robot\fP avant \fB\-\-version\fP. +. +.SH "MODE ROBOT" +The robot mode is activated with the \fB\-\-robot\fP option. It makes the output +of \fBxz\fP easier to parse by other programs. Currently \fB\-\-robot\fP is +supported only together with \fB\-\-list\fP, \fB\-\-filters\-help\fP, \fB\-\-info\-memory\fP, +and \fB\-\-version\fP. It will be supported for compression and decompression in +the future. +. +.SS "Mode liste" +\fBxz \-\-robot \-\-list\fP utilise une sortie séparée par des tabulations. La +première colonne de toutes les lignes possède une chaîne qui indique le type +d'information trouvée sur cette ligne : +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP +C'est toujours la première ligne au début de la liste d'un fichier. La +seconde colonne de la ligne est le nom de fichier. +.TP +\fBfile\fP +Cette ligne contient l'information globale sur le fichier \fB.xz\fP. Cette +ligne est toujours écrite après la ligne \fBname\fP. +.TP +\fBstream\fP +Ce type de ligne n'est utilisée que lorsque \fB \-\-verbose\fP a été indiquée. Il +y a autant de lignes \fBstream\fP qu'il y a de flux dans le fichier \fB.xz\fP. +.TP +\fBblock\fP +Ce type de ligne n'est utilisé seulement lorsque \fB\-\-verbose\fP a été +indiquée. Il y a autant de lignes \fBblock\fP qu'il y a de blocs dans le +fichier \fB.xz\fP. Les lignes \fBblock\fP sont affichées après toutes les lignes +\fBstream\fP ; les différents types de lignes ne sont pas imbriqués. +.TP +\fBsummary\fP +Ce type de ligne n'est utilisé que lorsque \fB\-\-verbose\fP a été indiqué deux +fois. Cette ligne est affichée après toutes les lignes \fBblock\fP. Comme la +ligne \fBfile\fP, la ligne \fBsummary\fP contient l'information globale sur le +fichier \fB.xz\fP. +.TP +\fBtotals\fP +Cette ligne est toujours la toute dernière ligne de la sortie. Elle affiche +les comptes et les tailles totaux. +.PP +Les colonnes des lignes \fBfile\fP : +.PD 0 +.RS +.IP 2. 4 +Nombre de flux dans le fichier +.IP 3. 4 +Nombre total de blocs dans le ou les flux. +.IP 4. 4 +Taille compressée du fichier +.IP 5. 4 +Taille décompressée du fichier +.IP 6. 4 +Compression ratio, for example, \fB0.123\fP. If ratio is over 9.999, three +dashes (\fB\-\-\-\fP) are displayed instead of the ratio. +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +Liste de noms de contrôles d'intégrité séparés par des virgules. Les chaînes +suivantes sont utilisées pour les types de vérification connus : \fBNone\fP, +\fBCRC32\fP, \fBCRC64\fP et \fBSHA256\fP. Pour le types de vérification inconnus, +\fBUnknown\-\fP\fIN\fP est utilisé, où \fIN\fP est un identifiant de vérification sous +la forme d'un nombre décimal (un ou deux chiffres). +.IP 8. 4 +Taille totale du remplissage du flux dans le fichier +.RE +.PD +.PP +Les colonnes des lignes \fBstream\fP : +.PD 0 +.RS +.IP 2. 4 +Numéro de flux (le premier flux a le numéro 1) +.IP 3. 4 +Nombre de blocs dans le flux +.IP 4. 4 +Décalage de départ compressé +.IP 5. 4 +Décalage de départ décompressé +.IP 6. 4 +Taille compressée (ne comprend pas le remplissage du flux) +.IP 7. 4 +Taille décompressée +.IP 8. 4 +Taux de compression +.IP 9. 4 +Nom de la vérification d'intégrité +.IP 10. 4 +Taille du remplissage de flux +.RE +.PD +.PP +Les colonnes des lignes \fBblock\fP : +.PD 0 +.RS +.IP 2. 4 +Numéro du flux qui contient ce bloc +.IP 3. 4 +Numéro du bloc relatif au commencement du flux (le premier bloc a pour +numéro 1) +.IP 4. 4 +Numéro du bloc relatif au début du fichier +.IP 5. 4 +Décalage de départ compressé relatif au début du fichier +.IP 6. 4 +Décalage de départ décompressé relatif au début du fichier +.IP 7. 4 +Taille compressée totale du bloc (en\-têtes inclus) +.IP 8. 4 +Taille décompressée +.IP 9. 4 +Taux de compression +.IP 10. 4 +Nom de la vérification d'intégrité +.RE +.PD +.PP +Si \fB\-\-verbose\fP a été indiqué deux fois, les colonnes additionnelles sont +inclues sur les lignes \fBblock\fP. Elles ne sont pas affichées avec un seul +\fB\-\-verbose\fP, car l'obtention de ces informations nécessite de nombreuses +recherches et peut donc être lente : +.PD 0 +.RS +.IP 11. 4 +Valeur de la vérification d'intégrité en hexadécimal +.IP 12. 4 +Taille d'en\-tête de bloc +.IP 13. 4 +Drapeaux du bloc : \fBc\fP indique que la taille compressée est présente, et +\fBu\fP indique que la taille décompréssée est présente. Si le drapeau n'est +pas indiqué, un tiret (\fB\-\fP) est affiché à la place pour que la longueur de +la chaîne reste fixe. De nouveaux drapeaux pourraient être ajoutés à la fin +de la chaîne dans le futur. +.IP 14. 4 +Taille des données effectivement compressées dans le bloc (en excluant +l'en\-tête de bloc, le remplissage de bloc et les champs de vérification). +.IP 15. 4 +Quantité de mémoire (en octets) nécessaire pour décompresser ce bloc avec +cette version de \fBxz\fP. +.IP 16. 4 +Chaîne de filtrage. Remarquez que la plupart des options utilisées au moment +de la compression ne peuvent pas être connues, car seules les options +nécessaires pour la décompression sont stockées dans les en\-têtes \fB.xz\fP. +.RE +.PD +.PP +Les colonnes des lignes \fBsummary\fP : +.PD 0 +.RS +.IP 2. 4 +Quantité de mémoire (en octets) nécessaire pour décompresser ce fichier avec +cette version de \fBxz\fP. +.IP 3. 4 +\fByes\fP ou \fBno\fP indique si tous les en\-têtes de bloc stockent à la fois la +taille compressée et la taille décompressée. +.PP +\fIDepuis\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +Version minimale de \fBxz\fP nécessaire pour décompresser le fichier. +.RE +.PD +.PP +Les colonnes de la ligne \fBtotals\fP : +.PD 0 +.RS +.IP 2. 4 +Nombre de flux +.IP 3. 4 +Nombre de blocs +.IP 4. 4 +Taille compressée +.IP 5. 4 +Taille décompressée +.IP 6. 4 +Taux de compression moyen +.IP 7. 4 +Liste séparée par des virgules des noms de vérification d'intégrité qui +étaient présents dans les fichiers +.IP 8. 4 +Taille de remplissage de flux +.IP 9. 4 +Nombre de fichiers. Permet de garder l'ordre des colonnes précédentes comme +sur les lignes \fBfile\fP. +.PD +.RE +.PP +Si \fB\-\-verbose\fP a été indiqué deux fois, des colonnes supplémentaires sont +incluses sur la ligne \fBtotals\fP : +.PD 0 +.RS +.IP 10. 4 +Quantité maximale de mémoire (en octets) nécessaire pour décompresser les +fichiers avec cette version de \fBxz\fP. +.IP 11. 4 +\fByes\fP ou \fBno\fP indique si tous les en\-têtes de bloc stockent à la fois la +taille compressée et la taille décompressée. +.PP +\fIDepuis\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +Version minimale de \fBxz\fP nécessaire pour décompresser le fichier. +.RE +.PD +.PP +Les versions futures pourront ajouter de nouveaux types de lignes et de +nouvelles colonnes pourront être ajoutées aux types de lignes existants, +mais les colonnes existantes ne seront pas modifiées. +. +.SS "Filters help" +\fBxz \-\-robot \-\-filters\-help\fP prints the supported filters in the following +format: +.PP +\fIfilter\fP\fB:\fP\fIoption\fP\fB=<\fP\fIvalue\fP\fB>,\fP\fIoption\fP\fB=<\fP\fIvalue\fP\fB>\fP... +.TP +\fIfilter\fP +Name of the filter +.TP +\fIoption\fP +Name of a filter specific option +.TP +\fIvalue\fP +Numeric \fIvalue\fP ranges appear as \fB<\fP\fImin\fP\fB\-\fP\fImax\fP\fB>\fP. String +\fIvalue\fP choices are shown within \fB< >\fP and separated by a \fB|\fP +character. +.PP +Each filter is printed on its own line. +. +.SS "Information de limite de mémoire" +\fBxz \-\-robot \-\-info\-memory\fP prints a single line with multiple tab\-separated +columns: +.IP 1. 4 +Total amount of physical memory (RAM) in bytes. +.IP 2. 4 +Memory usage limit for compression in bytes (\fB\-\-memlimit\-compress\fP). A +special value of \fB0\fP indicates the default setting which for +single\-threaded mode is the same as no limit. +.IP 3. 4 +Memory usage limit for decompression in bytes (\fB\-\-memlimit\-decompress\fP). A +special value of \fB0\fP indicates the default setting which for +single\-threaded mode is the same as no limit. +.IP 4. 4 +Since \fBxz\fP 5.3.4alpha: Memory usage for multi\-threaded decompression in +bytes (\fB\-\-memlimit\-mt\-decompress\fP). This is never zero because a +system\-specific default value shown in the column 5 is used if no limit has +been specified explicitly. This is also never greater than the value in the +column 3 even if a larger value has been specified with +\fB\-\-memlimit\-mt\-decompress\fP. +.IP 5. 4 +Since \fBxz\fP 5.3.4alpha: A system\-specific default memory usage limit that is +used to limit the number of threads when compressing with an automatic +number of threads (\fB\-\-threads=0\fP) and no memory usage limit has been +specified (\fB\-\-memlimit\-compress\fP). This is also used as the default value +for \fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +Since \fBxz\fP 5.3.4alpha: Number of available processor threads. +.PP +Dans le futur, la sortie de \fBxz \-\-robot \-\-info\-memory\fP pourrait avoir plus +de colonnes, mais jamais plus qu'une ligne unique. +. +.SS Version +\fBxz \-\-robot \-\-version\fP prints the version number of \fBxz\fP and liblzma in +the following format: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +Version majeure. +.TP +\fIYYY\fP +Version mineure. Les numéros pairs sont stables. Les numéros impairs sont +des versions alpha ou beta. +.TP +\fIZZZ\fP +Niveau de correctif pour les options stables ou juste un compteur pour les +options de développement. +.TP +\fIS\fP +Stabilité. 0 est alpha, 1 est bêta et 2 est stable. \fIS\fP devrait toujours +être 2 quand \fIYYY\fP est pair. +.PP +\fIXYYYZZZS\fP sont identiques sur les deux lignes si \fBxz\fP et liblzma sont +issus de la même version d'utilitaires XZ. +.PP +Exemples : 4.999.9beta est \fB49990091\fP et 5.0.0 est \fB50000002\fP. +. +.SH "STATUT DE SORTIE" +.TP +\fB0\fP +Tout est bon. +.TP +\fB1\fP +Une erreur est survenue. +.TP +\fB2\fP +Quelquechose méritant un avertissement s'est produit, mais aucune erreur +véritable n'est survenue. +.PP +Les notifications (pas les avertissements ou les erreurs) affichées sur +l'erreur standard n'affectent pas le statut de sortie. +. +.SH ENVIRONNEMENT +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP analyse les listes d'options séparées par des espaces à partir des +variables d'environnement \fBXZ_DEFAULTS\fP et \fBXZ_OPT\fP, dans cet ordre, avant +d'analyser les options de la ligne de commandes. Remarquez que seules les +options sont analysées depuis l'environnement des variables ; toutes les +non\-options sont ignorées silencieusement. L'analyse est faite avec +\fBgetopt_long\fP(3) qui est aussi utilisé pour les arguments de la ligne de +commandes. +.PP +\fBWarning:\fP By setting these environment variables, one is effectively +modifying programs and scripts that run \fBxz\fP. Most of the time it is safe +to set memory usage limits, number of threads, and compression options via +the environment variables. However, some options can break scripts. An +obvious example is \fB\-\-help\fP which makes \fBxz\fP show the help text instead of +compressing or decompressing a file. More subtle examples are \fB\-\-quiet\fP +and \fB\-\-verbose\fP. In many cases it works well to enable the progress +indicator using \fB\-\-verbose\fP, but in some situations the extra messages +create problems. The verbosity level also affects the behavior of +\fB\-\-list\fP. +.TP +\fBXZ_DEFAULTS\fP +User\-specific or system\-wide default options. Typically this is set in a +shell initialization script to enable \fBxz\fP's memory usage limiter by +default or set the default number of threads. Excluding shell +initialization scripts and similar special cases, scripts should never set +or unset \fBXZ_DEFAULTS\fP. +.TP +\fBXZ_OPT\fP +This is for passing options to \fBxz\fP when it is not possible to set the +options directly on the \fBxz\fP command line. This is the case when \fBxz\fP is +run by a script or tool, for example, GNU \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +Scripts may use \fBXZ_OPT\fP, for example, to set script\-specific default +compression options. It is still recommended to allow users to override +\fBXZ_OPT\fP if that is reasonable. For example, in \fBsh\fP(1) scripts one may +use something like this: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "Compatibilité des utilitaires LZMA" +La syntaxe de la ligne de commande de \fBxz\fP est quasimment un sur\-ensemble +de \fBlzma\fP, \fBunlzma\fP et \fBlzcat\fP comme ils sont trouvés dans les +utilitaires LZMA 4.32.x . Dans la pluspart des cas, il est possible de +remplacer les outils LZMA par les outils XZ sans casser les scripts +existants. Il existe cependant certaines incompatibilités qui peuvent +parfois poser des problèmes. +. +.SS "Niveaux de préréglage de la compression" +La numérotation des préréglages de niveau de compression est différente +entre les outils \fBxz\fP et LZMA. La différence la plus importante est la +manière dont les tailles de dictionnaire sont affectées aux différents +préréglages. La taille de dictionnaire est à peu près égale à celle +d'utilisation de la mémoire de la décompression. +.RS +.PP +.TS +tab(;); +c c c +c n n. +Niveau;xz;Utilitaires LZMA +\-0;256 KiB;N/A +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +Les différences de tailles des dictionnaires affectent aussi l'utilisation +de la mémoire du compresseur, mais il y a quelques autres différences entre +les outils LZMA et les outils XZ, qui rendent la différence encore plus +grande : +.RS +.PP +.TS +tab(;); +c c c +c n n. +Niveau;xz;Utilitaires LZMA 4.32.x +\-0;3 MiB;N/A +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +Le niveau de préréglage par défaut dans les outils LZMA est \fB\-7\fP alors que +pour les outils XZ c'est \fB\-6\fP, les deux utilisent ainsi un dictionnaire de +8 Mio par défaut. +. +.SS "Fichiers .lzma en flux ou non" +The uncompressed size of the file can be stored in the \fB.lzma\fP header. +LZMA Utils does that when compressing regular files. The alternative is to +mark that uncompressed size is unknown and use end\-of\-payload marker to +indicate where the decompressor should stop. LZMA Utils uses this method +when uncompressed size isn't known, which is the case, for example, in +pipes. +.PP +\fBxz\fP prend en charge la décompression des fichiers \fB.lzma\fP avec ou sans +marqueur de fin de charge utile, mais tous les fichiers \fB.lzma\fP créés par +\fBxz\fP utiliseront un marqueur de fin de charge utile et ont la taille non +compréssée marquée comme inconnue dans l'en\-tête \fB.lzma\fP. Cela peut être un +problème dans quelques situations inhabituelles. Par exemple, un +décompresseur \fB.lzma\fP dans un périphérique embarqué pourrait ne fonctionner +qu'avec des fichiers dont la taille non comprimée est connue. Si vous vous +heurtez à ce problème, vous devez utiliser les utilitaires LZMA ou LZMA SDK +pour créer des fichiers \fB.lzma\fP avec une taille non compressée connue. +. +.SS "Fichiers .lzma non pris en charge" +Le format \fB.lzma\fP autorise des valeurs \fIlc\fP jusqu'à 8, et des valeurs +\fIlp\fP jusqu'à 4. Les outils LZMA peuvent décompresser des fichiers avec tous +les \fIlc\fP et \fIlp\fP, mais créez toujours les fichiers avec \fBlc=3\fP et +\fBlp=0\fP. Créer des fichiers avec d'autres valeurs \fIlc\fP et \fIlp\fP est +possible avec \fBxz\fP et avec LZMA SDK. +.PP +L'implémentation du filtre LZMA1 dans liblzma nécessite que la somme de +\fIlc\fP et \fIlp\fP soit inférieure ou égale à 4. Ainsi, les fichiers \fB.lzma\fP +qui excèdent cette limitation ne peuvent pas être décompressés avec \fBxz\fP. +.PP +Les outils LZMA créent seulement des fichiers \fB.lzma\fP qui ont une taille de +dictionnaire de 2^\fIn\fP (une puissance de 2) mais acceptent les fichiers avec +toutes les tailles de dictionnaire. Libzlma n'accepte que les fichiers +\&\fB.lzma\fP qui ont une taille dictionnaire de 2^\fIn\fP ou +2^\fIn\fP + 2^(\fIn\fP\-1). Cela afin de diminuer les faux positifs lors de la +détection des fichiers \fB.lzma\fP. +.PP +Ces limitations ne devraient pas poser problème en pratique, car +pratiquement tous les fichiers \fB.lzma\fP ont été compressés avec des réglages +que liblzma accepte. +. +.SS "Déchets excédentaires" +Lors de la décompession, l'utilitaire LZMA ignore silencieusement tout ce +qui est après le premier flux \fB.lzma\fP. Dans la majorité des situations, +c'est un bogue. Cela veut dire aussi que les outils LZMA ne gèrent pas la +décompression de fichiers \fB.lzma\fP concaténés. +.PP +S'il reste des données après le premier flux \fB.lzma\fP, \fBxz\fP considère que +le fichier est corrompu sauf si \fB\-\-single\-stream\fP a été utilisé. Cela peut +casser des scripts obscurs qui ont supposé que les déchets de fin de ligne +sont ignorés. +. +.SH NOTES +. +.SS "La sortie compressée peut varier" +La sortie compressée exacte produite par les même fichiers non compressés en +entrée peut varier en fonction des différentes versions de l'utilitaire XZ, +même si les options de compression sont identiques. En effet, il est +possible d'améliorer l'encodeur (compression plus rapide ou meilleure) sans +affecter le format du fichier. La sortie peut même varier entre différentes +compilations de la même version d'utilitaire XZ, si des options de +construction différentes sont utilisées. +.PP +Cela signifie qu'une fois que \fB\-\-rsyncable\fP a été implémenté, les fichiers +résultants ne seront pas nécessairement synchronisables avec rsync à moins +que les nouveaux et anciens fichiers n'aient été compressés avec la même +version de xz. Ce problème peut être résolu si une partie de +l'implémentation est gelée pour garantir la stabilité de la sortie rsyncable +à travers les versions de xz. +. +.SS "Décompresseurs .xz embarqués" +Les implémentations de décompresseur embarqué comme XZ Embedded ne gèrent +pas nécessairement les fichiers créés avec d'autres types de \fIvérification\fP +d'intégrité que \fBnone\fP et \fBCRC32\fP. Comme la valeur par défaut est +\fB\-\-check=crc64\fP, vous devez utiliser \fB\-\-check=none\fP ou \fB\-\-check=crc32\fP +lors de la création de fichiers pour les systèmes embarqués. +.PP +En dehors des systèmes embarqués, tous les décompresseurs de format \fB.xz\fP +gèrent tous les types de \fIvérification\fP ou sont au moins capables de +décompresser le fichier sans effectuer la vérification d'intégrité si ce +type de \fIvérification\fP particulière n'est pas pris en charge. +.PP +XZ Embedded prend en charge les filtres BCJ, mais seulement avec le décalage +de départ par défaut. +. +.SH EXEMPLES +. +.SS Bases +Compresser le fichier \fItoto\fP en \fItoto.xz\fP en utilisant le niveau de +compression par défaut (\fB\-6\fP) et supprimer \fItoto\fP si la compression +réussit : +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +Décompresser \fIbidule.xz\fP en \fIbidule\fP et ne pas supprimer \fIbidule.xz\fP même +si la compression réussit : +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +Create \fIbaz.tar.xz\fP with the preset \fB\-4e\fP (\fB\-4 \-\-extreme\fP), which is +slower than the default \fB\-6\fP, but needs less memory for compression and +decompression (48\ MiB and 5\ MiB, respectively): +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +Un mélange de fichiers compressés et non compressés peuvent être +décompressés vers la sortie standard avec une simple commande : +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "Compression en parallèle de plusieurs fichiers" +Sur GNU et *BSD, \fBfind\fP(1) et \fBxargs\fP(1) peuvent être utilisés pour mettre +en parallèle la compression de plusieurs fichiers : +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +L'option \fBP\fP passée à \fBxargs\fP(1) fixe le nombre de processus \fBxz\fP en +parallèles. La meilleure valeur pour l'option \fBn\fP dépend du nombre de +fichiers à compresser. S\-il n'y a que quelques fichiers, la valeur sera +probablement 1 ; avec des dizaines de milliers de fichiers, 100 ou même plus +serait approprié pour réduire le nombre de processus \fBxz\fP que \fBxargs\fP(1) +créera éventuellement. +.PP +L'option \fB\-T1\fP de \fBxz\fP est là pour le forcer en mode mono\-thread, car +\fBxargs\fP(1) est utilisé pour contrôler la quantité de mise en parallèle. +. +.SS "Mode robot" +Calculer combien d'octets ont été économisés au total après avoir compressé +plusieurs fichiers : +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +Un script peut vouloir savoir qu'il utilise une version suffisamment récente +de \fBxz\fP. Le script \fBsh\fP(1) suivant vérifie que le numéro de version de +l'outil \fBxz\fP soit au minimum 5.0.0. Cette méthode est compatible avec les +vieilles versions bêta, qui ne gèrent pas l'option \fB\-\-robot\fP : +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Your xz is too old." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +Régler une limite d'utilisation de la mémoire pour la décompression en +utilisant \fBXZ_OPT\fP, mais si une limite a déjà été définie, ne pas +l'augmenter : +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "Chaînes de filtres de compresseur personnalisées" +L'utilisation la plus simple des chaînes de filtres personnalisées est la +personnalisation d'un préréglage LZMA2. Cela peut être utile, car les +préréglages ne couvrent qu'un sous\-ensemble des réglages de compression +potentiellement utiles. +.PP +Les colonnes CompCPU des tableaux des descriptions des options \fB\-0\fP à \fB\-9\fP +et \fB\-\-extreme\fP sont utiles lors de la personnalisation des préréglages +LZMA2. Voici les parties pertinentes recueillies à partir de ces deux +tableaux : +.RS +.PP +.TS +tab(;); +c c +n n. +Préréglage;CompCPU +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +If you know that a file requires somewhat big dictionary (for example, 32\ MiB) to compress well, but you want to compress it quicker than \fBxz \-8\fP +would do, a preset with a low CompCPU value (for example, 1) can be +modified to use a bigger dictionary: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +Avec certains fichiers, la commande ci\-dessus peut être plus rapide que +\fBxz\-6\fP tout en compressant bien mieux. Cependant, il faut souligner que +seuls certains fichiers bénéficient d'un grand dictionnaire tout en gardant +la valeur de CompCPU faible. La siutation la plus évidente où un gros +dictionnaire peut baucoup aider, est une archive contenant des fichiers très +similaires de quelques megaoctets chacun. La taille de dictionnaire doit +être significativement plus grosse que tout fichier individuel pour +permettre à LZMA2 de tirer pleinement partie des similarités entre des +fichiers consécutifs. +.PP +Si une utilisation de la mémoire élevée pour la compression et décompression +convient, et que le fichier à compresser a une taille de plusieurs centaines +de megaoctets, il peut être utile d'utiliser un plus gros dictionnaire que +celui fourni par \fBxz\-9\fP (64 Mio) : +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +Utiliser \fB\-vv\fP (\fB\-\-verbose\-\-verbose\fP) comme dans l'exemple ci\-dessus peut +être utile pour voir les besoins en mémoire du compresseur et du +décompresseur. Rappelez\-vous qu'utiliser un dictionnaire plus gros que la +taille du fichier non compressé est un gachis de mémoire, donc la commande +ci\-dessus n'est pas utile pour les petits fichiers. +.PP +Sometimes the compression time doesn't matter, but the decompressor memory +usage has to be kept low, for example, to make it possible to decompress the +file on an embedded system. The following command uses \fB\-6e\fP (\fB\-6 \-\-extreme\fP) as a base and sets the dictionary to only 64\ KiB. The +resulting file can be decompressed with XZ Embedded (that's why there is +\fB\-\-check=crc32\fP) using about 100\ KiB of memory. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +If you want to squeeze out as many bytes as possible, adjusting the number +of literal context bits (\fIlc\fP) and number of position bits (\fIpb\fP) can +sometimes help. Adjusting the number of literal position bits (\fIlp\fP) +might help too, but usually \fIlc\fP and \fIpb\fP are more important. For +example, a source code archive contains mostly US\-ASCII text, so something +like the following might give slightly (like 0.1\ %) smaller file than \fBxz \-6e\fP (try also without \fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar\fR +.fi +.RE +.PP +Using another filter together with LZMA2 can improve compression with +certain file types. For example, to compress a x86\-32 or x86\-64 shared +library using the x86 BCJ filter: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +Notez que l'ordre des options de filtre est significatif. Si \fB\-\-x86\fP est +indiqué après \fB\-\-lzma2\fP, \fBxz\fP donnera une erreur, car il ne peut y avoir +aucun filtre après LZMA2, et aussi parce que le filtre BCJ x86 ne peut pas +être utilisé comme dernier filtre dans la chaîne. +.PP +Le filtre Delta associé à LZMA2 peut donner de bons résultats avec les +images bitmap. Cela devrait habituellement battre PNG, qui a quelques +filtres avancés supplémentaires qu'un simple delta, mais qui utilise Deflate +pour la compression effective. +.PP +The image has to be saved in uncompressed format, for example, as +uncompressed TIFF. The distance parameter of the Delta filter is set to +match the number of bytes per pixel in the image. For example, 24\-bit RGB +bitmap needs \fBdist=3\fP, and it is also good to pass \fBpb=0\fP to LZMA2 to +accommodate the three\-byte alignment: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +If multiple images have been put into a single archive (for example, +\&\fB.tar\fP), the Delta filter will work on that too as long as all images have +the same number of bytes per pixel. +. +.SH "VOIR AUSSI" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ Utils: +.br +XZ Embedded: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/fr/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/fr/xzdec.1 new file mode 100644 index 000000000..cd31d6c9f --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/fr/xzdec.1 @@ -0,0 +1,90 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" french translation of XZ Utils man +.\" Copyright (C) 2021 Debian French l10n team +.\" Translator +.\" bubu , 2021. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 2024\-04\-08 Tukaani "Utilitaires XZ" +.SH NOM +xzdec, lzmadec \- Small .xz et .lzma decompresseurs +.SH SYNOPSIS +\fBxzdec\fP [\fIoption...\fP] [\fIfichier...\fP] +.br +\fBlzmadec\fP [\fIoption...\fP] [\fIfichier...\fP] +.SH DESCRIPTION +\fBxzdec\fP est un outil uniquement de décompression, basé sur liblzma pour les +fichiers \fB.xz\fP (et seulement \fB.xz\fP). \fBxzdec\fP est destiné à remplacer +\fBxz\fP(1) dans les situations les plus courantes où un script a été écrit +pour utiliser \fBxz \-\-decompress \-\-stdout\fP (et possiblement quelques autres +options courantes) pour décompresser des fichiers \fB.xz\fP. \fBlzmadec\fP est +identique à \fBxzdec\fP, sauf que \fBlzmadec\fP prend en charge les fichiers +\&\fB.lzma\fP au lieu des fichiers \fB.xz\fP. +.PP +Pour réduire la taille de l'exécutable, \fBxzdec\fP ne prend en charge ni le +multithreading ni la localisation et ne lit pas les options des variables +d'environnement \fBXZ_DEFAULTS\fP et \fBXZ_OPT\fP. \fBxzdec\fP ne gère pas +l'affichage d'information sur la progression du traitement : envoyer +\fBSIGINFO\fP à \fBxzdec\fP ne fait rien, mais envoyer \fBSIGUSR1\fP termine le +processus au lieu d'afficher de l'information sur la progression. +.SH OPTIONS +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +Ignoré pour la compatibilité avec \fBxz\fP(1), \fBxzdec\fP ne gère que la +décompression. +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ignoré pour la compatibilité avec \fBxz\fP(1), \fBxzdec\fP ne crée ni ne supprime +jamais aucun fichier. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Ignoré pour la compatibilité avec \fBxz\fP(1), \fBxzdec\fP écrit toujours les +données décompressées sur la sortie standard. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Spécifier cela une fois ne fait rien, car \fBxzdec\fP n'affiche jamais aucun +avertissement ou notification. Spécifier cela deux fois pour supprimer les +erreurs. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Ignoré pour la compatibilité avec \fBxz\fP(1), \fBxzdec\fP n'utilise jamais le +satut de sortie 2. +.TP +\fB\-h\fP, \fB\-\-help\fP +Afficher un message d'aide et quitter. +.TP +\fB\-V\fP, \fB\-\-version\fP +Afficher le numéro de version de \fBxzdec\fP et liblzma. +.SH "STATUT DE SORTIE" +.TP +\fB0\fP +Tout s'est bien passé. +.TP +\fB1\fP +Une erreur est survenue. +.PP +A la différence de \fBxz\fP(1),\fBxzdec\fP n'a pas de messages d'avertissement, et +donc le statut de sortie 2 n'est pas utilisé par \fBxzdec\fP. +.SH NOTES +Utilisez \fBxz\fP(1) au lieu de \fBxzdec\fP ou \fBlzmadec\fP pour un usage normal de +tous les jours. \fBxzdec\fP ou \fBlzmadec\fP ne sont utiles que pour les +situations où il est important d'avoir un plus petit décompresseur que le +\fBxz\fP(1) complet. +.PP +\fBxzdec\fP et \fBlzmadec\fP ne sont en fait pas vraiment si petits. La taille +peut être encore réduite en abandonnant des fonctionnalités de liblzma au +moment de la compilation, mais cela ne devrait pas être fait pour des +exécutables distribués sur des systèmes d'exploitation classique non +embarqués. Si vous avez besoin d'un décompresseur vraiment petit, pensez à +utiliser XZ Embedded. +.SH "VOIR AUSSI" +\fBxz\fP(1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/fr/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/fr/xzless.1 new file mode 100644 index 000000000..797382bd5 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/fr/xzless.1 @@ -0,0 +1,49 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" french translation of XZ Utils man +.\" Copyright (C) 2021 Debian French l10n team +.\" Translator +.\" bubu , 2021. +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 2025\-03\-06 Tukaani "Utilitaires XZ" +.SH NOM +xzless, lzless \- Voir le contenu des fichiers (texte) compressés xz ou lzma +.SH SYNOPSIS +\fBxzless\fP [\fIfichier\fP...] +.br +\fBlzless\fP [\fIfile\fP...] (DEPRECATED) +.SH DESCRIPTION +\fBxzless\fP is a filter that displays text from compressed files to a +terminal. Files supported by \fBxz\fP(1) are decompressed; other files are +assumed to be in uncompressed form already. If no \fIfiles\fP are given, +\fBxzless\fP reads from standard input. +.PP +\fBxzless\fP utilise \fBless\fP(1) pour afficher sa sortie. Contrairement à +\fBxzmore\fP, son choix d'afficheur ne peut pas être modifié en indiquant une +variable d'environnement. Les commandes sont basées sur \fBmore\fP(1) et +\fBvi\fP(1) et permettent des déplacements en avant et en arrière et des +recherches. Voir le manuel de \fBless\fP(1) pour plus d'information. +.PP +The command named \fBlzless\fP is provided for backward compatibility with LZMA +Utils. It is deprecated and will be removed in a future version. +.SH ENVIRONNEMENT +.TP +\fBLESSMETACHARS\fP +Une liste de caractères spéciaux pour l'interpréteur. Définis par \fBxzless\fP +à moins qu'ils ne l'aient déjà été dans l'environnement. +.TP +\fBLESSOPEN\fP +Définir en ligne de commande le décompresseur \fBxz\fP(1) à invoquer pour +préparer les fichiers en entrée pour \fBless\fP(1). +.SH "VOIR AUSSI" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/it/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/it/lzmainfo.1 new file mode 100644 index 000000000..dadc8a848 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/it/lzmainfo.1 @@ -0,0 +1,45 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Italian translations for xz-man package +.\" Luca Vercelli , 2024-2025 +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 30/06/2013 Tukaani "XZ Utils" +.SH NOME +lzmainfo \- mostra le informazioni nell'intestazione di file .lzma +.SH SINOSSI +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fIFILE...\fP] +.SH DESCRIZIONE +\fBlzmainfo\fP mostra le informazioni contenute nell'intestazione del file +\&\fB.lzma\fP. Legge i primi 13 byte del \fIFILE\fP specificato, decodifica +l'intestazione, e la stampa su standard output in formato leggibile +dall'uomo. Se nessun \fIFILE\fP è specificato o se \fIFILE\fP è \fB\-\fP, viene letto +lo standard input. +.PP +Di solito le informazioni più interessanti sono la dimensione non compressa +e la dimensione del dizionario. Le dimensioni non compresse possono essere +visualizzate solo se il file è nella variante di formato \fB.lzma\fP "senza +flussi". La quantità di memoria necessaria per decomprimere il file è di +alcune dozzine di kilobyte più la dimensione del dizionario. +.PP +\fBlzmainfo\fP è incluso nelle XZ Utils principalmente per retrocompatibilità +con le LZMA Utils. +.SH "CODICE DI USCITA" +.TP +\fB0\fP +Tutto bene. +.TP +\fB1\fP +È avvenuto un errore. +.SH BUG +\fBlzmainfo\fP usa \fBMB\fP mentre il suffisso corretto dovrebbe essere \fBMiB\fP +(2^20 byte). Questo serve per rendere l'output compatibile con quello delle +LZMA Utils. +.SH "VEDERE ANCHE" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/it/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/it/xz.1 new file mode 100644 index 000000000..53a915947 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/it/xz.1 @@ -0,0 +1,2080 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Italian translations for xz-man package +.\" Luca Vercelli , 2024-2025 +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 08/03/2025 Tukaani "XZ Utils" +. +.SH NOME +xz, unxz, xzcat, lzma, unlzma, lzcat \- Comprime o decomprime file .xz e +\&.lzma +. +.SH SINOSSI +\fBxz\fP [\fIOPZIONE...\fP] [\fIFILE...\fP] +. +.SH "ALIAS DEI COMANDI" +\fBunxz\fP è equivalente a \fBxz \-\-decompress\fP. +.br +\fBxzcat\fP è equivalente a \fBxz \-\-decompress \-\-stdout\fP. +.br +\fBlzma\fP è equivalente a \fBxz \-\-format=lzma\fP. +.br +\fBunlzma\fP è equivalente a \fBxz \-\-format=lzma \-\-decompress\fP. +.br +\fBlzcat\fP è equivalente a \fBxz \-\-format=lzma \-\-decompress \-\-stdout\fP. +.PP +Quando si scrivono script che richiedono di decomprimere file, si raccomanda +di utilizzare sempre il comando \fBxz\fP con argomenti appropriati (\fBxz \-d\fP o +\fBxz \-dc\fP) al posto degli alias \fBunxz\fP e \fBxzcat\fP. +. +.SH DESCRIZIONE +\fBxz\fP è uno strumento di compressione dati generico con sintassi della riga +di comando simile a \fBgzip\fP(1) e \fBbzip2\fP(1). Il formato file nativo è +\&\fB.xz\fP, ma sono supportati anche il formato tradizionale \fB.lzma\fP usato +dalle LZMA Utils e i flussi grezzi (raw) compressi senza intestazioni di +formato contenitore. In più, è supportata la decompressione del formato +\&\fB.lz\fPusato da \fBlzip\fP. +.PP +\fBxz\fP comprime o decomprime ogni \fIFILE\fP a seconda della modalità di +funzionamento selezionata. Se nessun \fIFILE\fP è indicato o se \fIFILE\fP è \fB\-\fP, +\fBxz\fP legge dallo standard input e scrive i dati processati sullo standard +output. \fBxz\fP si rifiuterà (stamperà un errore e salterà il \fIFILE\fP) di +scrivere dati compressi sullo standard output se è il +terminale. Analogamente, \fBxz\fP si rifiuterà di leggere dati compressi dallo +standard input se è il terminale. +.PP +A meno che non sia specificato \fB\-\-stdout\fP, i \fIFILE\fP diversi da \fB\-\fP +vengono scritti in un nuovo file il cui nome deriva dal nome del \fIFILE\fP +sorgente: +.IP \(bu 3 +Quando si comprime, il suffisso del file destinazione (\fB.xz\fP or \fB.lzma\fP) +viene accodato al nome del file sorgente per ottenere il nome del file +destinazione. +.IP \(bu 3 +Quando si decomprime, i suffissi \fB.xz\fP, \fB.lzma\fP, o \fB.lz\fP vengono rimossi +dal nome del file per ottenere il nome del file destinazione. \fBxz\fP +riconosce anche i suffissi \fB.txz\fP e \fB.tlz\fP, e li sostituisce con il +suffisso \fB.tar\fP. +.PP +Se il file di destinazione esiste già, viene visualizzato un errore e +\fIFILE\fP viene saltato. +.PP +A meno che non si scriva nello standard output, \fBxz\fP visualizzerà un +avvertimento e salterà il \fIFILE\fP se si verifica una delle seguenti +condizioni: +.IP \(bu 3 +\fIFILE\fP non è un file regolare. I collegamenti simbolici non vengono +seguiti, quindi non sono considerati file regolari. +.IP \(bu 3 +\fIFILE\fP ha più di un collegamento "hard". +.IP \(bu 3 +\fIFILE\fP ha impostati i bit setuid, setgid, o sticky. +.IP \(bu 3 +La modalità di funzionamento è impostata sulla compressione e il \fIFILE\fP ha +già un suffisso del formato di file di destinazione (\fB.xz\fP o \fB.txz\fP quando +si comprime nel formato \fB.xz\fP e \fB.lzma\fP o \fB.tlz\fP quando si comprime nel +formato \fB.lzma\fP). +.IP \(bu 3 +La modalità di funzionamento è impostata sulla decompressione e il \fIFILE\fP +non ha un suffisso di nessuno dei formati di file supportati (\fB.xz\fP, +\&\fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP, o \fB.lz\fP). +.PP +Dopo aver compresso o decompresso correttamente il \fIFILE\fP, \fBxz\fP copia il +proprietario, il gruppo, le autorizzazioni, l'ora di accesso e l'ora di +modifica dal \fIFILE\fP di origine al file di destinazione. Se la copia del +gruppo fallisce, le autorizzazioni vengono modificate in modo che il file di +destinazione non diventi accessibile agli utenti che non disponevano +dell'autorizzazione per accedere al \fIFILE\fP di origine. \fBxz\fP non supporta +ancora la copia di altri metadati, ad esempio elenchi di controllo degli +accessi o attributi estesi. +.PP +Una volta che il file di destinazione è stato chiuso con successo, il +\fIFILE\fP sorgente viene rimosso, a meno che sia stato specificato +\fB\-\-keep\fP. Il \fIFILE\fP sorgente non viene mai rimosso se l'output è scritto +sullo standard output, né se si verifica un errore. +.PP +L'invio di \fBSIGINFO\fP o \fBSIGUSR1\fP al processo \fBxz\fP comporta la stampa +delle informazioni sullo stato di avanzamento sullo standard error. Questo +ha solo un uso limitato poiché quando lo standard error è un terminale, +utilizzando \fB\-\-verbose\fP verrà visualizzato un indicatore di avanzamento che +si aggiorna automaticamente. +. +.SS "Utilizzo memoria" +L'utilizzo della memoria di \fBxz\fP varia da poche centinaia di kilobyte a +diversi gigabyte a seconda delle impostazioni di compressione. Le +impostazioni utilizzate durante la compressione di un file determinano i +requisiti di memoria del decompressore. In genere il decompressore richiede +dal 5\% al 20\% della quantità di memoria necessaria al compressore durante +la creazione del file. Ad esempio, la decompressione di un file creato con +\fBxz \-9\fP al momento richiede 65\ MiB di memoria. Ancora, è possibile avere +file \fB.xz\fP che richiedono diversi gigabyte di memoria per la +decompressione. +.PP +Soprattutto gli utenti di sistemi più vecchi possono trovare fastidiosa +l'eventualità di un utilizzo molto elevato di memoria. Per evitare +spiacevoli sorprese, \fBxz\fP dispone di un limitatore di utilizzo della +memoria incorporato, che è disabilitato per impostazione predefinita. Anche +se alcuni sistemi operativi forniscono modi per limitare l'utilizzo della +memoria dei processi, fare affidamento su questi non è stato ritenuto +sufficientemente flessibile (ad esempio, l'uso di \fBulimit\fP(1) per limitare +la memoria virtuale tende a paralizzare \fBmmap\fP(2)). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +Il limitatore di utilizzo della memoria può essere abilitato con l'opzione +della riga di comando \fB\-\-memlimit=\fP\fILIMITE\fP. Spesso è più conveniente +abilitare il limitatore per impostazione predefinita impostando la variabile +d'ambiente \fBXZ_DEFAULTS\fP, ad esempio, \fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP. È +possibile impostare separatamente i limiti per la compressione e la +decompressione utilizzando \fB\-\-memlimit\-compress=\fP\fILIMITE\fP and +\fB\-\-memlimit\-decompress=\fP\fILIMITE\fP. L'uso di queste due opzioni al di fuori +di \fBXZ_DEFAULTS\fP è raramente utile perché una singola esecuzione di \fBxz\fP +non può eseguire sia la compressione che la decompressione e +\fB\-\-memlimit=\fP\fILIMITE\fP (or \fB\-M\fP \fILIMITE\fP) è più breve da digitare sulla +riga di comando. +.PP +Se il limite di utilizzo della memoria specificato viene superato durante la +decompressione, \fBxz\fP visualizzerà un errore e la decompressione del file +fallirà. Se il limite viene superato durante la compressione, \fBxz\fP tenterà +di ridimensionare le impostazioni in modo che il limite non venga più +superato (tranne quando si usa \fB\-\-format=raw\fP o \fB\-\-no\-adjust\fP). In questo +modo l'operazione non fallirà a meno che il limite sia molto basso. Il +ridimensionamento delle impostazioni viene eseguito in piccole differenze +che non corrispondono ai livelli di compressione preimpostati, ad esempio, +se il limite è solo leggermente inferiore alla quantità richiesta per \fBxz \-9\fP, le impostazioni saranno ridimensionate solo un poco, non proprio fino a +\fBxz \-8\fP. +. +.SS "Concatenazione e padding con file .xz" +È possibile concatenare i file \fB.xz\fP così come sono. \fBxz\fP decomprimerà +tali file come se fossero un singolo file \fB.xz\fP. +.PP +È possibile inserire un padding tra le parti concatenate o dopo l'ultima +parte. Il padding deve essere costituito da byte "null" e la dimensione del +padding deve essere un multiplo di quattro byte. Questo può essere utile, ad +esempio, se il file \fB.xz\fP è memorizzato su un supporto che misura le +dimensioni dei file in blocchi di 512 byte. +.PP +Concatenazione e padding non sono permessi con file \fB.lzma\fP o con flussi +grezzi. +. +.SH OPZIONI +. +.SS "Suffissi interi e valori speciali" +Nella maggior parte dei casi in cui è previsto un argomento intero, è +supportato un suffisso facoltativo per indicare facilmente numeri interi di +grandi dimensioni. Non deve esserci alcuno spazio tra il numero intero e il +suffisso. +.TP +\fBKiB\fP +Moltiplica l'intero per 1024 (2^10). \fBKi\fP, \fBk\fP, \fBkB\fP, \fBK\fP, e \fBKB\fP +sono accettati come sinonimi di \fBKiB\fP. +.TP +\fBMiB\fP +Moltiplica l'intero per 1.048.576 (2^20). \fBMi\fP, \fBm\fP, \fBM\fP, e \fBMB\fP sono +accettati come sinonimi di \fBMiB\fP. +.TP +\fBGiB\fP +Moltiplica l'intero per 1.073.741.824 (2^30). \fBGi\fP, \fBg\fP, \fBG\fP, e \fBGB\fP +sono accettati come sinonimi di \fBGiB\fP. +.PP +Il valore speciale \fBmax\fP può essere utilizzato per indicare il valore +intero massimo supportato dall'opzione. +. +.SS "Modalità operativa" +Se vengono fornite più opzioni di modalità operativa, l'ultima ha effetto. +.TP +\fB\-z\fP, \fB\-\-compress\fP +Compressione. Questa è la modalità operativa predefinita quando non viene +specificata alcuna opzione della modalità operativa e non è determinata +nessun'altra modalità operativa dal nome del comando (ad esempio, \fBunxz\fP +implica \fB\-\-decompress\fP). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Dopo che la compressione è terminata con successo, il file origine viene +rimosso a meno che si stia scrivendo su standard output o che venga +specificato \fB\-\-keep\fP. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Decompressione. Dopo che la decompressione è terminata con successo, il file +origine viene rimosso a meno che si stia scrivendo su standard output o che +venga specificato \fB\-\-keep\fP. +.TP +\fB\-t\fP, \fB\-\-test\fP +Testa l'integrità dei \fIFILE\fP compressi. Questa opzione è equivalente a +\fB\-\-decompress \-\-stdout\fP tranne per il fatto che i dati decompressi vengono +scartati invece di essere scritti nello standard output. Nessun file viene +creato o rimosso. +.TP +\fB\-l\fP, \fB\-\-list\fP +Stampa le informazioni sul \fIFILE\fP compresso. Non viene prodotto alcun +output non compresso e non viene creato o rimosso alcun file. In modalità +elenco, il programma non è in grado di leggere i dati compressi dallo +standard input o da altre fonti che non permettano la ricerca. +.IP "" +Il tracciato predefinito mostra le informazioni di base sui \fIFILE\fP, un file +per riga. Per ottenere informazioni più dettagliate, usare anche l'opzione +\fB\-\-verbose\fP. Per avere ancora più informazioni, usare \fB\-\-verbose\fP due +volte, ma si noti che questo può essere lento, perché ottenere tutte le +informazioni extra richiede molte estrazioni. La larghezza dell'output +dettagliato supera gli 80 caratteri, quindi il reindirizzamento dell'output, +ad esempio, a \fBless\ \-S\fP può essere utile se il terminale non è +sufficientemente ampio. +.IP "" +L'output esatto può variare tra le versioni di \fBxz\fP e le diverse +impostazioni locali. Per un output leggibile dalla macchina si dovrebbe +utilizzare \fB\-\-robot \-\-list\fP. +. +.SS "Modificatori dell'operazione" +.TP +\fB\-k\fP, \fB\-\-keep\fP +Non elimina i file input. +.IP "" +A partire da \fBxz\fP 5.2.6, questa opzione fa sì che \fBxz\fP comprima o +decomprima anche se l'input è un collegamento simbolico a un file regolare, +ha più di un collegamento fisico o ha il bit setuid, setgid o sticky +impostato. I bit setuid, setgid e sticky non vengono copiati nel file di +destinazione. Nelle versioni precedenti questo veniva fatto solo con +\fB\-\-force\fP. +.TP +\fB\-f\fP, \fB\-\-force\fP +Questa opzione ha diverse conseguenze: +.RS +.IP \(bu 3 +Se il file di destinazione esiste già, lo elimina prima di comprimere o +decomprimere. +.IP \(bu 3 +Comprime o decomprime anche se l'input è un collegamento simbolico a un file +regolare, ha più di un collegamento "hard", o ha il bit setuid, setgid o +sticky impostato. I bit setuid, setgid e sticky non sono copiati sul file +destinazione. +.IP \(bu 3 +Quando usato con \fB\-\-decompress\fP \fB\-\-stdout\fP e \fBxz\fP non riesce a +riconoscere il tipo di file sorgente, copia il file sorgente così com'è +sullo standard output. Questo permette a \fBxzcat\fP \fB\-\-force\fP di essere usato +come \fBcat\fP(1) per file che non siano stati compressi con \fBxz\fP. Si noti che +in futuro \fBxz\fP potrebbe supportare nuovi formati di file compressi, il che +potrebbe portare \fBxz\fP a decomprimere più tipi di file anziché copiarli come +sono sullo standard output. \fB\-\-format=\fP\fIFORMATO\fP può essere usato per +forzare \fBxz\fP a decomprimere solo un singolo formato di file. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Scrive i dati compressi o decompressi nello standard output anziché in un +file. Implica \fB\-\-keep\fP. +.TP +\fB\-\-single\-stream\fP +Decomprime solo il primo flusso \fB.xz\fP, e ignora automaticamente i possibili +dati di input rimanenti che seguono il flusso. Normalmente questi dati +sporchi finali portano \fBxz\fP a visualizzare un errore. +.IP "" +\fBxz\fP non decomprime mai più di un flusso dai file \fB.lzma\fP o dai flussi +grezzi, ma questa opzione fa comunque in modo che \fBxz\fP ignori i possibili +dati finali dopo il file \fB.lzma\fP o il flusso grezzo. +.IP "" +Questa opzione non ha effetto se la modalità operativa non è \fB\-\-decompress\fP +o \fB\-\-test\fP. +.IP "" +Dalla versione \fBxz\fP 5.7.1alpha, \fB\-\-single\-stream\fP implica \fB\-\-keep\fP. +.TP +\fB\-\-no\-sparse\fP +Disabilita la creazione di file sparsi. Per impostazione predefinita, se si +esegue la decompressione in un file regolare, \fBxz\fP tenta di rendere il file +sparso se i dati decompressi contengono lunghe sequenze di zeri +binari. Funziona anche quando si scrive su standard output, purché lo +standard output sia collegato a un file regolare e siano soddisfatte alcune +condizioni aggiuntive per renderlo sicuro. La creazione di file sparsi può +risparmiare spazio su disco e velocizzare la decompressione riducendo la +quantità di I/O su disco. +.TP +\fB\-S\fP \fI.SUFFISSO\fP, \fB\-\-suffix=\fP\fI.SUFFISSO\fP +Durante la compressione, utilizzare \fI.suf\fP come suffisso per il file di +destinazione anziché \fB.xz\fP o \fB.lzma\fP. Se non si scrive nello standard +output e il file di origine ha già il suffisso \fI.suf\fP, viene visualizzato +un avvertimento e il file viene ignorato. +.IP "" +Quando si decomprime, accetta i file con suffisso \fI.suf\fP in aggiunta a +quelli con suffisso \fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP, o \fB.lz\fP. Se il file +sorgente ha suffisso \fI.suf\fP, il suffisso viene rimosso per ottenere il nome +del file destinazione. +.IP "" +Quando si comprimono o decomprimono flussi grezzi (\fB\-\-format=raw\fP), il +suffisso deve sempre essere specificato, a meno che si scriva sullo standard +output, perché non esiste un suffisso predefinito per i flussi grezzi. +.TP +\fB\-\-files\fP[\fB=\fP\fIFILE\fP] +Legge i nomi dei file da processare da \fIFILE\fP; se \fIFILE\fP è omesso, i nomi +dei file vengono letti dallo standard input. I nomi dei file devono essere +terminati da un carattere "a capo". Un trattino (\fB\-\fP) è considerato come un +nome di file regolare; non indica lo standard input. Se vengono forniti +anche dei nomi di file come argomenti della riga di comando, questi sono +processati prima di quelli letti da \fIFILE\fP. +.TP +\fB\-\-files0\fP[\fB=\fP\fIFILE\fP] +Questo è identico a \fB\-\-files\fP[\fB=\fP\fIFILE\fP] tranne per il fatto che ogni +nome di file deve terminare con il carattere null. +. +.SS "Formato file di base e opzioni di compressione" +.TP +\fB\-F\fP \fIFORMATO\fP, \fB\-\-format=\fP\fIFORMATO\fP +Specifica il \fIFORMATO\fP del file da comprimere o decomprimere: +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +Questa è l'impostazione predefinita. Quando si comprime, \fBauto\fP è +equivalente a \fBxz\fP. Quando si decomprime, il formato del file input viene +rilevato automaticamente. Si noti che per i flussi grezzi (creati con +\fB\-\-format=raw\fP) non è possibile il rilevamento automatico. +.TP +\fBxz\fP +Comprime nel formato di file \fB.xz\fP, oppure accetta solo file \fB.xz\fP durante +la decompressione. +.TP +\fBlzma\fP, \fBalone\fP +Comprime nel formato tradizionale \fB.lzma\fP, oppure accetta solo file +\&\fB.lzma\fP per la decompressione. Il nome alternativo \fBalone\fP è fornito per +retrocompatibilità con le LZMA Utils. +.TP +\fBlzip\fP +Accetta solo file \fB.lz\fP per la decompressione. La compressione non è +supportata. +.IP "" +Sono supportate le versioni 0 e 1 del formato \fB.lz\fP. I file in versione 0 +sono stati prodotti da \fBlzip\fP 1.3 e precedenti. Questi file non sono +comuni, ma possono essere trovati negli archivi di file, perché alcuni +pacchetti sorgente erano stati rilasciati in questo formato. Qualcuno +potrebbe anche avere vecchi file personali in questo formato. Il supporto +alla decompressione per la versione di formato 0 è stato rimosso in \fBlzip\fP +1.18. \fBlzip\fP 1.4 e successivi creano i file nella versione di formato 1. +.TP +\fBraw\fP +Comprime o decomprime un flusso grezzo (senza intestazione). Questo è inteso +solamente per utenti avanzati. Per decodificare flussi grezzi, occorre usare +\fB\-\-format=raw\fP e specificare esplicitamente la catena dei filtri, che +normalmente sarebbero conservati nell'intestazione. +.RE +.TP +\fB\-C\fP \fICONTROLLO\fP, \fB\-\-check=\fP\fICONTROLLO\fP +Specifica il tipo di controllo di integrità. Il controllo viene calcolato +dai dati non compressi e memorizzato nel file \fB.xz\fP. Questa opzione ha +effetto solo quando si comprime nel formato \fB.xz\fP; il formato \fB.lzma\fP non +supporta i controlli di integrità. Il controllo di integrità (se presente) +viene verificato quando il file \fB.xz\fP viene decompresso. +.IP "" +Tipi di \fICONTROLLI\fP supportati: +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +Non calcola proprio il controllo di integrità. Questo in genere è una +pessima idea. Può essere utile quando l'integrità dei dati viene comunque +verificata con altri mezzi. +.TP +\fBcrc32\fP +Calcola la firma CRC32 usando il polinomio di IEEE\-802.3 (Ethernet). +.TP +\fBcrc64\fP +Calcola la firma CRC64 usando il polinomio di ECMA\-182. Questa è +l'impostazione predefinita, perché è leggermente migliore della CRC32 nel +rilevare i file danneggiati e la differenza di velocità è trascurabile. +.TP +\fBsha256\fP +Calcola la firma SHA\-256. Questo è un po' più lento che CRC32 e CRC64. +.RE +.IP "" +L'integrità delle intestazioni \fB.xz\fP viene sempre verificata con CRC32. Non +è possibile modificarlo o disabilitarlo. +.TP +\fB\-\-ignore\-check\fP +Non verifica il controllo di integrità dei dati compressi durante la +decompressione. Il valore CRC3 nelle intestazioni \fB.xz\fP sarà ancora +verificata normalmente. +.IP "" +\fBNon usare questa opzione se non si è consci di cosa si sta facendo.\fP +Possibili ragioni per utilizzare questa opzione: +.RS +.IP \(bu 3 +Tentativo di recupero dei dati da un file .xz corrotto. +.IP \(bu 3 +Accelerazione della decompressione. Questo è importante soprattutto con +SHA\-256 o con i file che sono stati compressi molto bene. Si consiglia di +non utilizzare questa opzione per questo scopo, a meno che l'integrità del +file non venga verificata esternamente in altro modo. +.RE +.TP +\fB\-0\fP ... \fB\-9\fP +Selezionare un livello di compressione preimpostato. Il valore predefinito è +\fB\-6\fP. Se vengono specificati più livelli preimpostati, l'ultimo ha +effetto. Se è già stata specificata una catena di filtri personalizzata, +l'impostazione di un livelli preimpostati cancella la catena di filtri +personalizzata. +.IP "" +Le differenze tra i livelli preimpostati sono più significative rispetto a +\fBgzip\fP(1) e \fBbzip2\fP(1). Le impostazioni di compressione selezionate +determinano i requisiti di memoria del decompressore, quindi l'utilizzo di +un livello preimpostato troppo alto potrebbe rendere difficile la +decompressione del file su un vecchio sistema con poca RAM. Specificamente, +\fBnon è una buona idea utilizzare ciecamente \-9 per tutto\fP come spesso +accade per \fBgzip\fP(1) e \fBbzip2\fP(1). +.RS +.TP +\fB\-0\fP ... \fB\-3\fP +Questi sono livelli preimpostati piuttosto veloci. \fB\-0\-\fP a volte è più +veloce di \fBgzip \-9\fP e comprime molto meglio. Quelli più alti hanno spesso +una velocità paragonabile a \fBbzip2\fP(1) con un rapporto di compressione +comparabile o migliore, anche se i risultati dipendono molto dal tipo di +dati che vengono compressi. +.TP +\fB\-4\fP ... \fB\-6\fP +Compressione da buona a molto buona, mantenendo l'utilizzo della memoria del +decompressore ragionevole anche per vecchi sistemi. \fB\-6\fP è il valore +predefinito, che di solito è una buona scelta per distribuire file che +debbano essere decompressi anche su sistemi con solo 16\ MiB di +RAM. (Potrebbe valere la pena di considerare anche \fB\-5e\fP o \fB\-6e\fP. Si veda +\fB\-\-extreme\fP.) +.TP +\fB\-7 ... \-9\fP +Questi sono come \fB\-6\fP ma con requisiti di memoria di compressore e +decompressore più elevati. Sono utili solo quando si comprimono file di +dimensioni superiori a 8\ MiB, 16\ MiB e 32\ MiB, rispettivamente. +.RE +.IP "" +A parità di hardware, la velocità di decompressione è approssimativamente un +numero costante di byte di dati compressi al secondo. In altre parole, +migliore è la compressione, più veloce sarà di solito la decompressione. Ciò +significa anche che la quantità di output non compresso prodotta al secondo +può variare notevolmente. +.IP "" +La tabella seguente riassume le caratteristiche dei livelli preimpostati: +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Livello preimpostato;DictSize;CompCPU;CompMem;DecMem +\-0;256 KiB;0;3 MiB;1 MiB +\-1;1 MiB;1;9 MiB;2 MiB +\-2;2 MiB;2;17 MiB;3 MiB +\-3;4 MiB;3;32 MiB;5 MiB +\-4;4 MiB;4;48 MiB;5 MiB +\-5;8 MiB;5;94 MiB;9 MiB +\-6;8 MiB;6;94 MiB;9 MiB +\-7;16 MiB;6;186 MiB;17 MiB +\-8;32 MiB;6;370 MiB;33 MiB +\-9;64 MiB;6;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Descrizioni delle colonne: +.RS +.IP \(bu 3 +DictSize è la dimensione del dizionario LZMA2. È uno spreco di memoria usare +un dizionario più grande della dimensione del file non compresso. Ecco +perché è una buona cosa evitare di usare i livelli preimpostati \fB\-7\fP +\&... \fB\-9\fP quando non c'è reale necessità. Con \fB\-6\fP e inferiori, la quantità +di memoria sprecata in genere è sufficientemente bassa da essere +trascurabile. +.IP \(bu 3 +CompCPU è una rappresentazione semplificata delle impostazioni di LZMA2 che +influenzano la velocità di compressione. Anche la dimensione del dizionario +influenza la velocità, quindi mentre CompCPU è lo stesso per i livelli \fB\-6\fP +\&... \fB\-9\fP, i livelli più alti tendono ancora ad essere un po' più lenti. Per +avere una compressione ancora più lenta e quindi potenzialmente migliore, +utilizzare \fB\-\-extreme\fP. +.IP \(bu 3 +CompMem contiene i requisiti di memoria del compressore in modalità a +singola thread. Può variare leggermente tra le versioni di \fBxz\fP. +.IP \(bu 3 +DecMem contiene i requisiti di memoria del decompressore. In altre parole, +le impostazioni di compressione determinano i requisiti di memoria del +decompressore. L'utilizzo esatto della memoria del decompressore è +leggermente superiore alla dimensione del dizionario LZMA2, ma i valori +nella tabella sono stati arrotondati per eccesso al successivo MiB completo. +.RE +.IP "" +I requisiti di memoria per la modalità a thread multiple sono +significativamente più alti che per la modalità thread singola. Con il +valore predefinito di \fB\-\-block\-size\fP, ogni thread richiede 3*3*dimensione +del dizionario più CompMem oppure DecMem. Ad esempio, 4 thread con il +livello preimpostato \fB\-6\fP hanno bisogno di 660\(en670\ MiB di memoria. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +Utilizzare una variante più lenta del livello preimpostato selezionato +(\fB\-0\fP ... \fB\-9\fP) nella speranza di ottenere un rapporto di compressione +leggermente migliore, ma con un po' di sfortuna questo potrebbe anche +renderlo peggiore. L'utilizzo della memoria del decompressore non è +influenzato, ma l'utilizzo della memoria del compressore aumenta leggermente +ai livelli preimpostati \fB\-0\fP ... \fB\-3\fP. +.IP "" +Dal momento che ci sono due livelli preimpostati con dimensione del +dizionario di 4\ MiB e 8\ MiB, i livelli preimpostati \fB\-3e\fP e \fB\-5e\fP usano +impostazioni leggermente più veloci (minore CompCPU) di \fB\-4e\fP e \fB\-6e\fP, +rispettivamente. In questo modo non ci sono due livelli preimpostati +identici. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Livello preimpostato;DictSize;CompCPU;CompMem;DecMem +\-0e;256 KiB;8;4 MiB;1 MiB +\-1e;1 MiB;8;13 MiB;2 MiB +\-2e;2 MiB;8;25 MiB;3 MiB +\-3e;4 MiB;7;48 MiB;5 MiB +\-4e;4 MiB;8;48 MiB;5 MiB +\-5e;8 MiB;7;94 MiB;9 MiB +\-6e;8 MiB;8;94 MiB;9 MiB +\-7e;16 MiB;8;186 MiB;17 MiB +\-8e;32 MiB;8;370 MiB;33 MiB +\-9e;64 MiB;8;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Ad esempio, ci sono un totale di quattro livelli preimpostati che utilizzano +un dizionario da 8\ MiB, il cui ordine dal più veloce al più lento è \fB\-5\fP, +\fB\-6\fP, \fB\-5e\fP, e \fB\-6e\fP. +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +Questi sono alias in qualche modo fuorvianti per \fB\-0\fP e \fB\-9\fP, +rispettivamente. Sono forniti solo per retrocompatibilità con le LZMA +Utils. Evitare di utilizzare queste opzioni. +.TP +\fB\-\-block\-size=\fP\fIDIMENSIONE\fP +Quando si comprime in formato \fB.xz\fP, divide i dati input in blocchi da +\fIDIMENSIONE\fP byte. I blocchi vengo compressi indipendentemente l'uno +dall'altro, cosa che aiuta con le thread multiple e rende possibile la +decompressione con accessi casuali limitati. Questa opzione viene usata +tipicamente per sovrascrivere la dimensione predefinita dei blocchi in +modalità a thread multiple, ma può essere utilizzata anche in modalità +thread singola. +.IP "" +In modalità a thread multiple verranno allocati circa il triplo di +\fIDIMENSIONE\fP di byte in ogni thread per il buffering dell'input e +dell'output. La \fIDIMENSIONE\fP predefinita è tre volte la dimensione del +dizionario LZMA2 e comunque almeno 1 MiB. Tipicamente un buon valore è +2\(en4 volte la dimensione del dizionario LZMA2 oppure almeno 1 MiB. Usare +una \fIDIMENSIONE\fP inferiore della dimensione del dizionario LZMA2 causa uno +spreco di RAM, in quanto il buffer del dizionario LZMA2 non verrà mai +riempito completamente. In modalità a thread multiple, la dimensione dei +blocchi è conservata nelle intestazioni dei blocchi. L'informazione sulla +dimensione è richiesta per la decompressione a thread multiple. +.IP "" +Nella modalità a thread singola, per impostazione predefinita non viene +eseguita alcuna suddivisione in blocchi. L'impostazione di questa opzione +non influisce sull'utilizzo della memoria. Nessuna informazione sulle +dimensioni viene memorizzata nelle intestazioni di blocco, quindi i file +creati in modalità a thread singola non saranno identici ai file creati in +modalità a thread multiple. La mancanza di informazioni sulle dimensioni +significa anche che \fBxz\fP non sarà in grado di decomprimere i file in +modalità a thread multiple. +.TP +\fB\-\-block\-list=\fP\fIELEMENTI\fP +Quando si comprime nel formato \fB.xz\fP, inizia un nuovo blocco con una catena +di filtri personalizzata dopo gli intervalli indicati di dati non compressi. +.IP "" +Gli \fIELEMENTI\fP sono un elenco separato da virgole. Ogni elemento è +costituito da un numero di catena di filtri opzionale compreso tra 0 e 9 +seguito da due punti (\fB:\fP) e da una dimensione richiesta di dati non +compressi. L'omissione di un elemento (due o più virgole consecutive) è una +scorciatoia per utilizzare le dimensioni e i filtri dell'elemento +precedente. +.IP "" +Se il file di input è più grande della somma delle dimensioni in +\fIELEMENTI\fP, l'ultimo elemento viene ripetuto fino alla fine del file. Il +valore speciale \fB0\fP può essere utilizzato come ultima dimensione per +indicare che il resto del file deve essere codificato come un singolo +blocco. +.IP "" +È possibile specificare una catena di filtri alternativa per ogni blocco in +combinazione con le opzioni \fB\-\-filters1=\fP\fIFILTRI\fP \&...\& +\fB\-\-filters9=\fP\fIFILTRI\fP. Queste opzioni definiscono catene di filtri con un +identificatore compreso tra 1\(en9. La catena di filtri 0 può essere +utilizzata per indicare la catena di filtri predefinita, che equivale a non +specificare una catena di filtri. L'identificatore della catena di filtri +può essere utilizzato prima della dimensione non compressa, seguita da due +punti (\fB:\fP). Ad esempio, se si specifica +\fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP allora i blocchi verranno +creati utilizzando: +.RS +.IP \(bu 3 +La catena dei filtri specificata da \fB\-\-filters1\fP e un input di 2 MiB +.IP \(bu 3 +La catena dei filtri specificata da \fB\-\-filters3\fP e un input di 2 MiB +.IP \(bu 3 +La catena dei filtri specificata da \fB\-\-filters2\fP e un input di 4 MiB +.IP \(bu 3 +La catena dei filtri specificata da \fB\-\-filters2\fP e un input di 4 MiB +.IP \(bu 3 +La catena di filtri predefinita e l'input di 2 MiB +.IP \(bu 3 +La catena di filtri predefinita e l'input di 4 MiB per ogni blocco fino alla +fine dell'input. +.RE +.IP "" +Se si specifica una dimensione che supera la dimensione del blocco del +codificatore (il valore predefinito in modalità thread oppure il valore +specificato con \fB\-\-block\-size=\fP\fIDIMENSIONE\fP), il codificatore creerà +blocchi aggiuntivi mantenendo i limiti specificati in \fIELEMENTI\fP. Ad +esempio, se si indica \fB\-\-block\-size=10MiB\fP +\fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP e il file input è di 80 MiB, si +otterranno 11 blocchi: 5, 10, 8, 10, 2, 10, 10, 4, 10, 10, and 1 MiB. +.IP "" +In modalità a thread multiple, le dimensioni dei blocchi vengono memorizzate +nelle intestazioni dei blocchi. Questo non avviene in modalità thread +singola, quindi l'output codificato non sarà identico a quello della +modalità a thread multiple. +.TP +\fB\-\-flush\-timeout=\fP\fITIMEOUT\fP +Quando si comprime, se sono passati più di \fITIMEOUT\fP millisecondi (un +intero positivo) dallo scaricamento precedente e la lettura di ulteriori +input si bloccherebbe, tutti i dati di input in sospeso vengono scaricati +dal codificatore e resi disponibili nel flusso di output. Questo può essere +utile se \fBxz\fP viene usato per comprimere dati in streaming dalla +rete. Piccoli valori del \fITIMEOUT\fP rendono disponibili i dati al ricevente +con un ritardo minimo, mentre valori di \fITIMEOUT\fP grandi danno un miglior +rapporto di compressione. +.IP "" +Questa funzionalità è disabilitata per impostazione predefinita. Se questa +opzione viene specificata più di una volta, l'ultima ha effetto. Il valore +speciale \fITIMEOUT\fP di \fB0\fP può essere utilizzato per disabilitare +esplicitamente questa funzionalità. +.IP "" +Questa funzionalità non è disponibile sui sistemi non\-POSIX. +.IP "" +.\" FIXME +\fBQuesta funzionalità è sperimentale.\fP Attualmente \fBxz\fP non è adatto per +decomprimere il flusso in tempo reale, a causa di come effettua il +buffering. +.TP +\fB\-\-no\-sync\fP +Non sincronizzare il file target e la sua directory sull'unità di +archiviazione prima di rimuovere il file sorgente. Questo può migliorare le +performance se si sta comprimendo o decomprimendo tanti piccoli +file. Tuttavia, se il sistema dovesse andare in crash subito dopo +l'eliminazione, è possibile che il file destinazione non sia ancora stato +scritto sull'unità di archiviazione mentre l'operazione di eliminazione +sì. In questo caso non saranno più disponibili né il file sorgente originale +né il file di destinazione. +.IP "" +Questa opzione ha effetto solamente quando \fBxz\fP deve rimuovere il file +sorgente. Negli altri casi la sincronizzazione non viene eseguita. +.IP "" +La sincronizzazione e \fB\-\-no\-sync\fP sono stati aggiunti nella versione \fBxz\fP +5.7.1alpha. +.TP +\fB\-\-memlimit\-compress=\fP\fILIMITE\fP +Imposta un limite di utilizzo della memoria per la compressione. Se questa +opzione viene specificata più volte, ha effetto l'ultima. +.IP "" +Se le impostazioni di compressione superano il valore \fILIMITE\fP, \fBxz\fP +tenterà di regolare le impostazioni verso il basso in modo che il limite non +venga più superato e visualizzerà un avviso che indica che è stata eseguita +una regolazione automatica. Le regolazioni vengono eseguite in questo +ordine: riduzione del numero di thread, passaggio alla modalità a thread +singola se anche un solo thread in modalità a thread multiple supera il +\fILIMITE\fP, e infine riducendo la dimensione del dizionario LZMA2. +.IP "" +Quando si comprime con \fB\-\-format=raw\fP oppure se si è specificato +\fB\-\-no\-adjust\fP, è possibile ridurre solo il numero di thread, poiché questo +può essere fatto senza influire sull'output compresso. +.IP "" +Se non è possibile soddisfare il \fILIMITE\fP anche con le regolazioni sopra +descritte, viene visualizzato un errore e \fBxz\fP uscirà con lo stato di +uscita 1. +.IP "" +Il \fILIMITE\fP può essere specificato in diversi modi: +.RS +.IP \(bu 3 +Il \fILIMITE\fP può essere un valore assoluto in byte. Usare un suffisso intero +come \fBMiB\fP può essere utile. Ad esempio: \fB\-\-memlimit\-compress=80MiB\fP +.IP \(bu 3 +Il \fILIMITE\fP può essere specificato come percentuale della memoria fisica +(RAM) totale. Questo può essere utile specialmente quando si imposta la +variabile di ambiente \fBXZ_DEFAULTS\fP in uno script di inizializzazione di +shell che è condiviso tra computer diversi. In questo modo il limite è +automaticamente più grande sui sistemi con più memoria. Ad esempio: +\fB\-\-memlimit\-compress=70%\fP +.IP \(bu 3 +Il \fILIMITE\fP può essere reimpostato al suo valore predefinito impostandolo a +\fB0\fP.Questo attualmente equivale a impostare il \fILIMITE\fP a \fBmax\fP (nessun +limite nell'utilizzo di memoria). +.RE +.IP "" +Per \fBxz\fP a 32\-bit esiste un caso particolare: se il \fILIMITE\fP fosse oltre +\fB4020\ MiB\fP, il \fILIMITE\fP viene impostato a \fB4020\ MiB\fP. Su MIPS32 invece +viene usato \fB2000\ MiB\fP. (I valori \fB0\fP e \fBmax\fP non sono influenzati da +questo. Un comportamento simile non esiste per la decompressione). Questo +può essere utile quando un eseguibile a 32 bit ha accesso a uno spazio di +indirizzi da 4\ GiB (2 GiB su MIPS32), e si spera che non faccia danni in +altre situazioni. +.IP "" +Vedere anche la sezione \fBUtilizzo memoria\fP +.TP +\fB\-\-memlimit\-decompress=\fP\fILIMITE\fP +Imposta un limite di utilizzo della memoria per la decompressione. Questo +influisce anche sulla modalità \fB\-\-list\fP. Se l'operazione non è possibile +senza oltrepassare il \fILIMITE\fP, \fBxz\fP mostrerà un errore e la +decompressione del file fallirà. Si veda \fB\-\-memlimit\-compress=\fP\fILIMITE\fP +per possibili modi per specificare il \fILIMITE\fP. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fILIMITE\fP +Imposta un limite di utilizzo della memoria per la decompressione +multi\-thread. Questo può influire solo sul numero di thread; non indurrà mai +\fBxz\fP a rifiutarsi di decomprimere un file. Se \fILIMITE\fP è troppo basso per +consentire le thread multiple, il \fILIMITE\fP viene ignorato e \fBxz\fP +continuerà in modalità a thread singola. Si noti che se viene utilizzato +anche \fB\-\-memlimit\-decompress\fP, si applicherà sempre sia alla modalità a +thread singola che a quella a thread multiple, e quindi il \fILIMITE\fP +effettivo per le thread multiple non sarà mai superiore a quello impostato +con \fB\-\-memlimit\-decompress\fP. +.IP "" +In contrasto con le altre opzioni di limite di utilizzo della memoria, +\fB\-\-memlimit\-mt\-decompress=\fP\fILIMITE\fP ha un \fILIMITE\fP predefinito specifico +per il sistema. \fBxz \-\-info\-memory\fP può essere utilizzato per vedere il +valore corrente. +.IP "" +Questa opzione e il suo valore predefinito esistono perché, senza un limite, +il decompressore a thread multiple potrebbe finire per allocare una quantità +folle di memoria per alcuni file input. Se il valore predefinito \fILIMITE\fP è +troppo basso sul proprio sistema, è possibile aumentarlo liberamente, ma non +deve essere mai impostato a un valore più grande della quantità di RAM +utilizzabile, in quanto con file di input appropriati \fBxz\fP cercherà di +utilizzare quella quantità di memoria anche con un basso numero di +thread. Esaurire la memoria o fare swap non migliorerà le performance della +decompressione. +.IP "" +Vedi \fB\-\-memlimit\-compress=\fP\fILIMITE\fP per possibili modi per specificare il +\fILIMITE\fP. Impostando \fILIMITE\fP su \fB0\fP si ripristina il valore predefinito +\fILIMITE\fP specifico del sistema. +.TP +\fB\-M\fP \fILIMITE\fP, \fB\-\-memlimit=\fP\fILIMITE\fP, \fB\-\-memory=\fP\fILIMITE\fP +Questo equivale a specificare \fB\-\-memlimit\-compress=\fP\fILIMITE\fP +\fB\-\-memlimit\-decompress=\fP\fILIMITE\fP \fB\-\-memlimit\-mt\-decompress=\fP\fILIMITE\fP. +.TP +\fB\-\-no\-adjust\fP +Visualizza un errore e esce se non è possibile soddisfare il limite di +utilizzo della memoria senza regolare le impostazioni che influiscono +sull'output compresso. In altre parole, ciò impedisce a \fBxz\fP di passare il +codificatore dalla modalità multi\-thread alla modalità a thread singola e di +ridurre le dimensioni del dizionario LZMA2. Anche quando viene usata questa +opzione, il numero di thread può essere ridotto per soddisfare il limite di +utilizzo della memoria, in quanto ciò non influirà sull'output compresso. +.IP "" +La regolazione automatica è sempre disabilitata quando si creano flussi raw +(\fB\-\-format=raw\fP). +.TP +\fB\-T\fP \fITHREADS\fP, \fB\-\-threads=\fP\fITHREADS\fP +Specifica il numero di thread di lavoro da utilizzare. L'impostazione di +\fITHREADS\fP al valore speciale \fB0\fP fa sì che \fBxz\fP utilizzi fino a un numero +di thread che il processore/i del sistema supportano. Il numero effettivo di +thread può essere inferiore a \fITHREADS\fP se il file di input non è +sufficientemente grande per il threading con le impostazioni specificate o +se l'utilizzo di più thread supera il limite di utilizzo della memoria. +.IP "" +I compressori a thread singola e a thread multiple producono output +diversi. Il compressore a thread singola produrrà la dimensione del file più +piccola, ma solo l'output del compressore a thread multiple può essere +decompresso utilizzando più thread. Impostando \fITHREADS\fP su \fB1\fP verrà +utilizzata la modalità a thread singola. L'impostazione di \fITHREADS\fP su +qualsiasi altro valore, incluso \fB0\fP, utilizzerà il compressore a thread +multiple anche se il sistema supporta un solo thread hardware. (\fBxz\fP 5.2.x +utilizzava la modalità a thread singola in questa situazione.) +.IP "" +Per utilizzare la modalità a thread multiple con un solo thread, impostare +\fITHREADS\fP su \fB+1\fP. Il prefisso \fB+\fP non ha alcun effetto con valori +diversi da \fB1\fP. Un limite di utilizzo della memoria può comunque far +passare \fBxz\fP alla modalità a thread singola a meno che non venga utilizzato +\fB\-\-no\-adjust\fP. Il supporto per il prefisso \fB+\fP è stato aggiunto in \fBxz\fP +5.4.0. +.IP "" +Se è stato richiesto un numero automatico di thread e non è stato +specificato alcun limite di utilizzo della memoria, verrà utilizzato un +limite "soft" predefinito, specifico del sistema, per limitare eventualmente +il numero di thread. È un limite "soft" nel senso che viene ignorato se il +numero di thread diventa uno, quindi un limite soft non impedirà mai a \fBxz\fP +di comprimere o decomprimere. Questo limite soft predefinito non farà +passare \fBxz\fP dalla modalità a thread multiple alla modalità thread +singola. I limiti attivi possono essere visualizzati con \fBxz \-\-info\-memory\fP. +.IP "" +Attualmente l'unico metodo di threading consiste nel dividere l'input in +blocchi e comprimerli indipendentemente l'uno dall'altro. La dimensione +predefinita del blocco dipende dal livello di compressione e può essere +sovrascritta con l'opzione \fB\-\-block\-size=\fP\fIDIMENSIONE\fP. +.IP "" +La decompressione a thread multiple funziona solo su file che contengano più +blocchi con l'informazione della dimensione nelle intestazioni del +blocco. Tutti i file sufficientemente grandi compressi in modalità a thread +multiple soddisfano questa condizione, mentre i file compressi in modalità +thread singola no, neanche se si è utilizzato \fB\-\-block\-size=\fP +\fIDIMENSIONE\fP. +.IP "" +Il valore predefinito per \fITHREADS\fP è \fB0\fP. In \fBxz\fP 5.4.x e precedenti il +valore predefinito era \fB1\fP. +. +.SS "Catene di filtri di compressione personalizzate" +Una catena di filtri personalizzata consente di specificare in dettaglio le +impostazioni di compressione invece di fare affidamento sulle impostazioni +associate ai livelli preimpostati. Quando viene specificata una catena di +filtri personalizzata, le opzioni relative ai livelli preimpostati (\fB\-0\fP +\&...\& \fB\-9\fP e \fB\-\-extreme\fP) specificate in precedenza sulla riga di +comando vengono dimenticate. Se un'opzione livello preimpostato viene +specificata dopo una o più opzioni della catena di filtri personalizzata, il +nuovo livello preimpostato ha effetto e le opzioni della catena di filtri +personalizzate specificate in precedenza vengono dimenticate. +.PP +Una catena di filtri è paragonabile a una pipe sulla riga di +comando. Durante la compressione, l'input non compresso va al primo filtro, +il cui output va al filtro successivo (se presente). L'output dell'ultimo +filtro viene scritto nel file compresso. Il numero massimo di filtri nella +catena è quattro, ma in genere una catena di filtri ha solo uno o due +filtri. +.PP +Molti filtri hanno limitazioni su dove possono trovarsi nella catena di +filtri: alcuni filtri possono funzionare solo come ultimo filtro della +catena, altri solo come filtro non ultimo e alcuni funzionano in qualsiasi +posizione nella catena. A seconda del filtro, questa limitazione è inerente +alla struttura del filtro oppure esiste per evitare problemi di sicurezza. +.PP +Una catena di filtri personalizzata può essere specificata in due modi +diversi. Le opzioni \fB\-\-filters=\fP\fIFILTRI\fP and \fB\-\-filters1=\fP\fIFILTRI\fP +\&...\& \fB\-\-filters9=\fP\fIFILTRI\fP permettono di specificare un'intera catena +di filtri in una opzione utilizzando la sintassi della stringa del filtro di +lzma. In alternativa, una catena di filtri può essere specificata +utilizzando una o più singole opzioni di filtro nell'ordine desiderato nella +catena di filtri. Questo significa che l'ordine delle singole opzioni di +filtro è importante! Quando si decodificano i flussi grezzi +(\fB\-\-format=raw\fP), la catena di filtri deve essere specificata nello stesso +ordine in cui è stata specificata durante la compressione. Qualsiasi filtro +individuale o opzione livello preimpostato specificata prima dell'opzione +della catena completa (\fB\-\-filters=\fP\fIFILTRI\fP) verrà dimenticata. I singoli +filtri specificati dopo l'opzione della catena completa reimposteranno la +catena di filtri. +.PP +Sia l'opzione di filtro completo che quella individuale accettano \fIOPZIONI\fP +specifiche del filtro come un elenco separato da virgole. Virgole in eccesso +nelle \fIOPZIONI\fP vengono ignorate. Ogni opzione ha un valore di default, +quindi occorre specificare solamente quelle che si desidera modificare. +.PP +Per vedere l'intera catena di filtri e \fIOPZIONI\fP, usa \fBxz \-vv\fP (ossia, usa +\fB\-\-verbose\fP due volte). Questo funziona anche per visualizzare le opzioni +della catena di filtri utilizzate dai livelli preimpostati. +.TP +\fB\-\-filters=\fP\fIFILTRI\fP +Specifica l'intera catena dei filtri oppure un livello preimpostato in una +singola opzione. Ogni filtro può essere separato da spazi o da due trattini +(\fB\-\-\fP). Potrebbe essere necessario mettere tra virgolette i \fIFILTRI\fP sulla +riga di comando della shell in modo che vengano analizzati come una singola +opzione. Per indicare \fIOPZIONI\fP, usa \fB:\fP o \fB=\fP. Un livello preimpostato +può essere preceduto da un \fB\-\fP e seguito da zero o più flag. L'unico flag +supportato è \fBe\fP per applicare le stesse opzioni di \fB\-\-extreme\fP. +.TP +\fB\-\-filters1\fP=\fIFILTRI\fP ... \fB\-\-filters9\fP=\fIFILTRI\fP +Specifica fino a nove catene di filtri aggiuntive che possono essere +utilizzate con \fB\-\-block\-list\fP. +.IP "" +Ad esempio, quando si comprime un archivio con file eseguibili seguiti da +file di testo, la parte eseguibile potrebbe utilizzare una catena di filtri +con un filtro BCJ e la parte di testo solo il filtro LZMA2. +.TP +\fB\-\-filters\-help\fP +Mostra un messaggio di aiuto che descrive come specificare livelli +preimpostati e catene di filtri personalizzati nelle opzioni \fB\-\-filters\fP e +\fB\-\-filters1=\fP\fIFILTRI\fP \&...\& \fB\-\-filters9=\fP\fIFILTRI\fP, e termina con +successo. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fIOPZIONI\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fIOPZIONI\fP] +.PD +Aggiunge un filtro LZMA1 o LZMA2 alla catena dei filtri. Questi filtri +possono essere usati solo come ultimo filtro della catena. +.IP "" +LZMA1 è un filtro obsoleto, supportato quasi esclusivamente a causa del +formato obsoleto di file \fB.lzma\fP, che supporta solo LZMA1. LZMA2 è una +versione aggiornata di LZMA1 che risolve alcuni problemi pratici di +LZMA1. Il formato \fB.xz\fP utilizza LZMA2 e non supporta LZMA1. La velocità e +i rapporti di compressione di LZMA1 e LZMA2 sono praticamente gli stessi. +.IP "" +LZMA1 e LZMA2 condividono lo stesso insieme di \fIOPZIONI\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fIPRESET\fP +Reimposta tutte le \fIOPZIONI\fP LZMA1 o LZMA2 a \fIPRESET\fP. Il \fIPRESET\fP +(livello preimpostato) consiste di un numero intero, che può essere seguito +da modificatori costituiti da una singola lettera. Il numero intero può +andare da \fB0\fP a \fB9\fP, corrispondenti alle opzioni della riga di comando +\fB\-0\fP \&...\& \fB\-9\fP. L'unico modificatore attualmente supportato è \fBe\fP, che +corrisponde a \fB\-\-extreme\fP. Se non viene specificato alcun \fIPRESET\fP, i +valori predefiniti delle \fIOPZIONI\fP LZMA1 o LZMA2 sono presi dal livello +preimpostato \fB6\fP. +.TP +\fBdict=\fP\fIDIMENSIONE\fP +La \fIDIMENSIONE\fPdel dizionario (buffer di cronologia) indica quanti byte dei +dati non compressi elaborati di recente vengono mantenuti in +memoria. L'algoritmo tenta di trovare sequenze di byte ripetute +(corrispondenze) nei dati non compressi e di sostituirle con riferimenti ai +dati attualmente presenti nel dizionario. Più grande è il dizionario, +maggiore è la possibilità di trovare una corrispondenza. Quindi, l'aumento +della \fIDIMENSIONE\fP del dizionario di solito migliora il rapporto di +compressione, ma un dizionario più grande del file non compresso è uno +spreco di memoria. +.IP "" +Una \fIDIMENSIONE\fP tipica per un dizionario è da 64\ KiB a 64\ MiB. Il minimo +è 4\ KiB. Il massimo per la compressione è attualmente 1.5\ GiB (1536\ MiB). La decompressione supporta già dizionari fino a 4\ GiB meno 1 byte, +che è il massimo per i formati di flusso LZMA1 e LZMA2. +.IP "" +La \fIDIMENSIONE\fP del dizionario e il cercatore di corrispondenze +(\fICERCATORE\fP) insieme determinano l'utilizzo della memoria del codificatore +LZMA1 o LZMA2. Per la decompressione è necessaria la stessa \fIDIMENSIONE\fP +del dizionario utilizzata durante la compressione (o più grande), quindi +l'utilizzo della memoria del decodificatore è determinato dalla dimensione +del dizionario utilizzato durante la compressione. Le intestazioni \fB.xz\fP +memorizzano la \fIDIMENSIONE\fP del dizionario come 2^\fIn\fP o 2^\fIn\fP + 2^( +\fIn\fP\-1), quindi queste \fIDIMENSIONI\fP sono in qualche modo preferite per la +compressione. Altre \fIDIMENSIONI\fP verranno arrotondate per eccesso quando +memorizzate nelle intestazioni \fB.xz\fP. +.TP +\fBlc=\fP\fIlc\fP +Specificare il numero di bit di contesto letterali. Il minimo è 0 e il +massimo è 4; Il valore predefinito è 3. Inoltre, la somma di \fIlc\fP e \fIlp\fP +non deve superare 4. +.IP "" +Tutti i byte che non possono essere codificati come corrispondenze vengono +codificati come valori letterali. In altre parole, i valori letterali sono +semplicemente byte a 8 bit codificati uno alla volta. +.IP "" +La codifica letterale presuppone che i bit di \fIlc\fP più alti del byte non +compresso precedente siano correlati al byte successivo. Ad esempio, in un +tipico testo inglese, una lettera maiuscola è spesso seguita da una lettera +minuscola e una lettera minuscola è solitamente seguita da un'altra lettera +minuscola. Nel set di caratteri US\-ASCII, i tre bit più alti sono 010 per le +lettere maiuscole e 011 per le lettere minuscole. Quando \fIlc\fP è almeno 3, +la codifica letterale può sfruttare questa proprietà nei dati non compressi. +.IP "" +Il valore predefinito (3) solitamente è buono. Se si desidera la +compressione massima, provare con \fBlc=4\fP. A volte aiuta un po', e a volte +rende la compressione peggiore. Se la rende peggiore, provare anche \fBlc=2\fP. +.TP +\fBlp=\fP\fIlp\fP +Specificare il numero di bit di posizione letterale. Il minimo è 0 e il +massimo è 4; Il valore predefinito è 0. +.IP "" +Il parametro \fIlp\fP influisce sul tipo di allineamento nei dati non compressi +presunto durante la codifica dei valori letterali. Vedi \fIpb\fP di seguito per +ulteriori informazioni sull'allineamento. +.TP +\fBpb=\fP\fIpb\fP +Specificare il numero di bit di posizione. Il minimo è 0 e il massimo è 4; +Il valore predefinito è 2. +.IP "" +Il parametro \fIpb\fP influisce su quale tipo di allineamento nei dati non +compressi sia assunto in generale. L'impostazione predefinita indica un +allineamento a quattro byte (2^\fIpb\fP =2^2=4), che è spesso una buona scelta +se non c'è un'ipotesi migliore. +.IP "" +Quando l'allineamento è noto, impostare \fIpb\fP concordemente può ridurre un +po' le dimensioni del file. Ad esempio, con file di testo con 1 byte di +allineamento (US\-ASCII, ISO\-8859\-*, UTF\-8), impostare \fBpb=0\fP può migliorare +leggermente la compressione. Per il testo UTF\-16, \fBpb=1\fP è una buona +scelta. Se l'allineamento è un numero dispari, come 3 byte, \fBpb=0\fP potrebbe +essere la scelta migliore. +.IP "" +Anche se l'allineamento assunto può essere regolato con \fIpb\fP e \fIlp\fP, LZMA1 +e LZMA2 favoriscono ancora leggermente l'allineamento a 16 byte. Potrebbe +valere la pena tenerlo in considerazione quando si progettano formati di +file che possono essere spesso compressi con LZMA1 o LZMA2. +.TP +\fBmf=\fP\fICERCATORE\fP +Il cercatore di corrispondenze ha un effetto importante sulla velocità del +codificatore, sull'utilizzo della memoria e sul rapporto di compressione. Di +solito i cercatori di corrispondenze a catena hash sono più veloci dei +cercatori di corrispondenze ad albero binario. Il valore predefinito dipende +da \fIPRESET\fP : 0 usa \fBhc3\fP, 1\(en3 usa \fBhc4\fP e il resto usa \fBbt4\fP. +.IP "" +Sono supportati i seguenti cercatori di corrispondenze. Le formule di +utilizzo della memoria riportate di seguito sono approssimazioni, che sono +le più vicine alla realtà quando \fIDIZIONARIO\fP è una potenza di due. +.RS +.TP +\fBhc3\fP +Catena hash con hashing da 2 e 3 byte +.br +Minimo valore per \fINICE\fP: 3 +.br +Utilizzo memoria: +.br +\fIDIZIONARIO\fP * 7.5 (se \fIDIZIONARIO\fP <= 16 MiB); +.br +\fIDIZIONARIO\fP * 5.5 + 64 MiB (se \fIDIZIONARIO\fP > 16 MiB) +.TP +\fBhc4\fP +Catena hash con hash da 2, 3 e 4 byte +.br +Minimo valore per \fINICE\fP: 4 +.br +Utilizzo memoria: +.br +\fIDIZIONARIO\fP * 7.5 (se \fIDIZIONARIO\fP <= 32 MiB); +.br +\fIDIZIONARIO\fP * 6.5 (se \fIDIZIONARIO\fP > 32 MiB) +.TP +\fBbt2\fP +Albero binario con hashing da 2 byte +.br +Valore minimo per \fINICE\fP: 2 +.br +Utilizzo di memoria: \fIDIZIONARIO\fP * 9.5 +.TP +\fBbt3\fP +Albero binario con hashing da 2 e 3 byte +.br +Minimo valore per \fINICE\fP: 3 +.br +Utilizzo memoria: +.br +\fIDIZIONARIO\fP * 11.5 (se \fIDIZIONARIO\fP <= 16 MiB); +.br +\fIDIZIONARIO\fP * 9.5 + 64 MiB (se \fIDIZIONARIO\fP > 16 MiB) +.TP +\fBbt4\fP +Albero binario con hashing da 2, 3 e 4 byte +.br +Minimo valore per \fINICE\fP: 4 +.br +Utilizzo memoria: +.br +\fIDIZIONARIO\fP * 11.5 (se \fIDIZIONARIO\fP <= 32 MiB); +.br +\fIDIZIONARIO\fP * 10.5 (se \fIDIZIONARIO\fP > 32 MiB) +.RE +.TP +\fBmode=\fP\fIMODALITÀ\fP +La \fIMODALITÀ\fP di compressione specifica il metodo per analizzare i dati +prodotti dal cercatore di corrispondenze. Le \fIMODALITÀ\fP supportate sono +\fBfast\fP e \fBnormal\fP. Il predefinito è \fBfast\fP per i \fIPRESET\fP 0\(en3 e +\fBnormal\fP per i \fIPRESET\fP 4\(en9. +.IP "" +Di solito \fBfast\fP viene utilizzato con i cercatori di corrispondenze a +catena hash e \fBnormal\fP con i cercatori di corrispondenze a albero +binario. Questo è anche quello che fanno i \fIPRESET\fP. +.TP +\fBnice=\fP\fINICE\fP +Specifica quella che si considera una lunghezza accettabile ("nice") per una +corrispondenza. Una volta trovata una corrispondenza di almeno \fINICE\fP byte, +l'algoritmo smette di cercare corrispondenze potenzialmente migliori. +.IP "" +\fINICE\fP può valere 2\(en273 byte. Valori più alti tendono a dare un miglior +rapporto di compressione ai danni della velocità. Il valore predefinito +dipende dal \fIPRESET\fP. +.TP +\fBdepth=\fP\fIPROFONDITÀ\fP +Specificare la profondità di ricerca massima nel cercatore di +corrispondenze. Il valore predefinito è il valore speciale 0, che dice al +compressore di determinare una \fIPROFONDITÀ\fP ragionevole da \fICERCATORE\fP e +\fINICE\fP. +.IP "" +Una \fIPROFONDITÀ\fP ragionevole per le catene hash è 4\(en100 e 16\(en1000 per +gli alberi binari. Utilizzando valori di \fIPROFONDITÀ\fP molto alti si può +rendere il codificatore estremamente lento con alcuni file. Evitare di +impostare la \fIPROFONDITÀ\fP oltre 1000 a meno che si sia preparati a +interrompere la compressione nel caso in cui richieda troppo tempo. +.RE +.IP "" +Quando si decomprime un flusso grezzo (\fB\-\-format=raw\fP), LZMA2 ha bisogno +solamente della \fIDIMENSIONE\fP del dizionario. LZMA1 ha anche bisogno di +\fIlc\fP, \fIlp\fP, e \fIpb\fP. +.TP +\fB\-\-x86\fP[\fB=\fP\fIOPZIONI\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fIOPZIONI\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fIOPZIONI\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fIOPZIONI\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fIOPZIONI\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fIOPZIONI\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fIOPZIONI\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIOPZIONI\fP] +.PD +Aggiunge un filtro branch/call/jump (BCJ) alla catena dei filtri. Questi +filtri non possono essere utilizzati come ultimo filtro nella catena di +filtri. +.IP "" +Un filtro BCJ converte gli indirizzi relativi in codice macchina nelle loro +controparti assolute. Questo non cambia la dimensione dei dati ma aumenta la +ridondanza, cosa che può aiutare LZMA2 a produrre \fB.xz\fP file 0\(en15\ % più +piccoli. I filtri BCJ sono sempre reversibili, quindi usare un filtro BCJ +per il tipo di dati sbagliato non causa perdita di dati, al massimo può +determinare un rapporto di compressione leggermente peggiore. I filtri BCJ +sono molto veloci e usano una quantità di memoria minima. +.IP "" +Questi filtri BCJ presentano problemi noti relativi al rapporto di +compressione: +.RS +.IP \(bu 3 +Alcuni tipi di file contenenti codice eseguibile (ad esempio, file oggetto, +librerie statiche e moduli del kernel Linux) hanno gli indirizzi nelle +istruzioni riempiti con valori di riempimento. Questi filtri BCJ eseguiranno +comunque la conversione degli indirizzi, il che peggiorerà la compressione +con questi file. +.IP \(bu 3 +Se un filtro BCJ viene applicato a un archivio, è possibile che renda il +rapporto di compressione peggiore rispetto a non usare un filtro BCJ. Ad +esempio, se ci sono eseguibili simili o addirittura identici, il filtraggio +probabilmente renderà i file meno simili e quindi la compressione sarà +peggiore. Anche il contenuto dei file non eseguibili nello stesso archivio +può essere importante. In pratica bisogna provare con e senza filtro BCJ per +vedere quale sia il migliore in ogni situazione. +.RE +.IP "" +Insiemi diversi di istruzioni hanno diversi allineamenti: il file eseguibile +deve essere allineato a un multiplo di questo valore nei dati di input per +far funzionare il filtro. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +Filtro;Allineamento;Note +x86;1;32\-bit o 64\-bit x86 +ARM;4; +ARM\-Thumb;2; +ARM64;4;L'allineamento migliore è a 4096 byte +PowerPC;4;Solo big\-endian +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +Dal momento che i dati filtrati da BCJ solitamente sono compressi con LZMA2, +il rapporto di compressione può essere migliorato leggermente se le opzioni +LZMA2 sono impostate in modo che corrispondano all'allineamento del filtro +BCJ selezionato. Esempi: +.RS +.IP \(bu 3 +Il filtro IA\-64 ha un allineamento a 16 byte, quindi \fBpb=4,lp=4,lc=0\fP è una +buona scelta per LZMA2 (2^4=16). +.IP \(bu 3 +Il codice RISC\-V ha un allineamento a 2 o 4 byte a seconda che il file +contenga o meno istruzioni 16 bit compresse (cosiddetta estensione +C). Quando sono usate istruzioni a 16 bit, va bene \fBpb=2,lp=1,lc=3\fP o +\fBpb=1,lp=1,lc=3\fP. Quando le istruzioni a 16 bit non sono presenti, è meglio +\fBpb=2,lp=2,lc=2\fP. Si può usare \fBreadelf \-h\fP per controllare se "RVC" +appare sulla riga del "Flag". +.IP \(bu 3 +ARM64 è sempre allineato a 4 byte, quindi \fBpb=2,lp=2,lc=2\fP è la scelta +migliore. +.IP \(bu 3 +Il filtro x86 è un'eccezione. Di solito è bene attenersi alle impostazioni +predefinite di LZMA2 (\fBpb=2,lp=0,lc=3\fP) quando si comprimono gli eseguibili +x86. +.RE +.IP "" +Tutti i filtri BCJ supportano le stesse \fIOPZIONI\fP: +.RS +.TP +\fBstart=\fP\fIOFFSET\fP +Specifica l'\fIOFFSET\fP iniziale utilizzato per la conversione tra indirizzi +relativi e assoluti. L'\fIOFFSET\fP deve essere un multiplo dell'allineamento +del filtro (vedere la tabella sopra). Il valore predefinito è zero. In +pratica, l'impostazione predefinita è buona; specificare un \fIOFFSET\fP +personalizzato non è quasi mai utile. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fIOPZIONI\fP] +Aggiunge un filtro Delta alla catena dei filtri. I filtri Delta non possono +essere utilizzati come ultimo filtro nella catena di filtri. +.IP "" +Al momento è supportato solo un semplice calcolo delta byte\-per\-byte. Può +essere utile quando si comprime, per esempio, immagini bitmap non compresse +o file audio PCM non compressi. Tuttavia, speciali algoritmi ad\-hoc +potrebbero dare risultati significativamente migliori che Delta + +LZMA2. Questo è vero specialmente per l'audio, che comprime più velocemente +e meglio, ad esempio, con \fBflac\fP(1). +.IP "" +\fIOPZIONI\fP supportate: +.RS +.TP +\fBdist=\fP\fIDISTANZA\fP +Specifica la \fIDISTANZA\fP del calcolo delta in byte. \fIDISTANZA\fP deve essere +nel range 1\(en256. Il valore predefinito è 1. +.IP "" +Per esempio, con \fBdist=2\fP e un input di 8 byte A1 B1 A2 B3 A3 B5 A4 B7, +l'output sarà A1 B1 01 02 01 02 01 02. +.RE +. +.SS "Altre opzioni" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Sopprime avvertimenti e avvisi. Specificarlo due volte per eliminare anche +gli errori. Questa opzione non ha alcun effetto sullo stato di uscita. In +altre parole, anche se un avvertimento è stato eliminato, lo stato di uscita +che indica un avvertimento viene comunque utilizzato. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +Sii prolisso. Se lo standard error è collegato a un terminale, \fBxz\fP +visualizzerà un indicatore di avanzamento. Specificando \fB\-\-verbose\fP due +volte si otterrà un output ancora più dettagliato. +.IP "" +L'indicatore di avanzamento mostra le seguenti informazioni: +.RS +.IP \(bu 3 +La percentuale di avanzamento è mostrata se la dimensione del file input è +nota. Quindi, la percentuale non può essere mostrata nei pipe. +.IP \(bu 3 +Quantità di dati compressi prodotti (in compressione) o utilizzati (in +decompressione). +.IP \(bu 3 +Quantità di dati non compressi consumati (in compressione) o prodotti (in +decompressione). +.IP \(bu 3 +Rapporto di compressione, calcolato dividendo la quantità di dati compressi +processati finora con la quantità di dati non compressi processati finora. +.IP \(bu 3 +Velocità di compressione o decompressione. Questa è misurata come la +quantità di dati non compressi consumati (in compressione) o prodotti (in +decompressione) al secondo. Viene mostrata dopo che è trascorso qualche +secondo da quando \fBxz\fP ha iniziato a processare il file. +.IP \(bu 3 +Tempo trascorso nel formato M:SS o H:MM:SS. +.IP \(bu 3 +Il tempo residuo stimato è mostrato solo quando la dimensione del file in +ingresso è nota e sono già passati un paio di secondi da quando \fBxz\fP ha +iniziato a processare il file. Il tempo è mostrato in un formato meno +preciso che non ha mai i due punti, ad esempio 2 min 30 s. +.RE +.IP "" +Quando lo standard error non è un terminale, \fB\-\-verbose\fP farà stampare a +\fBxz\fP il nome del file, la dimensione compressa, la dimensione non +compressa, il rapporto di compressione, e potendo anche la velocità e il +tempo trascorso, su una singola riga dello standard error, dopo aver +compresso o decompresso il file. La velocità e il tempo trascorso sono +inclusi solo se l'operazione è durata almeno un paio di secondi. Se +l'operazione non è conclusa, ad esempio a causa dell'interruzione da parte +dell'utente, viene stampata anche la percentuale di completamento, a patto +che la dimensione del file input sia nota. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Non impostare lo stato di uscita a 2 anche se è stata rilevata una +condizione che merita un avvertimento. Questa opzione non influisce sul +livello di dettaglio, quindi sia \fB\-\-quiet\fP che \fB\-\-no\-warn\fP devono essere +utilizzati per non visualizzare avvertimenti e per non alterare lo stato di +uscita. +.TP +\fB\-\-robot\fP +Stampa i messaggi in un formato analizzabile dal computer. Questo ha lo +scopo di facilitare la scrittura dei frontend che vogliono usare \fBxz\fP +invece di liblzma, che potrebbe essere il caso di vari script. Si intende +che con questa opzione abilitata l'output dovrebbe rimanere stabile tra le +versioni di \fBxz\fP. Per ulteriori informazioni, vedere la sezione \fBMODALITÀ ROBOT\fP. +.TP +\fB\-\-info\-memory\fP +Mostra, in un formato leggibile da umani, quanta memoria fisica (RAM) e +quante thread \fBxz\fP pensa che il sistema abbia e i limiti di utilizzo di +memoria per la compressione e la decompressione, quindi termina con +successo. +.TP +\fB\-h\fP, \fB\-\-help\fP +Mostra un messaggio di aiuto che descrive le opzioni usate più comunemente, +e termina con successo. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +Mostra un messaggio di aiuto che descrive tutte le funzionalità di \fBxz\fP, e +termina con successo +.TP +\fB\-V\fP, \fB\-\-version\fP +Mostra il numero di versione di \fBxz\fP e liblzma in un formato leggibile +dagli umani. Per ottenere un output analizzabile da una macchina specificare +\fB\-\-robot\fP prima di \fB\-\-version\fP. +. +.SH "MODALITÀ ROBOT" +La "modalità robot" viene attivata con l'opzione \fB\-\-robot\fP. Rende l'output +di \fBxz\fP più facile da analizzare da altri programmi. Attualmente \fB\-\-robot\fP +è supportato solo insieme a \fB\-\-list\fP, \fB\-\-filters\-help\fP, \fB\-\-info\-memory\fP e +\fB\-\-version\fP. In futuro sarà supportato per la compressione e la +decompressione. +. +.SS "Modalità stampa" +\fBxz \-\-robot \-\-list\fP usa un output separato da tabulazione. La prima colonna +di ogni riga contiene una stringa che indica il tipo di informazione +contenuta in quella riga: +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP +Questa è sempre la prima riga quando si inizia a elencare un file. La +seconda colonna della riga è il nome del file. +.TP +\fBfile\fP +Questa riga contiene informazioni generali sul file \fB.xz\fP. Questa riga +viene sempre stampata dopo la riga \fBname\fP. +.TP +\fBstream\fP +Questo tipo di riga viene utilizzato solo quando è stato specificato +\fB\-\-verbose\fP. Sono presenti tante righe \fBstream\fP quanti sono i flussi nel +file \fB.xz\fP. +.TP +\fBblock\fP +Questo tipo di riga viene utilizzato solo quando è stato specificato +\fB\-\-verbose\fP. Ci sono tante righe \fBblock\fP quanti sono i blocchi nel file +\&\fB.xz\fP. Le righe \fBblock\fP vengono visualizzate dopo tutte le righe +\fBstream\fP; i diversi tipi di riga non vengono interlacciati. +.TP +\fBsummary\fP +Questo tipo di riga viene utilizzato solo quando \fB\-\-verbose\fP è stato +specificato due volte. Questa riga viene stampata dopo tutte le righe +\fBblock\fP. Come la riga \fBfile\fP, la riga \fBsummary\fP contiene informazioni +generali sul file \fB.xz\fP. +.TP +\fBtotals\fP +Questa riga è sempre l'ultima riga dell'output dell'elenco. Mostra i +conteggi totali e le dimensioni. +.PP +Le colonne delle righe \fBfile\fP: +.PD 0 +.RS +.IP 2. 4 +Numero di flussi nel file +.IP 3. 4 +Numero totale di blocchi nel flusso/i. +.IP 4. 4 +Dimensione compressa del file +.IP 5. 4 +Dimensione non compressa del file +.IP 6. 4 +Rapporto di compressione, es. \fB0.123\fP. Se il rapporto è oltre 9999, al +posto del rapporto vengono mostrati tre trattini (\fB\-\-\-\fP). +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +Elenco separato da virgole dei nomi dei controlli di integrità. Le stringhe +seguenti vengono utilizzate per i tipi di controllo conosciuti: \fBNone\fP, +\fBCRC32\fP, \fBCRC64\fP, e \fBSHA\-256\fP. Per i tipi di controllo non conosciuti +viene utilizzato \fBUnknown\-\fP\fIN\fP, dove \fIN\fP è l'ID del controllo come numero +decimale (una o due cifre). +.IP 8. 4 +Dimensione totale del padding del flusso nel file +.RE +.PD +.PP +Le colonne delle righe \fBstream\fP: +.PD 0 +.RS +.IP 2. 4 +Numero di flusso (il primo è 1) +.IP 3. 4 +Numero di blocchi nel flusso +.IP 4. 4 +Offset iniziale compressione +.IP 5. 4 +Offset iniziale decompressione +.IP 6. 4 +Dimensione compressa (non include il padding del flusso) +.IP 7. 4 +Dimensione non compressa +.IP 8. 4 +Rapporto di compressione +.IP 9. 4 +Nome del controllo di integrità +.IP 10. 4 +Dimensione del padding del flusso +.RE +.PD +.PP +Le colonne delle righe \fBblock\fP: +.PD 0 +.RS +.IP 2. 4 +Numero di flussi che contengono questo blocco +.IP 3. 4 +Numero del blocco relativo all'inizio del flusso (il primo blocco è 1) +.IP 4. 4 +Numero del blocco relativo all'inizio del file +.IP 5. 4 +Offset iniziale compressione relativo all'inizio del file +.IP 6. 4 +Offset iniziale decompressione relativo all'inizio del file +.IP 7. 4 +Dimensione totale compressa del blocco (incluse le intestazioni) +.IP 8. 4 +Dimensione non compressa +.IP 9. 4 +Rapporto di compressione +.IP 10. 4 +Nome del controllo di integrità +.RE +.PD +.PP +Se \fB\-\-verbose\fP viene specificato due volte, sono incluse colonne aggiuntive +nelle righe \fBblock\fP. Queste non sono mostrate con un \fB\-\-verbose\fP singolo, +perché recuperare queste informazioni richiede molte ricerche e quindi può +essere lento: +.PD 0 +.RS +.IP 11. 4 +Valore del controllo di integrità in formato esadecimale +.IP 12. 4 +Dimensione intestazione blocco +.IP 13. 4 +Flag del blocco: \fBc\fPindica che è presente la dimensione compressa, \fBu\fP +indica che è presente la dimensione non compressa. Se il flag non è +impostato, viene mostrato un trattino (\fB\-\fP) per mantenere fissa la +lunghezza della stringa. Nuovi flag potrebbero essere aggiunti alla fine +della stringa in futuro. +.IP 14. 4 +Dimensione dei dati compressi effettivi nel blocco (sono esclusi +l'intestazione del blocco, il padding del blocco e i campi di controllo) +.IP 15. 4 +Quantità di memoria (in byte) necessaria per decomprimere questo blocco con +questa versione \fBxz\fP +.IP 16. 4 +Catena di filtri. Si noti che la maggior parte delle opzioni utilizzate al +momento della compressione non è nota, perché solo le opzioni necessarie per +la decompressione sono memorizzate nelle intestazioni \fB.xz\fP. +.RE +.PD +.PP +Le colonne delle righe \fBsummary\fP: +.PD 0 +.RS +.IP 2. 4 +Quantità di memoria (in byte) necessaria per decomprimere questo file con +questa versione \fBxz\fP +.IP 3. 4 +\fByes\fP o \fBno\fP indica se tutte le intestazioni di blocco contengono +all'interno sia dimensioni compresse che dimensioni non compresse +.PP +\fIA partire da\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +Versione minima di \fBxz\fP richiesta per decomprimere il file +.RE +.PD +.PP +Le colonne delle righe \fBtotali\fP: +.PD 0 +.RS +.IP 2. 4 +Numero di flussi +.IP 3. 4 +Numero di blocchi +.IP 4. 4 +Dimensione compressa +.IP 5. 4 +Dimensione non compressa +.IP 6. 4 +Rapporto di compressione medio +.IP 7. 4 +Elenco separato da virgole dei nomi dei controlli di integrità presenti nei +file +.IP 8. 4 +Dimensione del padding dello stream +.IP 9. 4 +Numero di file. Questo serve a mantenere l'ordine delle colonne precedenti +uguale a quello delle righe del \fBfile\fP. +.PD +.RE +.PP +Se \fB\-\-verbose\fP viene specificato due volte, sono incluse colonne aggiuntive +nella riga \fBtotali\fP: +.PD 0 +.RS +.IP 10. 4 +Quantità massima di memoria (in byte) necessaria per decomprimere i file con +questa versione \fBxz\fP +.IP 11. 4 +\fByes\fP o \fBno\fP indica se tutte le intestazioni di blocco contengono +all'interno sia dimensioni compresse che dimensioni non compresse +.PP +\fIA partire da\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +Versione minima di \fBxz\fP richiesta per decomprimere il file +.RE +.PD +.PP +Versioni future potrebbero aggiungere nuovi tipi di riga e nuove colonne +possono essere aggiunte ai tipi di riga esistenti, ma le colonne esistenti +non verranno modificate. +. +.SS "Aiuto sui filtri" +\fBxz \-\-robot \-\-filters\-help\fP stampa i filtri supportati nel seguente +formato: +.PP +\fIFILTRO\fP\fB:\fP\fIOPZIONE\fP\fB=<\fP\fIVALORE\fP\fB>,\fP\fIOPZIONE\fP\fB=<\fP\fIVALORE\fP\fB>\fP... +.TP +\fIFILTRO\fP +Nome del filtro +.TP +\fIOPZIONE\fP +Nome di un'opzione specifica del filtro +.TP +\fIVALORE\fP +Gli intervalli del \fIVALORE\fP numerico appaiono come +\fB<\fP\fIMIN\fP\fB\-\fP\fIMAX\fP\fB>\fP. Le scelte per i \fIVALORI\fP stringa sono +mostrati in \fB< >\fP e separati dal carattere \fB|\fP. +.PP +Ogni filtro è mostrato su una riga dedicata. +. +.SS "Informazione limite memoria" +\fBxz \-\-robot \-\-info\-memory\fP stampa una singola riga con più colonne separate +da tabulazione: +.IP 1. 4 +Quantità totale di memoria fisica (RAM) in byte. +.IP 2. 4 +Limite utilizzo memoria per la compressione in byte +(\fB\-\-memlimit\-compress\fP). Il valore speciale \fB0\fP indica l'impostazione +predefinita, che in modalità thread singola equivale a nessun limite. +.IP 3. 4 +Limite utilizzo memoria per la decompressione in byte +(\fB\-\-memlimit\-decompress\fP). Il valore speciale \fB0\fP indica l'impostazione +predefinita, che in modalità thread singola equivale a nessun limite. +.IP 4. 4 +A partire da \fBxz\fP 5.3.4alpha: Utilizzo della memoria per la decompressione +a thread multiple in byte (\fB\-\-memlimit\-mt\-decompress\fP). Questo valore non è +mai zero perché viene utilizzato un valore predefinito specifico del sistema +mostrato nella colonna 5, se non è stato specificato alcun limite in modo +esplicito. Inoltre, non è mai maggiore del valore nella colonna 3, anche se +è stato specificato un valore maggiore con \fB\-\-memlimit\-mt\-decompress\fP. +.IP 5. 4 +A partire da \fBxz\fP 5.3.4alpha: un limite di utilizzo della memoria +predefinito specifico del sistema, che viene utilizzato per limitare il +numero di thread durante la compressione con un numero automatico di thread +(\fB\-\-threads=0\fP) e non è stato specificato alcun limite di utilizzo della +memoria (\fB\-\-memlimit\-compress\fP). Questo viene utilizzato anche come valore +predefinito per \fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +A partire da \fBxz\fP 5.3.4alpha: Numero di thread del processore disponibili. +.PP +In futuro, l'output di \fBxz \-\-robot \-\-info\-memory\fP potrebbe avere più +colonne, ma mai più di una singola riga. +. +.SS Versione +\fBxz \-\-robot \-\-version\fP stampa il numero di versione di \fBxz\fP e liblzma nel +seguente formato: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +Versione major. +.TP +\fIYYY\fP +Versione minor. I numeri pari sono stabili. I numeri dispari sono versioni +alfa o beta. +.TP +\fIZZZ\fP +Livello di patch per le versioni stabili o solo un contatore per le versioni +di sviluppo. +.TP +\fIS\fP +Stabilità. 0 è alfa, 1 è beta e 2 è stabile. \fIS\fP dovrebbe essere sempre 2 +quando \fIYYY\fP è pari. +.PP +\fIXYYYZZZS\fP sono uguali su entrambe le righe se \fBxz\fP e liblzma appartengono +allo stesso rilascio delle XZ Utils. +.PP +Esempi: 4.999.9beta è \fB49990091\fP e 5.0.0 è \fB50000002\fP. +. +.SH "CODICE DI USCITA" +.TP +\fB0\fP +Tutto bene. +.TP +\fB1\fP +È avvenuto un errore. +.TP +\fB2\fP +Si è verificato qualcosa che merita un avvertimento, ma non si sono +verificati errori effettivi. +.PP +Gli avvisi (non gli avvertimenti o gli errori) stampati sullo standard error +non influiscono sullo stato di uscita. +. +.SH AMBIENTE +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP analizza elenchi di opzioni separate da spazi dalle variabili +d'ambiente \fBXZ_DEFAULTS\fP e \fBXZ_OPT\fP, in questo ordine, analizzando prima +le opzioni dalla riga di comando. Si noti che solo le opzioni vengono +analizzate dalle variabili d'ambiente; tutte le non\-opzioni vengono ignorate +silenziosamente. L'analisi viene eseguita con \fBgetopt_long\fP(3) che viene +utilizzato anche per gli argomenti della riga di comando. +.PP +\fBAttenzione:\fP Impostando queste variabili di ambiente, si sta di fatto +modificando programmi e script che lanciano \fBxz\fP. La maggior parte delle +volte va bene impostare i limiti di utilizzo della memoria, il numero di +thread e le opzioni di compressione tramite variabili d'ambiente. Tuttavia, +alcune opzioni possono rompere degli script. Un esempio banale è \fB\-\-help\fP +che forza \fBxz\fP a mostrare la pagina di aiuto anziché comprimere o +decomprimere file. Esempi meno ovvi sono \fB\-\-quiet\fP e \fB\-\-verbose\fP. In +molti casi funziona bene abilitare l'indicatore di avanzamento usando +\fB\-\-verbose\fP, ma in alcune situazioni i messaggi extra creano problemi. Il +livello di prolissità influisce anche sul comportamento di \fB\-\-list\fP. +.TP +\fBXZ_DEFAULTS\fP +Opzioni predefinite specifiche dell'utente o a livello di sistema. In genere +questo viene impostato in uno script di inizializzazione della shell per +abilitare il valore predefinito del limitatore di utilizzo della memoria di +\fBxz\fP, o per impostare il numero di thread predefinito. Escludendo gli +script di inizializzazione della shell e analoghi casi particolari, gli +script non dovrebbero mai impostare o annullare l'impostazione di +\fBXZ_DEFAULTS\fP. +.TP +\fBXZ_OPT\fP +Questo serve per passare le opzioni a \fBxz\fP quando non sia possibile +impostare le opzioni direttamente sulla riga di comando di \fBxz\fP. Questo è +il caso quando \fBxz\fP viene eseguito da uno script o da uno strumento, ad +esempio GNU \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +Gli script possono usare \fBXZ_OPT\fP, per esempio, per impostare opzioni di +compressione predefinite specifiche per lo script. Si raccomanda comunque di +permettere agli utenti di sovrascrivere \fBXZ_OPT\fPse questo è ragionevole. Ad +esempio, negli script \fBsh\fP(1) si può usare qualcosa come questo: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "COMPATIBILITÀ LZMA UTILS" +La sintassi della riga di comando di \fBxz\fP è essenzialmente un sopra\-insieme +di \fBlzma\fP, \fBunlzma\fP, e \fBlzcat\fP come trovati nelle LZMA Utils +4.32.x. Nella maggior parte dei casi è possibili sostituire le LZMA Utils +con le XZ Utils senza rompere gli script esistenti. Ci sono però alcune +incompatibilità, che in alcuni casi potrebbero causare problemi. +. +.SS "Livelli di compressione preimpostati" +La numerazione dei livelli di compressione preimpostati non è identica in +\fBxz\fP e nelle LZMA Utils. La differenza più importante è il modo in cui le +dimensioni del dizionario vengono mappate sulle diverse preimpostazioni. La +dimensione del dizionario è approssimativamente uguale all'utilizzo della +memoria del decompressore. +.RS +.PP +.TS +tab(;); +c c c +c n n. +Livello;xz;LZMA Utils +\-0;256 KiB;N/A +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +Le differenze di dimensione del dizionario influiscono anche sull'utilizzo +della memoria del compressore, ma ci sono alcune altre differenze tra le +LZMA Utils e le XZ Utils, che rendono la differenza ancora più grande: +.RS +.PP +.TS +tab(;); +c c c +c n n. +Livello;xz;LZMA Utils 4.32.x +\-0;3 MiB;N/A +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +Il livello preimpostato predefinito nelle LZMA Utils è \fB\-7\fP mentre nelle XZ +Utils è \fB\-6\fP, quindi entrambi utilizzano un dizionario da 8 MiB per +impostazione predefinita. +. +.SS "File .lzma con flussi vs. senza flussi" +La dimensione non compressa del file può essere memorizzata +nell'intestazione \fB.lzma\fP. Le LZMA Utils lo fanno durante la compressione +di file regolari. L'alternativa consiste nel memorizzare che la dimensione +non compressa è sconosciuta e utilizzare l'indicatore di fine carico utile +per indicare il punto in cui il decompressore deve fermarsi. Le LZMA Utils +utilizzano questo metodo quando le dimensioni non compresse non sono note, +come nel caso, ad esempio, delle pipe. +.PP +\fBxz\fP supporta la decompressione di file \fB.lzma\fP con o senza il marcatore +di fine payload, ma tutti i file \fB.lzma\fP creati da \fBxz\fP utilizzeranno il +marcatore di fine payload e avranno dimensioni non compresse contrassegnate +come sconosciute nell'intestazione \fB.lzma\fP. Questo può essere un problema +in alcune situazioni non comuni. Ad esempio, un decompressore \fB.lzma\fP in un +dispositivo embedded potrebbe funzionare solo con file con dimensioni non +compresse note. Se si incorre in questo problema, occorre utilizzare le LZMA +Utils oppure l'LZMA SDK per creare dei file \fB.lzma\fP con dimensioni non +compresse note. +. +.SS "File .lzma non supportati" +Il formato \fB.lzma\fP permette valori \fIlc\fP fino a 8, e valori \fIlp\fP fino a +4. Le LZMA Utils possono decomprimere file con qualunque \fIlc\fP e \fIlp\fP, ma +creeranno sempre file con \fBlc=3\fP e \fBlp=0\fP. Creare file con altri \fIlc\fP e +\fIlp\fP è possibile con \fBxz\fP e con l'LZMA SDK. +.PP +L'implementazione del filtro LZMA1 in liblzma richiede che la somma di \fIlc\fP +e \fIlp\fP non debba superare 4. Pertanto, i file \fB.lzma\fP che superano questa +limitazione non possono essere decompressi con \fBxz\fP. +.PP +Le LZMA Utils creano solo file \fB.lzma\fP con dimensione del dizionario 2^\fIn\fP +(una potenza di 2) ma accettano file con qualsiasi dimensione di +dizionario. liblzma accetta solo file \fB.lzma\fP con dimensione del dizionario +2^\fIn\fP o 2^\fIn\fP + 2^(\fIn\fP\-1). Questo serve a limitare i falsi positivi +quando si cerca di identificare i file \fB.lzma\fP. +.PP +All'atto pratico queste limitazioni non dovrebbero essere un problema, +perché praticamente tutti i file \fB.lzma\fP sono stati compressi con +impostazioni che liblzma accetterà. +. +.SS "Dati sporchi finali" +Quando si decomprime, le LZMA Utils ignorano automaticamente tutto quello +che c'è dopo il primo flusso \fB.lzma\fP. Nella maggior parte delle situazioni +questo è un baco. Questo significa anche che le LZMA Utils non supportano la +decompressione di file \fB.lzma\fP concatenati. +.PP +Se sono rimasti dati dopo il primo flusso \fB.lzma\fP, \fBxz\fP considera il file +corrotto a meno che sia stato utilizzato \fB\-\-single\-stream\fP. Questo può far +rompere script incomprensibili che hanno assunto che i dati sporchi finali +vengano ignorati. +. +.SH NOTE +. +.SS "L'output compresso può variare" +L'esatto output compresso prodotto dallo stesso file di input non compresso +può variare tra le versioni delle XZ Utils, anche se le opzioni di +compressione sono le stesse. Questo perché il codificatore può essere stato +migliorato (compressione più veloce o migliore) senza influire sul formato +del file. L'output può variare anche tra diverse build della stessa versione +delle XZ Utils, se vengono utilizzate opzioni di build differenti. +.PP +Quanto sopra significa che una volta che \fB\-\-rsyncable\fP è stato +implementato, i file risultanti non saranno necessariamente rsync\-abili a +meno che sia i vecchi che i nuovi file non siano stati compressi con la +stessa versione di xz. Questo problema può essere risolto se una parte +dell'implementazione del codificatore viene congelata per mantenere stabile +l'output rsync\-abile tra le versioni di xz. +. +.SS "Abilita i decompressori .xz" +Le implementazioni dei decompressori \fB.xz\fP embedded, come XZ Embedded, non +necessariamente supportano file creati con tipi di integrità \fICONTROLLO\fP +diversi da \fBnone\fP e \fBcrc32\fP. Dal momento che il valore predefinito è +\fB\-\-check=crc64\fP, occorre specificare \fB\-\-check=none\fP o \fB\-\-check=crc32\fP +quando si creano file per sistemi embedded. +.PP +Al di fuori dei sistemi embedded, tutti i decompressori in formato \fB.xz\fP +supportano tutti i tipi di \fICONTROLLO\fP, o almeno sono in grado di +decomprimere il file senza verificare il controllo di integrità se il +particolare \fICONTROLLO\fP non è supportato. +.PP +XZ Embedded supporta i filtri BCJ, ma solo con offset iniziale predefinito. +. +.SH ESEMPI +. +.SS "Informazioni di base" +Comprime il file \fIfoo\fP in \fIfoo.xz\fP utilizzando il livello di compressione +predefinito (\fB\-6\fP) e rimuove \fIfoo\fP se la compressione ha esito positivo: +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +Decomprime \fIbar.xz\fP in \fIbar\fP e non rimuove \fIbar.xz\fP anche se la +decompressione ha successo: +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +Crea \fIbaz.tar.xz\fP con il preset \fB\-4e\fP (\fB\-4 \-\-extreme\fP), che è più lenta +della predefinita \fB\-6\fP, ma ha bisogno di meno memoria per la compressione e +decompressione (48\ MiB e 5\ MiB, rispettivamente): +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +Una combinazione di file compressi e non compressi può essere decompressa +sullo output standard con un singolo comando: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "Compressione parallela di più file" +Su GNU e *BSD, \fBfind\fP(1) e \fBxargs\fP(1) possono essere usati per +parallelizzare la compressione di più file: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +L'opzione \fB\-p\fP di \fBxargs\fP(1) imposta il numero di processi \fBxz\fP +paralleli. Il valore migliore per l'opzione \fB\-n\fP dipende dal numero di file +da comprimere. Se sono presenti solo un paio di file, il valore dovrebbe +probabilmente essere 1; con decine di migliaia di file, 100 o anche di più +può essere appropriato per ridurre il numero di processi \fBxz\fP che +\fBxargs\fP(1) alla fine creerà. +.PP +L'opzione \fB\-T1\fP per \fBxz\fP serve a forzare la modalità a thread singola, +perché \fBxargs\fP (1) viene utilizzato per controllare la quantità di +parallelizzazione. +. +.SS "Modalità robot" +Calcola quanti byte sono stati salvati in totale dopo la compressione di più +file: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +Uno script potrebbe voler sapere se si sta utilizzando una versione di \fBxz\fP +sufficientemente recente. Il seguente script \fBsh\fP(1) controlla che il +numero di versione dello strumento \fBxz\fP sia almeno 5.0.0. Questo metodo è +compatibile con le vecchie versioni beta, che non supportavano l'opzione +\fB\-\-robot\fP: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Your xz is too old." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +Imposta un limite di utilizzo della memoria per la decompressione +utilizzando \fBXZ_OPT\fP, ma se è già stato impostato un limite, non lo +aumenta: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "Catene di filtri di compressione personalizzate" +L'uso più semplice delle catene di filtri personalizzate è la +personalizzazione di un preset di LZMA2. Questo può essere utile, perché i +preset coprono solamente un sottoinsieme di tutte le combinazioni di +impostazioni di compressione potenzialmente utili. +.PP +Le colonne CompCPU delle tabelle dalle descrizioni delle opzioni \fB\-0\fP +\&... \fB\-9\fP e \fB\-\-extreme\fP sono utili quando si personalizzano i preset di +LZMA2. Di seguito sono riportate le parti rilevanti raccolte da queste due +tabelle: +.RS +.PP +.TS +tab(;); +c c +n n. +Livello preimpostato;CompCPU +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +Se si sa che un file richiede un dizionario piuttosto grande (ad esempio, +32\ MiB) per essere compresso bene, ma si desidera comprimerlo più +velocemente di quanto farebbe \fBxz \-8\fP, è possibile modificare un preset con +un basso valore CompCPU (ad esempio, 1) per utilizzare un dizionario più +grande: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +Con alcuni file, il comando sopra potrebbe essere più veloce di \fBxz \-6\fP e +la compressione significativamente migliore. Tuttavia, si deve sottolineare +che solo alcuni file traggono beneficio da un dizionario grande e mantengono +basso il valore di CompCPU. La situazione più ovvia in cui un dizionario +grande può aiutare molto è un archivio contenente file molto simili di +almeno un paio di megabyte ciascuno. La dimensione del dizionario deve +essere significativamente più grande di ogni singolo file per permettere a +LZMA2 di trarre pieno vantaggio dalle somiglianze tra file consecutivi. +.PP +Se l'utilizzo molto elevato della memoria del compressore e del +decompressore è accettabile, e il file da comprimere è almeno di diverse +centinaia di megabyte, potrebbe essere utile utilizzare un dizionario ancora +più grande dei 64 MiB che \fBxz \-9\fP utilizzerebbe: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +L'uso di \fB\-vv\fP (\fB\-\-verbose \-\-verbose\fP) come nell'esempio precedente può +essere utile per vedere i requisiti di memoria del compressore e del +decompressore. Tenere presente che l'utilizzo di un dizionario più grande +della dimensione del file non compresso è uno spreco di memoria, quindi il +comando precedente non è utile per i file di piccole dimensioni. +.PP +A volte il tempo di compressione non importa, ma l'utilizzo di memoria del +decompressore deve essere tenuta bassa, per esempio, per permettere di +decomprimere il file in un sistema embedded. Il comando seguente usa \fB\-6e\fP +(\fB\-6 \-\-extreme\fP) come base e imposta il dizionario a soli 64\ KiB. Il file +risultante può essere decompresso con XZ Embedded (ecco perché c'è +\fB\-\-check=crc32\fP) usando circa 100\ KiB di memoria. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +Se si desidera spremere il maggior numero possibile di byte, a volte può +essere utile regolare il numero di bit di contesto letterale (\fIlc\fP) e il +numero di bit di posizione (\fIpb\fP). Anche la regolazione del numero di bit +di posizione letterale (\fIlp\fP) potrebbe essere d'aiuto, ma di solito \fIlc\fP e +\fIpb\fP sono più importanti. Per esempio, un archivio di codici sorgente +contiene principalmente testo US\-ASCII, quindi qualcosa come il seguente +potrebbe produrre un file leggermente (0,1\ %) più piccolo di \fBxz \-6e\fP +(provare anche senza \fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar\fR +.fi +.RE +.PP +Usare un altro filtro insieme a LZMA2 può migliorare la compressione per +alcuni tipi di file. Ad esempio, per comprimere una libreria condivisa +x86\-32 o x86\-64 usare il filtro BCJ: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +Si noti che l'ordine delle opzioni di filtro è significativo. Se viene +specificato \fB\-\-x86\fP dopo \fB\-\-lzma2\fP, \fBxz\fP darà un errore, perché non può +esserci alcun filtro dopo LZMA2 e anche perché il filtro BCJ x86 non può +essere utilizzato come ultimo filtro della catena. +.PP +Il filtro Delta insieme con LZMA2 può dare buoni risultati sulle immagini +bitmap. Di solito dovrebbe battere il PNG, il quale ha alcuni filtri più +avanzati rispetto al semplice delta ma utilizza Deflate per la compressione +effettiva. +.PP +L'immagine deve essere salvata in un formato non compresso, ad esempio un +TIFF non compresso. Il parametro distanza del filtro Delta è impostato in +modo che corrisponda al numero di byte per pixel nell'immagine. Per esempio, +un bitmap a 24 bit richiede \fBdist=3\fP, e va anche bene passare \fBpb=0\fP a +LZMA2 per adattarsi all'allineamento a tre byte: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +Se più immagini sono state inserite in un singolo archivio (ad esempio, +\&\fB.tar\fP), il filtro Delta funzionerà anche su questo purché tutte le +immagini abbiano lo stesso numero di byte per pixel. +. +.SH "VEDERE ANCHE" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ Utils: +.br +XZ Embedded: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/it/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/it/xzdec.1 new file mode 100644 index 000000000..e3ff6ec04 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/it/xzdec.1 @@ -0,0 +1,88 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Italian translations for xz-man package +.\" Luca Vercelli , 2024-2025 +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 08/04/2024 Tukaani "XZ Utils" +.SH NOME +xzdec, lzmadec \- Piccoli compressori .xz e .lzma +.SH SINOSSI +\fBxzdec\fP [\fIOPZIONE...\fP] [\fIFILE...\fP] +.br +\fBlzmadec\fP [\fIOPZIONE...\fP] [\fIFILE...\fP] +.SH DESCRIZIONE +\fBxzdec\fP è uno strumento di sola decompressione basato su liblzma per i file +\&\fB.xz\fP (e solo \fB.xz\fP). \fBxzdec\fP è destinato a funzionare come sostituto +drop\-in di \fBxz\fP (1) nelle situazioni più comuni in cui è stato scritto uno +script che utilizza \fBxz \-\-decompress \-\-stdout\fP (e possibilmente alcune +altre opzioni di uso comune) per decomprimere i file \fB.xz\fP. \fBlzmadec\fP è +identico a \fBxzdec\fP tranne nel fatto che supporta file \fB.lzma\fP invece di +\&\fB.xz\fP. +.PP +Per ridurre la dimensione dell'eseguibile, \fBxzdec\fP non supporta né il +multi\-thread né la localizzazione, e non legge le opzioni dalle variabili di +ambiente \fBXZ_DEFAULTS\fP e \fBXZ_OPT\fP. \fBxzdec\fP non supporta la +visualizzazione delle informazioni di avanzamento: inviare \fBSIGINFO\fP a +\fBxzdec\fP non fa nulla mentre inviare \fBSIGUSR1\fP termina il processo anziché +mostrare le informazioni di avanzamento. +.SH OPZIONI +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +Ignorato per compatibilità con \fBxz\fP(1). \fBxzdec\fP supporta solo la +decompressione. +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ignorato per compatibilità con \fBxz\fP(1). \fBxzdec\fP non crea né rimuove mai +file. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Ignorato per compatibilità con \fBxz\fP(1). \fBxzdec\fP scrive sempre i dati +decompressi sullo standard output. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Specificare questa opzione una sola volta non ha effetto, poiché \fBxzdec\fP +non visualizza mai alcun avvertimento né avviso. Specificare questa opzione +due volte per eliminare gli errori. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Ignorato per compatibilità con \fBxz\fP(1). \fBxzdec\fP non utilizza mai il codice +di uscita 2. +.TP +\fB\-h\fP, \fB\-\-help\fP +Mostra un messaggio di aiuto e termina con successo. +.TP +\fB\-V\fP, \fB\-\-version\fP +Mostra il numero di versione di \fBxzdec\fP e liblzma. +.SH "CODICE DI USCITA" +.TP +\fB0\fP +Andava tutto bene. +.TP +\fB1\fP +È avvenuto un errore. +.PP +\fBxzdec\fP non ha alcun messaggio di avvertimento come \fBxz\fP (1), quindi lo +stato di uscita 2 non viene utilizzato da \fBxzdec\fP. +.SH NOTE +Utilizzare \fBxz\fP(1) al posto di \fBxzdec\fP o \fBlzmadec\fP per l'utilizzo +normale abituale. \fBxzdec\fP e \fBlzmadec\fP sono pensati solo per situazioni in +cui sia importante avere un decompressore più piccolo rispetto a quello con +funzionalità complete \fBxz\fP(1). +.PP +\fBxzdec\fP e \fBlzmadec\fP non sono veramente così piccoli. La dimensione può +essere ridotta ulteriormente eliminando delle funzionalità da liblzma al +momento della compilazione, ma questo di solito non dovrebbe essere fatto +per gli eseguibili distribuiti nelle tipiche distribuzioni di sistemi +operativi non embedded. Se c'è bisogno di un decompressore \fB.xz\fP veramente +piccolo, si consideri l'utilizzo di XZ Embedded. +.SH "VEDERE ANCHE" +\fBxz\fP(1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/it/xzdiff.1 b/cpp/third_party/xz-5.8.3/po4a/man/it/xzdiff.1 new file mode 100644 index 000000000..dc0d9758b --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/it/xzdiff.1 @@ -0,0 +1,55 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Italian translations for xz-man package +.\" Luca Vercelli , 2024-2025 +.\" +.\" (Note that this file is not based on gzip's zdiff.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDIFF 1 06/03/2025 Tukaani "XZ Utils" +.SH NOME +xzcmp, xzdiff, lzcmp, lzdiff \- confronto tra file compressi +. +.SH SINOSSI +\fBxzcmp\fP [\fIOPZIONE...\fP] \fIFILE1\fP [\fIFILE2\fP] +.br +\fBxzdiff\fP \&... +.br +\fBlzcmp\fP \&... (DEPRECATO) +.br +\fBlzdiff\fP \&... (DEPRECATO) +. +.SH DESCRIZIONE +\fBxzcmp\fP e \fBxzdiff\fP confrontano i contenuti non compressi di due file. I +dati non compressi e le opzioni sono passate a \fBcmp\fP(1) o \fBdiff\fP(1) a +meno che sia specificato \fB\-\-help\fP o \fB\-\-version\fP. +.PP +Se sono indicati sia \fIFILE1\fP che \fIFILE2\fP, essi possono essere file non +compressi oppure file nei formati che \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), +\fBlzop\fP(1), \fBzstd\fP(1), o \fBlz4\fP(1) possono decomprimere. I comandi di +decompressione necessari sono dedotti dai suffissi dei nomi dei file +\fIFILE1\fP e \fIFILE2\fP. Un file con un suffisso non riconosciuto viene +considerato o non compresso oppure in un formato che \fBxz\fP(1) può +decomprimere. +.PP +Se viene fornito un solo nome di file, \fIFILE1\fP deve avere un suffisso di un +formato di compressione supportato e il nome di \fIFILE2\fP si assume che sia +\fIFILE1\fP senza il suffisso del formato di compressione. +.PP +I comandi \fBlzcmp\fP, e \fBlzdiff\fP sono forniti per retrocompatibilità con le +LZMA Utils. Sono deprecati e saranno rimosso in una versione futura. +. +.SH "CODICE DI USCITA" +Se avviene un errore nella decompressione, lo stato di uscita è +\fB2\fP. Altrimenti viene usato lo stato di uscita di \fBcmp\fP(1) o \fBdiff\fP(1) +. +.SH "VEDERE ANCHE" +\fBcmp\fP(1), \fBdiff\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), +\fBzstd\fP(1), \fBlz4\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/it/xzgrep.1 b/cpp/third_party/xz-5.8.3/po4a/man/it/xzgrep.1 new file mode 100644 index 000000000..778054dc4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/it/xzgrep.1 @@ -0,0 +1,94 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Italian translations for xz-man package +.\" Luca Vercelli , 2024-2025 +.\" +.\" (Note that this file is not based on gzip's zgrep.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZGREP 1 06/03/2025 Tukaani "XZ Utils" +.SH NOME +xzgrep \- Cerca pattern in file potenzialmente compressi +. +.SH SINOSSI +\fBxzgrep\fP [\fIOPZIONE...\fP] [\fILISTA_PATTERN\fP] [\fIFILE...\fP] +.br +\fBxzegrep\fP \&... +.br +\fBxzfgrep\fP \&... +.br +\fBlzgrep\fP \&... (DEPRECATO) +.br +\fBlzegrep\fP \&... (DEPRECATO) +.br +\fBlzfgrep\fP \&... (DEPRECATO) +. +.SH DESCRIZIONE +\fBxzgrep\fP invoca \fBgrep\fP(1) sui contenuti non compressi dei file. I formati +dei \fIFILE\fP sono dedotti dai suffissi dei nomi dei file. Sarà decompresso +qualsiasi file con un suffisso supportato da \fBxz\fP(1), \fBgzip\fP(1), +\fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), o \fBlz4\fP(1); tutti gli altri file +saranno considerati non compressi. +.PP +Se non sono specificati \fIFILE\fP, o se \fIFILE\fP è \fB\-\fP, viene letto lo +standard input. Quando si legge da standard input vengono decompressi +solamente i file supportati da \fBxz\fP(1). Gli altri file sono considerati già +non compressi. +.PP +Sono supportate la maggior parte delle \fIOPZIONI\fP di \fBgrep\fP(1). Tuttavia, +le opzioni seguenti non sono supportate: +.IP "" 4 +\fB\-r\fP, \fB\-\-recursive\fP +.IP "" 4 +\fB\-R\fP, \fB\-\-dereference\-recursive\fP +.IP "" 4 +\fB\-d\fP, \fB\-\-directories=\fP\fIAZIONE\fP +.IP "" 4 +\fB\-Z\fP, \fB\-\-null\fP +.IP "" 4 +\fB\-z\fP, \fB\-\-null\-data\fP +.IP "" 4 +\fB\-\-include=\fP\fIGLOB\fP +.IP "" 4 +\fB\-\-exclude=\fP\fIGLOB\fP +.IP "" 4 +\fB\-\-exclude\-from=\fP\fIFILE\fP +.IP "" 4 +\fB\-\-exclude\-dir=\fP\fIGLOB\fP +.PP +\fBxzegrep\fP è un alias per \fBxzgrep \-E\fP. \fBxzfgrep\fP è un alias per \fBxzgrep \-F\fP. +.PP +I comandi \fBlzgrep\fP, \fBlzegrep\fP, e \fBlzfgrep\fP sono forniti per +retrocompatibilità con le LZMA Utils. Sono deprecati e saranno rimosso in +una versione futura. +. +.SH "CODICE DI USCITA" +.TP +0 +Almeno una corrispondenza è stata trovata in almeno uno dei file +input. Nessun errore è avvenuto. +.TP +1 +Non sono state trovate corrispondenze in nessuno dei file di input. Non si +sono verificati errori. +.TP +>1 +Sono avvenuti uno o più errori. Non è noto se sono state trovate delle +corrispondenze. +. +.SH AMBIENTE +.TP +\fBGREP\fP +Se \fBGREP\fP è impostato a un valore non vuoto, verrà usato al posto di +\fBgrep\fP, \fBgrep \-E\fP, o \fBgrep \-F\fP. +. +.SH "VEDERE ANCHE" +\fBgrep\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), +\fBlz4\fP(1), \fBzgrep\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/it/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/it/xzless.1 new file mode 100644 index 000000000..03fcb0de8 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/it/xzless.1 @@ -0,0 +1,47 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Italian translations for xz-man package +.\" Luca Vercelli , 2024-2025 +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 06/03/2025 Tukaani "XZ Utils" +.SH NOME +xzless, lzless \- mostra file (testuali) compressi xz o lzma +.SH SINOSSI +\fBxzless\fP [\fIFILE\fP...] +.br +\fBlzless\fP [\fIFILE\fP...] (DEPRECATO) +.SH DESCRIZIONE +\fBxzless\fP è un filtro che visualizza testo da file compressi a un +terminale. I file supportati da \fBxz\fP(1) vengono decompressi; gli altri +file sono considerati già non compressi. Se non viene dato alcun \fIFILE\fP, +\fBxzless\fP legge dallo standard input. +.PP +\fBxzless\fP usa \fBless\fP(1) per mostrare il suo output. A differenza di +\fBxzmore\fP, la scelta del paginatore non può essere modificata impostando una +variabile d'ambiente. I comandi si basano sia su \fBmore\fP (1) che su \fBvi\fP +(1) e consentono il movimento in avanti e all'indietro e la ricerca. Per +ulteriori informazioni vedere il manuale di \fBless\fP(1). +.PP +Il comando chiamato \fBlzless\fP è fornito per retrocompatibilità con le LZMA +Utils. È deprecato e sarà rimosso in una versione futura. +.SH AMBIENTE +.TP +\fBLESSMETACHARS\fP +Un elenco di caratteri speciali per la shell. Impostato da \fBxzless\fP a meno +che sia già impostato nell'ambiente. +.TP +\fBLESSOPEN\fP +Valorizzare con una riga di comando per lanciare il decompressore \fBxz\fP(1) +per preprocessare i file input per \fBless\fP(1). +.SH "VEDERE ANCHE" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/it/xzmore.1 b/cpp/third_party/xz-5.8.3/po4a/man/it/xzmore.1 new file mode 100644 index 000000000..60fca9160 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/it/xzmore.1 @@ -0,0 +1,50 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Italian translations for xz-man package +.\" Luca Vercelli , 2024-2025 +.\" +.\" (Note that this file is based on xzless.1 instead of gzip's zmore.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZMORE 1 06/03/2025 Tukaani "XZ Utils" +.SH NOME +xzmore, lzmore \- mostra file (testuali) compressi xz o lzma +. +.SH SINOSSI +\fBxzmore\fP [\fIFILE\fP...] +.br +\fBlzmore\fP [\fIFILE\fP...] (DEPRECATO) +. +.SH DESCRIZIONE +\fBxzmore\fP visualizza il testo da file non compressi a un terminale usando +\fBmore\fP(1). I file supportati da \fBxz\fP(1) vengono decompressi; gli altri +file sono considerati non compressi. Se non viene dato alcun \fIFILE\fP, +\fBxzmore\fP legge dallo standard input. Si veda il manuale di \fBmore\fP(1) per i +comandi da tastiera. +.PP +Si noti che lo scorrimento all'indietro potrebbe non essere possibile a +seconda dell'implementazione di \fBmore\fP(1). Ciò è dovuto al fatto che +\fBxzmore\fP utilizza una pipe per passare i dati decompressi a +\fBmore\fP(1). \fBxzless\fP(1) utilizza \fBless\fP(1) che fornisce funzionalità più +avanzate. +.PP +Il comando \fBlzmore\fP è fornito per retrocompatibilità con le LZMA Utils. È +deprecato e sarà rimosso in una versione futura. +. +.SH AMBIENTE +.TP +.\" TRANSLATORS: Don't translate the uppercase PAGER. +.\" It is a name of an environment variable. +\fBPAGER\fP +Se \fBPAGER\fP è impostato, il suo valore è usato come paginatore al posto di +\fBmore\fP(1). +. +.SH "VEDERE ANCHE" +\fBmore\fP(1), \fBxz\fP(1), \fBxzless\fP(1), \fBzmore\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ko/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/ko/lzmainfo.1 new file mode 100644 index 000000000..718ad0a7c --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ko/lzmainfo.1 @@ -0,0 +1,38 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Korean translation for the xz-man +.\" Seong-ho Cho , 2023, 2024. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 2013\-06\-30 Tukaani "XZ 유틸리티" +.SH ì´ë¦„ +lzmainfo \- .lzma íŒŒì¼ í—¤ë”ì— ë“¤ì–´ìžˆëŠ” 정보를 ë³´ì—¬ì¤ë‹ˆë‹¤ +.SH 요약 +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fI<파ì¼>...\fP] +.SH 설명 +\fBlzmainfo\fP 는 \fB.lzma\fP íŒŒì¼ í—¤ë”ì— ë“¤ì–´ìžˆëŠ” 정보를 ë³´ì—¬ì¤ë‹ˆë‹¤. 지정 \fI<파ì¼>\fPì—서 13ë°”ì´íŠ¸ë¥¼ +ìš°ì„  ì½ì–´ í—¤ë”를 디코딩한 후, ê°€ë… í˜•ì‹ìœ¼ë¡œ 표준 ì¶œë ¥ì— ë³´ì—¬ì¤ë‹ˆë‹¤. \fI<파ì¼>\fPì„ ì§€ì •í•˜ì§€ 않거나 +\fI<파ì¼>\fP ê°’ì´ \fI\-\fP ì´ë©´ 표준 ìž…ë ¥ì„ ì½ìŠµë‹ˆë‹¤. +.PP +보통 대부분 관심있는 정보는 ì••ì¶• í•´ì œ 용량과 딕서너리 í¬ê¸°ìž…니다. ì••ì¶• í•´ì œ ìš©ëŸ‰ì˜ ê²½ìš° 파ì¼ì´ 비스트림 \fB.lzma\fP í˜•ì‹ ê³„ì—´ì¸ +경우ì—ë§Œ 나타납니다. íŒŒì¼ ì••ì¶• í•´ì œ í•„ìš” 메모리 ìš©ëŸ‰ì€ ìˆ˜ì‹­ 킬로바ì´íŠ¸ì— ë”•ì…”ë„ˆë¦¬ í¬ê¸°ë¥¼ 합친 값입니다. +.PP +\fBlzmainfo\fP 는 LZMA 유틸리티 하위 í˜¸í™˜ì„±ì„ ëª©ì ìœ¼ë¡œ XZ ìœ í‹¸ë¦¬í‹°ì— ê¸°ë³¸ìœ¼ë¡œ 들어있습니다. +.SH "종료 ìƒíƒœ" +.TP +\fB0\fP +모든 ìƒíƒœ 양호. +.TP +\fB1\fP +오류 ë°œìƒ. +.SH 버그 +\fBlzmainfo\fP í”„ë¡œê·¸ëž¨ì€ \fBMiB\fP (2^20 ë°”ì´íЏ) 용량 단위ì¸ë° (실제로) \fBMB\fP를 사용합니다. LZMA 유틸리티 +출력 호환 유지가 목ì ìž…니다. +.SH "추가 참조" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ko/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/ko/xz.1 new file mode 100644 index 000000000..631a9a7cc --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ko/xz.1 @@ -0,0 +1,1585 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Korean translation for the xz-man +.\" Seong-ho Cho , 2023, 2024. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 2025\-03\-08 Tukaani "XZ 유틸리티" +. +.SH ì´ë¦„ +xz, unxz, xzcat, lzma, unlzma, lzcat \- .xz 파ì¼ê³¼ .lzma 파ì¼ì„ ì••ì¶• ë˜ëŠ” ì••ì¶• 해제합니다 +. +.SH 요약 +\fBxz\fP [\fI<옵션>...\fP] [\fI<파ì¼>...\fP] +. +.SH "명령 별칭" +\fBunxz\fP ëª…ë ¹ì€ \fBxz \-\-decompress\fP 명령과 ë™ì¼í•©ë‹ˆë‹¤. +.br +\fBxzcat\fP ëª…ë ¹ì€ \fBxz \-\-decompress \-\-stdout\fP 명령과 ë™ì¼í•©ë‹ˆë‹¤. +.br +\fBlzma\fP ëª…ë ¹ì€ \fBxz \-\-format=lzma\fP 명령과 ë™ì¼í•©ë‹ˆë‹¤. +.br +\fBunlzma\fP ëª…ë ¹ì€ \fBxz \-\-format=lzma \-\-decompress\fP 명령과 ë™ì¼í•©ë‹ˆë‹¤. +.br +\fBlzcat\fP ëª…ë ¹ì€ \fBxz \-\-format=lzma \-\-decompress \-\-stdout\fP 명령과 ë™ì¼í•©ë‹ˆë‹¤. +.PP +íŒŒì¼ ì••ì¶•ì„ í•´ì œí•´ì•¼ 하는 ì…¸ 스í¬ë¦½íŠ¸ë¥¼ 작성할 때, \fBunxz\fP 와 \fBxzcat\fP ì´ë¦„ 대신 \fBxz\fP 명령과 ì ì ˆí•œ ì¸ìž +ê°’(\fBxz \-d\fP ë˜ëŠ” \fBxz \-dc\fP)ì˜ ì‚¬ìš©ì„ ì¶”ì²œë“œë¦½ë‹ˆë‹¤. +. +.SH 설명 +\fBxz\fP는 \fBgzip\fP(1) ê³¼ \fBbzip2\fP(1) ê³¼ 비슷한 명령행 ë¬¸ë²•ì„ ì§€ë‹Œ 범용 ë°ì´í„° ì••ì¶• ë„구입니다. ìžì²´ íŒŒì¼ +형ì‹ì€ \fB.xz\fP 형ì‹ì´ë‚˜, LZMA 유틸리티ì—서 사용하는 예전 \fB.lzma\fP 형ì‹ê³¼ í˜•ì‹ í—¤ë”ê°€ 없는 RAW ì••ì¶• ìŠ¤íŠ¸ë¦¼ë„ +ì§€ì›í•©ë‹ˆë‹¤. 게다가, \fBlzip\fPì—서 활용하는 \fB.lz\fP í˜•ì‹ ì••ì¶• í•´ì œë„ ì§€ì›í•©ë‹ˆë‹¤. +.PP +ê° \fI파ì¼\fP ì— ëŒ€í•œ \fBxz\fP ì••ì¶• ë˜ëŠ” ì••ì¶• 해제는 ì„ íƒ ë™ìž‘ ëª¨ë“œì— ë”°ë¦…ë‹ˆë‹¤. \fI<파ì¼>\fP ê°’ì´ ì£¼ì–´ì¡Œê±°ë‚˜ +\fI<파ì¼>\fP ê°’ì´ \fB\-\fPì´ë©´, \fBxz\fP 명령ì—서 표준 ìž…ë ¥ì„ ì½ê³  처리한 ë°ì´í„°ë¥¼ 표준 ì¶œë ¥ì— ê¸°ë¡í•©ë‹ˆë‹¤. +\fBxz\fP ì—서는 터미ë„ì—서 활용할 경우 ì••ì¶• ë°ì´í„°ë¥¼ 표준 압축으로 기ë¡í•˜ëŠ” ë™ìž‘ì„ ê±°ì ˆ(오류를 출력하고 \fI<파ì¼>\fPì„ +건너뜀)합니다. ì´ì™€ 비슷하게, \fBxz\fP 유틸리티를 터미ë„ì—서 실행하면 표준 ìž…ë ¥ì˜ ì••ì¶• ë°ì´í„° ì½ê¸°ë¥¼ 거절합니다. +.PP +\fB\-\-stdout\fP ì„ ì§€ì •í•˜ì§€ 않는 한, \fB\-\fPê°€ 아닌 \fI<파ì¼>\fPì„ ì›ë³¸ \fI<파ì¼>\fP ì´ë¦„ì—서 +가져온 새 íŒŒì¼ ì´ë¦„으로 기ë¡í•©ë‹ˆë‹¤: +.IP \(bu 3 +ì••ì¶•í•  때, ëŒ€ìƒ íŒŒì¼ í˜•ì‹ì˜ 접미사(\fB.xz\fP or \fB.lzma\fP) 는 ì›ë³¸ íŒŒì¼ ì´ë¦„ ë’¤ì— ë¶™ì–´ ëŒ€ìƒ íŒŒì¼ì´ë¦„ì´ ë©ë‹ˆë‹¤. +.IP \(bu 3 +ì••ì¶• 해제할 때, \fB.xz\fP, \fB.lzma\fP, \fB.lz\fP 접미사를 íŒŒì¼ ì´ë¦„ì—서 제거하고 ëŒ€ìƒ íŒŒì¼ ì´ë¦„ì„ ì•Œì•„ëƒ…ë‹ˆë‹¤. +\fBxz\fPì—서는 \fB.txz\fP, \fB.tlz\fP ì ‘ë¯¸ì‚¬ë„ ì¸ì‹í•˜ë©°, \fB.tar\fP 접미사로 치환합니다. +.PP +ëŒ€ìƒ íŒŒì¼ì´ ì´ë¯¸ 있으면, 오류를 나타내고 \fI<파ì¼>\fPì„ ê±´ë„ˆëœë‹ˆë‹¤. +.PP +표준 출력으로 기ë¡í•˜ê¸° ì „ì—는, \fBxz\fP는 경고를 나타내며, ë‹¤ìŒ ì¡°ê±´ì— ë§Œì¡±í•  경우 \fI<파ì¼>\fPì„ ê±´ë„ˆëœë‹ˆë‹¤: +.IP \(bu 3 +\fI<파ì¼>\fPì´ ì¼ë°˜ 파ì¼ì´ ì•„ë‹ ë•Œ. 심볼릭 ë§í¬ëŠ” ë”°ë¼ê°€ì§€ 않기ì—, ì¼ë°˜ 파ì¼ë¡œ 간주하지 않습니다. +.IP \(bu 3 +\fI<파ì¼>\fPì´ í•˜ë‚˜ ì´ìƒì˜ 하드 ë§í¬ì¼ ë–„. +.IP \(bu 3 +\fI<파ì¼>\fPì— setuid, setgid, ëˆì ì´ 비트 ì§‘í•©ì´ ë¶™ì–´ìžˆì„ ë–„. +.IP \(bu 3 +ë™ìž‘ 모드를 압축으로 설정하고, \fI<파ì¼>\fPì€ ëŒ€ìƒ íŒŒì¼ í˜•ì‹ì˜ 접미사를 ì´ë¯¸ ë¶™ì˜€ì„ ë•Œ(\fB.xz\fP 형ì‹ìœ¼ë¡œ 압축하면 +\&\fB.xz\fP ë˜ëŠ” \fB.txz\fP, \fB.lzma\fP 형ì‹ìœ¼ë¡œ 압축하면 \fB.lzma\fP ë˜ëŠ” \fB.tlz\fP). +.IP \(bu 3 +ë™ìž‘ 모드를 ì••ì¶• 해제로 설정하고, \fI<파ì¼>\fPì— ì§€ì› íŒŒì¼ í˜•ì‹ ì ‘ë¯¸ì‚¬(\fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, +\&\fB.tlz\fP, \fB.lz\fP)를 ë¶™ì´ì§€ ì•Šì•˜ì„ ë•Œ. +.PP +\fI<파ì¼>\fP ì˜ ì••ì¶• ë˜ëŠ” ì••ì¶• 해제를 성공하고 나면, \fBxz\fP는 소유ìž, 소유그룹, 권한, ì ‘ê·¼ 시ê°, 수정 ì‹œê° +정보를 ì›ë³¸ \fI<파ì¼>\fPì—서 ëŒ€ìƒ íŒŒì¼ë¡œ 그대로 복사합니다. 그룹 ì •ë³´ ë³µì‚¬ì— ì‹¤íŒ¨í•˜ë©´, ê¶Œí•œì„ ìˆ˜ì •í•˜ì—¬ ì›ë³¸ +\fI<파ì¼>\fPì— ì ‘ê·¼ ê¶Œí•œì´ ì—†ëŠ” 사용ìžê°€ ëŒ€ìƒ íŒŒì¼ë¡œ 접근하지 못하게 합니다. \fBxz\fP는 ì•„ì§ ì ‘ê·¼ 제어 목ë¡ì´ë‚˜ +확장 ì†ì„± ë“±ì˜ ê¸°íƒ€ 메타ë°ì´í„°ë¥¼ 복사하는 ê¸°ëŠ¥ì€ ì§€ì›í•˜ì§€ 않습니다. +.PP +ëŒ€ìƒ íŒŒì¼ì„ 온전히 ë‹«ê³  나면, \fB\-\-keep\fP ì˜µì…˜ì„ ì§€ì›í•˜ì§€ ì•Šì•˜ì„ ê²½ìš° ì›ë³¸ \fI<파ì¼>\fPì„ ì œê±°í•©ë‹ˆë‹¤. ì›ë³¸ +\fI<파ì¼>\fPì€ ì¶œë ¥ì„ í‘œì¤€ 출력으로 기ë¡í–ˆê±°ë‚˜ 오류가 ë°œìƒí–ˆì„ 경우 제거하지 않습니다. +.PP +\fBxz\fP í”„ë¡œì„¸ìŠ¤ì— \fBSIGINFO\fP ì‹œê·¸ë„ ë˜ëŠ” \fBSIGUSR1\fP 시그ë„ì„ ë³´ë‚´ë©´ 표준 출력으로 ì§„í–‰ 정보를 출력합니다. 표준 +오류가 터미ë„ì¼ ê²½ìš°ì¼ ê²½ìš°ì—ë§Œ 제한하며 \fB\-\-verbose\fP ì˜µì…˜ì„ ì§€ì •í•˜ë©´ ì§„í–‰ í‘œì‹œì¤„ì„ ìžë™ìœ¼ë¡œ 나타냅니다. +. +.SS "메모리 사용" +\fBxz\fP 메모리 ì‚¬ìš©ì€ ìˆ˜ë°± 킬로바ì´íŠ¸ë¡œ 시작하여 수 기가바ì´íŠ¸ê¹Œì§€ ì••ì¶• ì„¤ì •ì— ë”°ë¼ ë‹¤ë¦…ë‹ˆë‹¤. ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì´ í•„ìš”ë¡œ 하는 +메모리 ê³µê°„ì„ ê²°ì •í•˜ëŠ” íŒŒì¼ ì••ì¶•ì‹œì— ì„¤ì • ê°’ì„ í™œìš©í•©ë‹ˆë‹¤. 보통 ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì€ íŒŒì¼ì„ 만들 때, ì••ì¶• 프로그램 메모리 ì‚¬ìš©ëŸ‰ì˜ +5% ì—서 20% ì •ë„ í•„ìš”í•©ë‹ˆë‹¤. 예를 들면, \fBxz \-9\fP로 압축한 íŒŒì¼ ì••ì¶• 해제시 현재 65MiB 메모리 ìš©ëŸ‰ì´ í•„ìš”í•©ë‹ˆë‹¤. +여전하게ë„, ì••ì¶• 해제시 수 기가 ë°”ì´íŠ¸ì˜ ë©”ëª¨ë¦¬ê°€ 필요한 \fB.xz\fP 파ì¼ì—ë„ ê°€ëŠ¥í•œ ì´ì•¼ê¸°ìž…니다. +.PP +특히 ì´ì „ 시스템 사용ìžì˜ 경우 메모리 ì‚¬ìš©ëŸ‰ì´ ì—„ì²­ë‚˜ê²Œ 늘어나는 ì ì— ì§œì¦ì´ ë‚  수 있습니다. ì´ëŸ° 불편한 ìƒí™©ì„ 피하기 위해, +\fBxz\fPì— ê¸°ë³¸ì ìœ¼ë¡œ 비활성 ìƒíƒœì¸ 내장 메모리 사용 제한 ê¸°ëŠ¥ì„ ë„£ì—ˆìŠµë‹ˆë‹¤. ì¼ë¶€ ìš´ì˜ì²´ì œì—서 처리 중 메모리 ì‚¬ìš©ì„ ì œí•œí•˜ëŠ” +ìˆ˜ë‹¨ì„ ì œê³µí•˜ê¸´ 하지만, ì—¬ê¸°ì— ì˜ì§€í•˜ê¸°ì—는 충분히 유연하지 않습니다(예를 들면, \fBulimit\fP(1)ì„ ì‚¬ìš©í•˜ë©´ ê°€ìƒ ë©”ëª¨ë¦¬ë¥¼ +제한하여 \fBmmap\fP(2)ì„ ë¨¹í†µìœ¼ë¡œ 만듭니다). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +메모리 사용 제한 ê¸°ëŠ¥ì€ \fB\-\-memlimit=\fP\fI<제한용량>\fP 명령행 옵션으로 사용할 수 있습니다. 종종 +\fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP와 ê°™ì´ \fBXZ_DEFAULTS\fP 환경 변수를 설정하여 제한 ê¸°ëŠ¥ì„ ì¼œëŠ”ê²Œ ë” +편합니다. \fB\-\-memlimit\-compress=\fP\fI<제한용량>\fP 옵션과 +\fB\-\-memlimit\-decompress=\fP\fI<제한용량>\fP ì˜µì…˜ì„ í™œìš©í•˜ì—¬ ì••ì¶• ë° ì••ì¶• 해제시 별ë„로 한계 ê°’ì„ +설정할 수 있습니다. ì´ ë‘ ê°€ì§€ ì˜µì…˜ì˜ \fBXZ_DEFAULTS\fP 환경 변수 ë°–ì—ì„œì˜ ì‚¬ìš©ì€, \fBxz\fP를 ë‹¨ì¼ ì‹¤í–‰í•  때 ì••ì¶• ë° +ì••ì¶• í•´ì œ ë™ìž‘ì„ ë™ì‹œì— 수행하지 않으며, 앞서 언급한 ë‘가지 ì˜µì…˜ì„ ëª…ë ¹í–‰ì— ìž…ë ¥í•˜ê¸°ì—는 +\fB\-\-memlimit=\fP\fI<제한용량>\fP(ë˜ëŠ” \fB\-M\fP \fI<제한용량>\fP)ì´ ë” ì§§ê¸° ë•Œë¬¸ì— ë³„ë¡œ 쓸모가 +없습니다. +.PP +ì••ì¶• 해제시 메모리 사용 제한 지정 한계를 초과하면, \fBxz\fP 유틸리티ì—서 오류를 나타내며 íŒŒì¼ ì••ì¶• 해제는 실패합니다. ì••ì¶•ì„ +실행할 때 사용 제한 지정 한계를 넘어서면 \fBxz\fPì—서는 설정 ê°’ì„ ì¤„ì—¬ì„œ 어쨌든 한계를 넘지 못하게 +합니다(\fB\-\-format=raw\fP 옵션 ë˜ëŠ” \fB\-\-no\-adjust\fP 옵션 사용시 제외). 설정 한계 ê°’ì´ ì—„ì²­ 작지 ì•Šì€ ì´ìƒ ì´ +ë°©ì‹ëŒ€ë¡œ 처리하면 어쨌든 실패하지 않습니다. 설정 ê°’ì¡°ì •ì€ ì••ì¶• 래벨 사전 설정과 ì¼ì¹˜í•˜ì§€ ì•Šì„ ë•Œ 단계ì ìœ¼ë¡œ 진행하는ë°, ì´ë¥¼í…Œë©´, +\fBxz \-9\fP 명령 ìˆ˜í–‰ì— í•„ìš”í•œ 양보다 한계 ê°’ì´ ì•½ê°„ 작으면, 설정 ê°’ì„ \fBxz \-8\fPì— ëª»ë¯¸ì¹˜ê²Œ 약간 줄여서 진행합니다. +. +.SS ".xz íŒŒì¼ ê²°í•© ë° íŒ¨ë”©" +\&\fB.xz\fP 파ì¼ì„ 있는 그대로 í•©ì¹  수 있습니다. \fBxz\fP는 \fB.xz\fP 파ì¼ì„ ë‹¨ë… íŒŒì¼ì¼ 때 처럼 압축해제합니다. +.PP +ê²°í•© 부분과 마지막 부분 ë’¤ì— íŒ¨ë”©ì„ ì¶”ê°€í•  수 있습니다. íŒ¨ë”©ì€ ë„ ë°”ì´íŠ¸ë¡œ 구성해야 하며 패딩 길ì´ëŠ” 4ë°”ì´íŠ¸ë¡œ 구성해야 합니다. +512 ë°”ì´íЏ 블ë¡ìœ¼ë¡œ íŒŒì¼ í¬ê¸°ë¥¼ ì´ë£¨ëŠ” ë§¤ì²´ì— \fB.xz\fP 파ì¼ì„ ì €ìž¥í–ˆì„ ê²½ìš°ì— ìš”ê¸´í•  수 있습니다. +.PP +\&\fB.lzma\fP íŒŒì¼ ë˜ëŠ” ì›ì‹œ ìŠ¤íŠ¸ë¦¼ì˜ ê²½ìš° ê²°í•©ê³¼ íŒ¨ë”©ì„ í—ˆìš©í•˜ì§€ 않습니다. +. +.SH 옵션 +. +.SS "정수 ì ‘ë‘사와 ë³„ë„ ê°’" +정수 ì¸ìžê°’ì´ í•„ìš”í•œ 대부분 위치ì—서는, í° ì •ìˆ˜ê°’ì„ ë‚˜íƒ€ë‚´ê¸° 쉽게 하ë„ë¡ ì¶”ê°€ 접미사를 ì§€ì›í•©ë‹ˆë‹¤. 정수와 접미사 사ì´ì— ì–´ë–¤ ê³µë°±ì´ +있으면 안ë©ë‹ˆë‹¤. +.TP +\fBKiB\fP +1,024 (2^10) 배수 정수값. \fBKi\fP, \fBk\fP, \fBkB\fP, \fBK\fP, \fBKB\fP 단위를 \fBKiB\fP ë™ì˜ì–´ë¡œ 받아들입니다. +.TP +\fBMiB\fP +1,048,576 (2^20) 배수 정수값. \fBMi\fP, \fBm\fP, \fBM\fP, \fBMB\fP 단위를 \fBMiB\fP ë™ì˜ì–´ë¡œ 받아들입니다. +.TP +\fBGiB\fP +1,073,741,824 (2^30) 배수 정수값. \fBGi\fP, \fBg\fP, \fBG\fP, \fBGB\fP 단위를 \fBGiB\fP ë™ì˜ì–´ë¡œ +받아들입니다. +.PP +특수 ê°’ \fBmax\fP는 옵션ì—서 ì§€ì›í•˜ëŠ” 정수 최대 ê°’ì„ ë‚˜íƒ€ë‚¼ 때 사용할 수 있습니다. +. +.SS "ë™ìž‘ 모드" +여러 ë™ìž‘ 모드를 보여드리겠습니다만, ë§ˆì§€ë§‰ì— ì£¼ì–´ì§„ ë™ìž‘ 모드로 ë™ìž‘합니다. +.TP +\fB\-z\fP, \fB\-\-compress\fP +압축합니다. ì–´ë–¤ ë™ìž‘ 모드 ì˜µì…˜ë„ ì§€ì •í•˜ì§€ 않고 다른 ë™ìž‘ 모드를 ëª…ë ¹í–‰ì— ë”°ë¡œ 지정하지 않았다면 ì´ ë™ìž‘ 모드는 기본입니다(예: +\fBunxz\fP 는 \fB\-\-decompress\fP를 암시). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +ì••ì¶•ì„ ì œëŒ€ë¡œ ëë‚´ê³  나면, 표준 ì¶œë ¥ì— ê¸°ë¡í•˜ê±°ë‚˜ \fB\-\-keep\fP ì˜µì…˜ì„ ì§€ì •í•˜ì§€ 않았다면 ì›ë³¸ 파ì¼ì„ 제거합니다. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +ì••ì¶• 해제입니다. ì••ì¶• 해제를 제대로 ëë‚´ê³  나면, 표준 ì¶œë ¥ì— ê¸°ë¡í•˜ê±°ë‚˜ \fB\-\-keep\fP ì˜µì…˜ì„ ì§€ì •í•˜ì§€ 않았다면 ì›ë³¸ 파ì¼ì„ +제거합니다. +.TP +\fB\-t\fP, \fB\-\-test\fP +ì••ì¶• \fI<파ì¼>\fPì˜ ë¬´ê²°ì„±ì„ ì‹œí—˜í•´ë´…ë‹ˆë‹¤. ì´ ì˜µì…˜ì€ ì••ì¶• í•´ì œ ë°ì´í„°ë¥¼ 표준 출력으로 기ë¡í•˜ëŠ” 대신 버린다는 ì ì„ +제외하고 \fB\-\-decompress \-\-stdout\fPê³¼ ë™ì¼í•©ë‹ˆë‹¤. ì–´ë–¤ 파ì¼ë„ 만들거나 제거하지 않습니다. +.TP +\fB\-l\fP, \fB\-\-list\fP +ì••ì¶• \fI<파ì¼>\fP 정보를 출력합니다. ì••ì¶• í•´ì œ ì¶œë ¥ì„ ë‚´ë³´ë‚´ì§€ 않으며, ì–´ë–¤ 파ì¼ë„ 만들거나 제거하지 않습니다. ì´ +조회 모드ì—서, í”„ë¡œê·¸ëž¨ì€ í‘œì¤€ ìž…ë ¥ ë˜ëŠ” 기타 íƒìƒ‰ 불가능한 ì›ë³¸ì—서 ì••ì¶• ë°ì´í„°ë¥¼ ì½ì„ 수 없습니다. +.IP "" +\fI<파ì¼>\fP 기본 정보를 íŒŒì¼ ë‹¹ 한 줄 씩 기본으로 ë³´ì—¬ì¤ë‹ˆë‹¤. ë” ìžì„¸í•œ 정보를 보려면 \fB\-\-verbose\fP +ì˜µì…˜ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤. ë” ìžì„¸í•œ 정보는 \fB\-\-verbose\fP ì˜µì…˜ì„ ë‘번 사용하면 ë˜ì§€ë§Œ, 추가 정보를 ë” ë§Žì´ ê°€ì ¸ì˜¤ë©´ì„œ íƒìƒ‰ +횟수가 늘어나는 문제로 ì¸í•´ ëŠë ¤ì§ˆ 수 있습니다. 세부 출력 너비는 80 문ìžë¥¼ 초과하며, 예를 들어 ì¶œë ¥ì„ íŒŒì´í•‘한다면, 터미ë„ì´ +충분히 너비가 ë„“ì§€ 못할 경우 \fBless\ \-S\fP ëª…ë ¹ì´ íŽ¸ë¦¬í•  수 있습니다. +.IP "" +정확한 ì¶œë ¥ì€ \fBxz\fP 버전과 다른 ë¡œìº˜ì— ë”°ë¼ ë°”ë€” 수 있습니다. 기계 íŒë…ìš© 출력시 \fB\-\-robot \-\-list\fP ì˜µì…˜ì„ +사용합니다. +. +.SS "ë™ìž‘ 수정ìž" +.TP +\fB\-k\fP, \fB\-\-keep\fP +ìž…ë ¥ 파ì¼ì„ 삭제하지 않습니다. +.IP "" +\fBxz\fP 5.2.6 부터는 ì´ ì˜µì…˜ìœ¼ë¡œ ìž…ë ¥ 파ì¼ì´ ì¼ë°˜ 파ì¼ì„ 참조하는 심볼릭 ë§í¬ë‚˜ 하나 ì´ìƒì˜ 하드 ë§í¬, 내지는 setuid, +setgid, ëˆì ì´ 비트 세트를 설정한 ìƒíƒœë¼ë„ 압축하거나 ì••ì¶•ì„ í’€ 수 있습니다. setuid, setgid, ëˆì ì´ 비트는 ëŒ€ìƒ +파ì¼ì— 복사하지 않습니다. ì´ì „ 버전ì—서는 \fB\-\-force\fP ì˜µì…˜ì„ ì§€ì •í–ˆì„ ë•Œë§Œ 가능했습니다. +.TP +\fB\-f\fP, \fB\-\-force\fP +ì´ ì˜µì…˜ì€ ëª‡ê°€ì§€ ë™ìž‘ì— ì˜í–¥ì„ ì¤ë‹ˆë‹¤: +.RS +.IP \(bu 3 +ëŒ€ìƒ íŒŒì¼ì´ ì´ë¯¸ 있으면, ì••ì¶• ë˜ëŠ” ì••ì¶• í•´ì œ ì „ 삭제합니다. +.IP \(bu 3 +ìž…ë ¥ 파ì¼ì´ ì¼ë°˜ 파ì¼ì„ 참조하는 심볼릭 ë§í¬ë‚˜ 하나 ì´ìƒì˜ 하드 ë§í¬, 내지는 setuid, setgid, ëˆì ì´ 비트 세트를 설정한 +ìƒíƒœë¼ë„ ì••ì¶• ë˜ëŠ” ì••ì¶• 해제를 진행합니다. setuid, setgid, ëˆì ì´ 비트는 ëŒ€ìƒ íŒŒì¼ì— 복사하지 않습니다. +.IP \(bu 3 +\fB\-\-decompress\fP \fB\-\-stdout\fP ì˜µì…˜ì„ ê°™ì´ ì‚¬ìš©í•˜ëŠ” ìƒí™©ì—서 \fBxz\fP ëª…ë ¹ì´ ì›ë³¸ 파ì¼ì˜ 형ì‹ì„ 알아내지 못할 때, +ì›ë³¸ 파ì¼ì˜ ì‚¬ë³¸ì„ í‘œì¤€ 출력으로 보냅니다. ì´ë ‡ê²Œ 하면 \fBxzcat\fP \fB\-\-force\fP ëª…ë ¹ì„ \fBxz\fP 명령으로 압축하지 ì•Šì€ +파ì¼ì— 대해 \fBcat\fP(1) ì„ ì‚¬ìš©í•˜ëŠ” 것처럼 사용할 수 있습니다. 참고로 나중ì—, \fBxz\fPì—서 \fBxz\fP로 하여금 여러 형ì‹ì˜ +파ì¼ì„ 표준 출력으로 복사하는 대신 ì••ì¶•ì„ í•´ì œí•˜ë„ë¡ ìƒˆ ì••ì¶• íŒŒì¼ í˜•ì‹ì„ ì§€ì›í•  예정입니다. +\fB\-\-format=\fP\fI<형ì‹>\fP ì˜µì…˜ì€ \fBxz\fP ëª…ë ¹ì— ë‹¨ì¼ íŒŒì¼ í˜•ì‹ë§Œ ì••ì¶• 해제하ë„ë¡ ì œí•œí•  때 사용할 수 +있습니다. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +íŒŒì¼ ëŒ€ì‹  표준 출력으로 ì••ì¶• ë˜ëŠ” ì••ì¶• 해제한 ë°ì´í„°ë¥¼ 기ë¡í•©ë‹ˆë‹¤. \fB\-\-keep\fP를 ìƒëžµí–ˆìŠµë‹ˆë‹¤. +.TP +\fB\-\-single\-stream\fP +ì²˜ìŒ \fB.xz\fP 스트림만 ì••ì¶• 해제하며, ìŠ¤íŠ¸ë¦¼ì— ë’¤ë”°ë¼ì˜¤ëŠ” 나머지 ìž…ë ¥ ë°ì´í„°ëŠ” 조용히 무시합니다. 보통 뒤따ë¼ì˜¤ëŠ” 쓰레기 ê°’ì— +대해서는 \fBxz\fP ì—서 오류를 나타냅니다. +.IP "" +\fBxz\fP는 \fB.lzma\fP íŒŒì¼ ë˜ëŠ” ì›ì‹œ 스트림ì—서 온 하나 ì´ìƒì˜ ìŠ¤íŠ¸ë¦¼ì— ëŒ€í•´ ì••ì¶• í•´ì œë™ìž‘ì„ ì·¨í•˜ì§€ 않지만, ì´ ì˜µì…˜ì„ ì‚¬ìš©í•˜ë©´ +\fBxz\fPì—서 \fB.lzma\fP íŒŒì¼ ë˜ëŠ” ì›ì‹œ ìŠ¤íŠ¸ë¦¼ì„ ì²˜ë¦¬í•œ 다ìŒì— 뒤따ë¼ì˜¤ëŠ” ë°ì´í„°ë¥¼ 무시하ë„ë¡ í•©ë‹ˆë‹¤. +.IP "" +ì´ ì˜µì…˜ì€ ë™ìž‘ 모드가 \fB\-\-decompress\fP ë˜ëŠ” \fB\-\-test\fPê°€ 아니면 ë™ìž‘ì— ì•„ë¬´ëŸ° ì˜í–¥ì„ 주지 않습니다. +.IP "" +\fBxz\fP 5.7.1alpha 부터는 \fB\-\-single\-stream\fP ì˜µì…˜ì˜ ë™ìž‘ì— \fB\-\-keep\fP ë™ìž‘ì´ ë“¤ì–´ê°‘ë‹ˆë‹¤. +.TP +\fB\-\-no\-sparse\fP +í¬ì†Œ 파ì¼ì„ 만들지 않습니다. 기본ì ìœ¼ë¡œ ì¼ë°˜ 파ì¼ë¡œ ì••ì¶• 해제할 경우 \fBxz\fP ì—서는 ì••ì¶• 해제한 파ì¼ì— ì´ì§„ 0ê°’ì´ ê¸¸ê²Œ 늘어질 +경우 í¬ì†Œ ë°°ì—´ 파ì¼ì„ 만들려고 합니다. 표준 ì¶œë ¥ì˜ ë‚´ìš© 길ì´ë§Œí¼ 연결한 ì¼ë°˜ 파ì¼ë¡œ 기ë¡í•  ë•Œë„ ë™ìž‘하며 í¬ì†Œ 파ì¼ì„ 만드는 ë™ì•ˆ +아무런 문제가 나타나지 않게 ê°ê°ì˜ 추가 ì¡°ê±´ì„ ë§Œì¡±í•©ë‹ˆë‹¤. í¬ì†Œ 파ì¼ì„ 만들면 ë””ìŠ¤í¬ ê³µê°„ì„ ì ˆì•½í•  수 있으며 ë””ìŠ¤í¬ ìž…ì¶œë ¥ì„ ì¤„ì—¬ +ì••ì¶• í•´ì œ ì†ë„를 올릴 수 있습니다. +.TP +\fB\-S\fP \fI.suf\fP, \fB\-\-suffix=\fP\fI.suf\fP +ì••ì¶•í•  때, ëŒ€ìƒ íŒŒì¼ì˜ ì ‘ë‘사를 \fB.xz\fP ë˜ëŠ” \fB.lzma\fP 대신 \fI.suf\fP로 사용하십시오. 표준 출력으로 기ë¡í•˜ì§€ 않고 +ì›ë³¸ 파ì¼ì— \fI.suf\fP ì ‘ë‘사가 붙어있으면, 경고를 나타내고 해당 파ì¼ì„ 건너ëœë‹ˆë‹¤. +.IP "" +ì••ì¶• 해제할 때, \fI.suf\fP 접미사로 파ì¼ì„ ì¸ì‹í•˜ê¸°ë„ 하고, \fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP, +\&\fB.lz\fP 접미사가 ë¶™ì€ íŒŒì¼ë„ ì¸ì‹í•©ë‹ˆë‹¤. ì›ë³¸ 파ì¼ì— \fI.suf\fP 접미사가 붙어있으면, 해당 접미사를 제거하여 ëŒ€ìƒ íŒŒì¼ ì´ë¦„ì„ +알아냅니다. +.IP "" +ì›ì‹œ 스트림 ì••ì¶• ë° ì••ì¶• 해제시(\fB\-\-format=raw\fP) ì›ì‹œ ìŠ¤íŠ¸ë¦¼ì— ê¸°ë³¸ 접미사가 없기 때문ì—, 표준 출력으로 기ë¡í•˜ì§€ 않는 +한 접미사를 반드시 지정해야 합니다. +.TP +\fB\-\-files\fP[\fB=\fP\fI<파ì¼>\fP] +\fI<파ì¼>\fPì—서 처리할 íŒŒì¼ ì´ë¦„ì„ ì½ìŠµë‹ˆë‹¤. \fI<파ì¼>\fPì„ ìƒëžµí•˜ë©´ íŒŒì¼ ì´ë¦„ì€ í‘œì¤€ ìž…ë ¥ì—서 +불러옵니다. íŒŒì¼ ì´ë¦„ì€ ê°œí–‰ 문ìžë¡œ ë나야 합니다. 대시 문ìž(\fB\-\fP)는 ì¼ë°˜ íŒŒì¼ ì´ë¦„으로 취급하며 표준 ìž…ë ¥ì„ ì˜ë¯¸í•˜ì§€ +않습니다. íŒŒì¼ ì´ë¦„ì„ ëª…ë ¹í–‰ ì¸ìžë¡œ 지정하면, \fI<파ì¼>\fPì—서 íŒŒì¼ ì´ë¦„ì„ ì½ì–´ë“¤ì´ê¸° ì „ 해당 명령행 ì¸ìžë¥¼ 먼저 +처리합니다. +.TP +\fB\-\-files0\fP[\fB=\fP\fI<파ì¼>\fP] +ê° íŒŒì¼ ì´ë¦„ì´ ë„ ë¬¸ìžë¡œ ë나야 한다는 ì ë§Œ 제외하면 \fB\-\-files\fP[\fB=\fP\fI<파ì¼>\fP] 옵션과 ë™ì¼í•©ë‹ˆë‹¤. +. +.SS "기본 íŒŒì¼ í˜•ì‹ ë° ì••ì¶• 옵션" +.TP +\fB\-F\fP \fIformat\fP, \fB\-\-format=\fP\fI<형ì‹>\fP +ì••ì¶• ë˜ëŠ” ì••ì¶•í•´ì œ íŒŒì¼ \fI<형ì‹>\fPì„ ì§€ì •í•©ë‹ˆë‹¤: +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +기본 값입니다. ì••ì¶•í•  때, \fBauto\fP는 \fBxz\fPì˜ ê¸°ë³¸ ë™ìž‘ê³¼ ë™ì¼í•©ë‹ˆë‹¤. ì••ì¶•ì„ í•´ì œí•  때, ìž…ë ¥ íŒŒì¼ í˜•ì‹ì„ ìžë™ìœ¼ë¡œ +찾습니다. 참고로 ì›ì‹œ 스트림(\fB\-\-format=raw\fP)ì˜ ê²½ìš° ìžë™ìœ¼ë¡œ ì°¾ì„ ìˆ˜ 없습니다. +.TP +\fBxz\fP +\&\fB.xz\fP íŒŒì¼ í˜•ì‹ìœ¼ë¡œ 압축하거나, ì••ì¶• 해제시 \fB.xz\fP 파ì¼ë§Œ 받아들입니다. +.TP +\fBlzma\fP, \fBalone\fP +ì´ì „ \fB.lzma\fP íŒŒì¼ í˜•ì‹ìœ¼ë¡œ 압축하거나, ì••ì¶• 해제시 \fB.lzma\fP 파ì¼ë§Œ 받아들입니다. \fBalone\fP 대체 ëª…ë ¹ì€ LZMA +유틸리티 하위 í˜¸í™˜ì„±ì„ ëª©ì ìœ¼ë¡œ 제공합니다. +.TP +\fBlzip\fP +ì••ì¶• 해제시 \fB.lz\fP 파ì¼ë§Œ 받아들입니다. ì••ì¶•ì€ ì§€ì›í•˜ì§€ 않습니다. +.IP "" +\&\fB.lz\fP í˜•ì‹ ë²„ì „ 0ê³¼ 1ì„ ì§€ì›í•©ë‹ˆë‹¤. 버전 0파ì¼ì€ \fBlzip\fP 1.3 ì´ì „ì—서만 만듭니다. ì¼ë°˜ì ì´ì§„ 않지만 ì¼ë¶€ 파ì¼ì˜ +경우 ì´ í˜•ì‹ì˜ ì›ë³¸ 패키지로 보관한 파ì¼ì„ ì°¾ì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. ê°œì¸ì ìœ¼ë¡œ ì´ í˜•ì‹ìœ¼ë¡œ 압축한 ì˜¤ëž˜ëœ ê°œì¸ íŒŒì¼ì„ 가지고 ìžˆì„ ìˆ˜ë„ +있습니다. í˜•ì‹ ë²„ì „ 0 ì••ì¶• í•´ì œ ì§€ì›ì€ \fBlzip\fP 1.18ì—서 제거했습니다. \fBlzip\fP 1.4 ì´í›„ì˜ ë²„ì „ì—서는 버전 1 +í˜•ì‹ íŒŒì¼ì„ 만듭니다. +.TP +\fBraw\fP +ì›ì‹œ 스트림으로 압축하거나 ì••ì¶•ì„ í•´ì œí•©ë‹ˆë‹¤(í—¤ë” ì—†ìŒ). 고급 ì‚¬ìš©ìž ì „ìš©ìž…ë‹ˆë‹¤. ì›ì‹œ ìŠ¤íŠ¸ë¦¼ì„ ë””ì½”ë”©í•˜ë ¤ë©´, +\fB\-\-format=raw\fP ì˜µì…˜ì„ ì‚¬ìš©í•˜ê³  분명하게 í•„í„° ì²´ì¸ì„ 지정하여 컨테ì´ë„ˆ í—¤ë”ì— í•„ìš”í•œ 정보를 저장하게 ë” í•´ì•¼í•©ë‹ˆë‹¤. +.RE +.TP +\fB\-C\fP \fI<검사방ì‹>\fP, \fB\-\-check=\fP\fI<검사방ì‹>\fP +무결성 검사 ë°©ì‹ì„ 지정합니다. 검사 ë°©ì‹ì€ \fB.xz\fP 파ì¼ì— 저장하며 ì••ì¶• í•´ì œ ë°ì´í„°ë¥¼ 계산합니다. ì´ ì˜µì…˜ì€ \fB.xz\fP +형ì‹ìœ¼ë¡œ ì••ì¶•í•  때만 íš¨ë ¥ì´ ìžˆìŠµë‹ˆë‹¤: \fB.lzma\fP 형ì‹ì€ 무결성 ê²ì‚¬ë¥¼ ì§€ì›í•˜ì§€ 않습니다. 무결성 검사는 \fB.xz\fP íŒŒì¼ ì••ì¶•ì„ +í’€ì—ˆì„ ë•Œì— ê²€ì‚¬í•©ë‹ˆë‹¤. +.IP "" +ì§€ì› \fI검사\fP 형ì‹: +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +ì–´ë–¤ 경우ì—ë„ ë¬´ê²°ì„± 검사 ê³„ì‚°ì„ ìˆ˜í–‰í•˜ì§€ 않습니다. 보통 바람ì§í•˜ì§€ 못한 ìƒê°ìž…니다. ë°ì´í„° ë¬´ê²°ì„±ì„ ë‹¤ë¥¸ ë°©ì‹ìœ¼ë¡œë¼ë„ ê²€ì¦í•´ì•¼ +하는 ìƒí™©ì´ë©´ 쓸만할 수 있습니다. +.TP +\fBcrc32\fP +IEEE\-802.3 (ì´ë”ë„·)ì˜ ë‹¤í•­ 연산으로 CRC32를 계산합니다. +.TP +\fBcrc64\fP +ECMA\-182ì˜ ë‹¤í•­ì‹ ì—°ì‚°ìœ¼ë¡œ CRC64를 계산합니다. ì´ ë™ìž‘ì´ ê¸°ë³¸ ë™ìž‘ì´ê¸° ë•Œë¬¸ì— CRC32ê°€ 깨진 파ì¼ì„ ì°¾ì„ ë•Œë³´ë‹¤ëŠ” 좀 +ë‚®ì€ íŽ¸ì´ë©° ì†ë„ ì°¨ì´ë„ ê±°ì˜ ì—†ìŠµë‹ˆë‹¤. +.TP +\fBsha256\fP +SHA\-256 해시를 계산합니다. CRC32와 CRC64 보다는 좀 ëŠë¦½ë‹ˆë‹¤. +.RE +.IP "" +\&\fB.xz\fP í—¤ë” ë¬´ê²°ì„±ì€ í•­ìƒ CRC32로 ê²€ì¦í•˜ë¹ˆë‹¤. ì´ë¥¼ 바꾸거나 It is not possible to change or +disable it. +.TP +\fB\-\-ignore\-check\fP +ì••ì¶• ë°ì´í„°ë¥¼ 압축해제할 경우 ì••ì¶• ë°ì´í„°ì˜ 무결성 ê²€ì¦ì„ 진행하지 않습니다. \fB.xz\fP í—¤ë”ì˜ CRC32 ê°’ì€ ê·¸ëž˜ë„ ì—¬ì „ížˆ 보통 +ë°©ì‹ìœ¼ë¡œ ê²€ì¦í•©ë‹ˆë‹¤. +.IP "" +\fBì´ ì˜µì…˜ì´ ì •í™•ížˆ 무슨 ë™ìž‘ì„ í•˜ëŠ”ì§€ 알기 ì „ì—는 사용하지 마십시오.\fP ì´ ì˜µì…˜ì„ ì‚¬ìš©í•˜ëŠ” 타당한 ì´ìœ ë¡œ: +.RS +.IP \(bu 3 +깨진 .xz 파ì¼ì—서 ë°ì´í„° 복구를 시ë„합니다. +.IP \(bu 3 +ì••ì¶• í•´ì œ ì†ë„를 늘립니다. SHA\-256 ë˜ëŠ” ì••ì¶• 파ì¼ì— 들어간 ê·¸ 무언가를 ì—„ì²­ 빨리 처리합니다. 다른 ë°©ì‹ìœ¼ë¡œ íŒŒì¼ ë¬´ê²°ì„±ì„ +ê²€ì¦í•´ì•¼ 하는 목ì ì´ 아니ë¼ë©´ ì´ ì˜µì…˜ì„ ì‚¬ìš©í•˜ì§€ 않는게 좋습니다. +.RE +.TP +\fB\-0\fP ... \fB\-9\fP +ì••ì¶• 사전 설정 ìˆ˜ì¤€ì„ ì„ íƒí•©ë‹ˆë‹¤. ê¸°ë³¸ê°’ì€ \fB\-6\fP입니다. 다중 ìˆ˜ì¤€ì„ ì§€ì •í•˜ë©´ 가장 마지막 수준 ì˜µì…˜ì„ ì ìš©í•©ë‹ˆë‹¤. 개별 í•„í„° +ì²´ì¸ì„ ì´ë¯¸ 지정했다면, ì••ì¶• 사전 설정 수준 ê°’ì„ ì„¤ì •í•  때 개별 í•„í„° ì²´ì¸ì„ 정리합니다. +.IP "" +사전 설정간 ì°¨ì´ëŠ” \fBgzip\fP(1)ê³¼ \fBbzip2\fP(1)ì„ ì‚¬ìš©í•  때보다 ë” ë¹„ì¤‘ì„ ì°¨ì§€í•©ë‹ˆë‹¤. ì„ íƒí•œ ì••ì¶• ì„¤ì •ì€ ì••ì¶• 해제시 +필요한 메모리 ì‚¬ìš©ëŸ‰ì„ ì…œì •í•˜ë¯€ë¡œ 사전 설정 수준 ê°’ì„ ë„ˆë¬´ 높게 지정하면 RAM ìš©ëŸ‰ì´ ì ì€ ì˜¤ëž˜ëœ ì‹œìŠ¤í…œì—서 íŒŒì¼ ì••ì¶• 해제시 실패할 +수 있습니다. 게다가, \fBgzip\fP(1) ê³¼ \fBbzip2\fP(1)ì—서 처럼 종종 \fB모든 ë™ìž‘ì— \-9를 몰래 활용하는건 바람ì§í•˜ì§€ 않습니다\fP. +.RS +.TP +\fB\-0\fP ... \fB\-3\fP +ë™ìž‘ì´ ë¹ ë¥¸ 사전 설정 부류입니다. \fB\-0\fPì€ ë•Œë¡œëŠ” \fBgzip \-9\fP 명령보다 ì••ì¶•ìœ¨ì´ í›¨ì”¬ ìš°ìˆ˜í•˜ë©´ì„œë„ ë” ë¹ ë¦…ë‹ˆë‹¤. ë” í° +ê°’ì€ ë³´í†µ \fBbzip2\fP(1) 명령과 비êµí–ˆì„ ë–„ ì••ì¶• 결과가 ì••ì¶• ë°ì´í„°ì— ë”°ë¼ ë‹¬ë¼ì§€ë”ë¼ë„, 비êµí•  법한 ì†ë„ ë˜ëŠ” ë” ë‚˜ì€ +ì••ì¶•ìœ¨ì„ ë³´ìž…ë‹ˆë‹¤. +.TP +\fB\-4\fP ... \fB\-6\fP +ì˜¤ëž˜ëœ ì‹œìŠ¤í…œì—서 ì¡°ì°¨ë„ ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì˜ ì ì ˆí•œ 메모리 ì‚¬ìš©ëŸ‰ì„ ë³´ì´ë©´ì„œ 양호하거나 최ì ì˜ ì••ì¶•ìœ¨ì„ ë³´ì—¬ì¤ë‹ˆë‹¤. \fB\-6\fP ì˜µì…˜ì€ +ì••ì¶• 해제시 메모리 ì‚¬ìš©ëŸ‰ì´ 16MiB ë°–ì— ì•ˆë˜ê¸° ë•Œë¬¸ì— íŒŒì¼ì„ ë°°í¬í•  때 최ì ì˜ ì„ íƒì¸ 기본 값입니다. (\fB\-5e\fP ë˜ëŠ” +\fB\-6e\fPë„ ì—­ì‹œ 고려할 만합니다. \fB\-\-extreme\fPì„ ì°¸ê³ í•˜ì‹­ì‹œì˜¤.) +.TP +\fB\-7 ... \-9\fP +\fB\-6\fPê³¼ 비슷하지만 ì••ì¶• ë° ì••ì¶• 해제시 요구 메모리 ì‚¬ìš©ëŸ‰ì´ ë” ë†’ìŠµë‹ˆë‹¤. ì••ì¶• 파ì¼ì´ ê°ê° 8MiB, 16MiB, 32MiB +보다 í´ ê²½ìš°ì—ë§Œ 쓸만한 옵션입니다. +.RE +.IP "" +ë™ì¼í•œ 하드웨어ì—서, ì••ì¶• í•´ì œ ì†ë„는 압축한 ë°ì´í„°ì˜ 초당 ì •ì  ë°”ì´íЏ 처리 ìˆ˜ì˜ ì–´ë¦¼ í‰ê· ìž…니다. 다시 ë§í•´, ì••ì¶•ìœ¨ì„ ë” ì˜¬ë¦¬ë©´, +ì••ì¶• í•´ì œ ì†ë„ë„ ì—­ì‹œ 올ë¼ê°‘니다. ì´ëŠ” ê³§ 초당 비압축 ë°ì´í„° 출력 ì–‘ì´ ë‹¬ë¼ì§ˆ 수 있단 뜻입니다. +.IP "" +ë‹¤ìŒ í‘œì— ì‚¬ì „ 설정 ê¸°ëŠ¥ì„ ì •ë¦¬í–ˆìŠµë‹ˆë‹¤: +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Preset;DictSize;CompCPU;CompMem;DecMem +\-0;256 KiB;0;3 MiB;1 MiB +\-1;1 MiB;1;9 MiB;2 MiB +\-2;2 MiB;2;17 MiB;3 MiB +\-3;4 MiB;3;32 MiB;5 MiB +\-4;4 MiB;4;48 MiB;5 MiB +\-5;8 MiB;5;94 MiB;9 MiB +\-6;8 MiB;6;94 MiB;9 MiB +\-7;16 MiB;6;186 MiB;17 MiB +\-8;32 MiB;6;370 MiB;33 MiB +\-9;64 MiB;6;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +컬럼 설명: +.RS +.IP \(bu 3 +DictSize는 LZMA2 딕셔너리 í¬ê¸°ìž…니다. ì••ì¶• í•´ì œ 파ì¼ì˜ í¬ê¸°ë³´ë‹¤ 딕셔너리ì—서 사용하는 낭비 메모리 용량입니다. 실제로 +필요하지 ì•Šì€ \fB\-7\fP ... \fB\-9\fP 사전 ì„¤ì •ê°’ì„ í”¼í•´ì•¼ 하는 ì ì ˆí•œ ì´ìœ ì´ê¸°ë„ 합니다. \fB\-6\fP ì´í•˜ì—서는 소모 메모리 ì–‘ì´ +충분히 ì ê±°ë‚˜ 따로 신경쓸 필요가 없습니다. +.IP \(bu 3 +CompCPU는 ì••ì¶• ì†ë„ì— ì˜í–¥ì„ 주는 LZMA2 ì„¤ì •ì˜ ë‹¨ìˆœí™” 표기 값입니다. 딕셔너리 í¬ê¸°ëŠ” ì†ë„ì—ë„ ì˜í–¥ì„ 주기 ë•Œë¬¸ì— +CompCPU는 \fB\-6\fP ... \fB\-9\fP 수준값과 ë™ì¼í•œë°, 고수준 ê°’ì€ ì—¬ì „ížˆ 조금 ë” ëŠë ¤ì§ˆ 수 있습니다. ëŠë ¤ì§€ëŠ” ë§Œí¼ +ì••ì¶•ìœ¨ì€ ê°€ëŠ¥í•œ 한 ë” ì¢‹ì•„ì§‘ë‹ˆë‹¤. \fB\-\-extreme\fPì„ ì°¸ê³ í•˜ì‹­ì‹œì˜¤. +.IP \(bu 3 +CompMemì€ ë‹¨ì¼\-스레드 모드ì—서 필요한 ì••ì¶• í”„ë¡œê·¸ëž¨ì˜ ë©”ëª¨ë¦¬ ì ìœ  용량입니다. \fBxz\fP ë²„ì „ì— ë”°ë¼ ë‹¤ë¥¼ 수 있습니다. +.IP \(bu 3 +DecMemì€ ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì˜ ë©”ëª¨ë¦¬ ì ìœ ìš©ëŸ‰ìž…니다. ì´ëŠ” ê³§, ì••ì¶• í•´ì œ 프로그램ì—서 필요한 메모리 ì‚¬ìš©ëŸ‰ì„ ì••ì¶• 설정ì—서 +결정한다는 ì˜ë¯¸ê°€ 들어있습니다. 정확한 ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì˜ ë©”ëª¨ë¦¬ ì‚¬ìš©ëŸ‰ì€ LZMA2 딕셔너리 í¬ê¸° 보다는 조금 많지만 í…Œì´ë¸”ì˜ ê°’ì€ +MiB 용량으로 완전히 반올림한 값입니다. +.RE +.IP "" +다중\-스레드 모드ì—서 필요한 메모리 ìš©ëŸ‰ì€ ë‹¨ì¼\-스레드 모드보단 약간 ë” ë§ŽìŠµë‹ˆë‹¤. \fB\-\-block\-size\fP ê¸°ë³¸ê°’ì— ë”°ë¼, ê° +스레드ì—서는 3*3*딕셔녀리_í¬ê¸° + 압축시_메모리용량 ë˜ëŠ” ì••ì¶•_해제시_메모리용량 ì •ë„ê°€ 필요합니다. 예를 들면, 스레드 ë„·ì— ì‚¬ì „ +설정 옵션 \fB\-6\fPì„ ì‚¬ìš©í•œë‹¤ë©´, 660\(en670 MiB 메모리 ìš©ëŸ‰ì´ í•„ìš”í•©ë‹ˆë‹¤. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +기대하는 ë§Œí¼ì˜ 좀 ë” ë‚˜ì€ ì••ì¶•ìœ¨ì„ í™•ë³´í•˜ë ¤ ì„ íƒí•œ ì••ì¶• 사전 설정 ìˆ˜ì¤€ì˜ ëŠë¦° 변형 ì˜µì…˜ì„ ì‚¬ìš©í•˜ì§€ë§Œ, 재수 없는 ì™€ì¤‘ì— ê³¨ë¡œ 가는 +경우가 ìƒê¸°ê¸°ë„ 합니다. ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì˜ ë©”ëª¨ë¦¬ 사용ì—는 ì˜í–¥ì„ 주지 않지만, ì••ì¶• í”„ë¡œê·¸ëž¨ì˜ ë©”ëª¨ë¦¬ ì‚¬ìš©ëŸ‰ì€ \fB\-0\fP +\&... \fB\-3\fP 사전 설정 수준ì—서 약간 ë” ì˜¬ë¼ê°ˆ ë¿ìž…니다. +.IP "" +4MiB와 8MiB ë‘ ê°€ì§€ 딕셔너리 용량 ì„¤ì •ì´ ìžˆê¸° ë•Œë¬¸ì— \fB\-3e\fP 와 \fB\-5e\fP 사전 ì„¤ì •ì„ (CompCPU 수치를 낮춰서) +ê°ê° \fB\-4e\fP 와 \fB\-6e\fP 보다 약간 ë” ë¹ ë¥´ê²Œ 설정할 수 있습니다. ì´ëŸ° ì‹ìœ¼ë¡œ ë‘ ì‚¬ì „ ì„¤ì •ì´ ë™ì¼í•˜ì§€ 않습니다. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Preset;DictSize;CompCPU;CompMem;DecMem +\-0e;256 KiB;8;4 MiB;1 MiB +\-1e;1 MiB;8;13 MiB;2 MiB +\-2e;2 MiB;8;25 MiB;3 MiB +\-3e;4 MiB;7;48 MiB;5 MiB +\-4e;4 MiB;8;48 MiB;5 MiB +\-5e;8 MiB;7;94 MiB;9 MiB +\-6e;8 MiB;8;94 MiB;9 MiB +\-7e;16 MiB;8;186 MiB;17 MiB +\-8e;32 MiB;8;370 MiB;33 MiB +\-9e;64 MiB;8;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +예를 들면, 8MiB 딕셔너리를 활용하는 네가지 사전 ì„¤ì •ì´ ìžˆë‹¤ê³  í•  때, 빠른 순으로 ì„¤ì •ì„ ë‚˜ì—´í•˜ìžë©´, \fB\-5\fP, \fB\-6\fP, +\fB\-5e\fP, \fB\-6e\fP 입니다. +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +ì´ ì˜µì…˜ì€ \fB\-0\fP ê³¼ \fB\-9\fPì˜ ë³„ì¹­ìœ¼ë¡œ ê°ê° 오해할 수 있습니다. LZMA ìœ í‹¸ë¦¬í‹°ì˜ í•˜ìœ„ í˜¸í™˜ì„±ì„ ëª©ì ìœ¼ë¡œ 제공합니다. ì´ +옵션 ì‚¬ìš©ì€ í”¼í•˜ì‹­ì‹œì˜¤. +.TP +\fB\-\-block\-size=\fP\fI<í¬ê¸°>\fP +\&\fB.xz\fP 형ì‹ìœ¼ë¡œ ì••ì¶•í•  때, ìž…ë ¥ ë°ì´í„°ë¥¼ \fI<í¬ê¸°>\fP ë°”ì´íЏ 블ë¡ìœ¼ë¡œ ìž…ë ¥ ë°ì´í„°ë¥¼ 쪼갭니다. ê°ê°ì˜ 블ë¡ì€ +다중\-스레드 ë°©ì‹ìœ¼ë¡œ 처리할 수 있고 ìž„ì˜ ì ‘ê·¼ ì••ì¶• í•´ì œ ê°€ëŠ¥ì„±ì„ ì œí•œí•  수 있게 개별ì ìœ¼ë¡œ ì••ì¶• 처리합니다. ì´ ì˜µì…˜ì€ ë³´í†µ +다중\-스레드 모드ì—서 기본 ë¸”ë¡ í¬ê¸°ë¥¼ 지정할 때 사용하지만, 단ì¼\-스레드 모드ì—ì„œë„ ì‚¬ìš©í•  수 있습니다. +.IP "" +다중\-스레드 모드ì—서는 약 3ë°° ìš©ëŸ‰ì˜ \fI<í¬ê¸°>\fP ë°”ì´íŠ¸ë§Œí¼ ê° ìŠ¤ë ˆë“œ 별로 입출력 버í¼ë§ìš© ê³µê°„ì„ í• ë‹¹í•©ë‹ˆë‹¤. 기본 +\fI<í¬ê¸°>\fP는 LZMA2 딕셔너리 í¬ê¸° ë˜ëŠ” 1MiB 중 가장 í° ìª½ì˜ ì„¸ 배입니다. 보통 ì ì ˆí•œ 값으로 LZMA2 +딕셔너리 í¬ê¸° ë˜ëŠ” 최소한 1MiB ìš©ëŸ‰ì˜ 2\(en4배입니다. LZMA2 딕셔너리 í¬ê¸°ë³´ë‹¤ ìž‘ì€ \fI<í¬ê¸°>\fP는 ëž¨ì˜ +ì†Œëª¨ì  ì‚¬ìš© 공간으로 í• ë‹¹í•˜ëŠ”ë° LZMA2 딕셔너리 버í¼ë¥¼ 할당한 용량 í¬ê¸° 전체를 다 사용하지 않기 때문입니다. 다중\-스레드 모드ì—서 +ë¸”ë¡ í¬ê¸°ëŠ” ë¸”ë¡ í—¤ë”ì— ì €ìž¥í•˜ë©°, ì´ í¬ê¸° 정보는 다중\-스레드 ì••ì¶• 해제시 필요합니다. +.IP "" +단ì¼\-스레드 모드ì—서는 기본ì ìœ¼ë¡œ ë¸”ë¡ ìª¼ê°œê¸°ë¥¼ 하지 않습니다. ì´ ì˜µì…˜ì„ ì„¤ì •í•œë‹¤ê³  해서 메모리 ì‚¬ìš©ì— ì˜í–¥ì„ 주지는 않습니다. +ë¸”ë¡ í—¤ë”ì— í¬ê¸° 정보를 저장하지 않기 ë•Œë¬¸ì— ë‹¨ì¼\-스레드 모드ì—서 만든 파ì¼ì€ 다중\-스레드 모드ì—서 만든 파ì¼ê³¼ ë™ì¼í•˜ì§€ 않습니다. +í¬ê¸° ì •ë³´ì˜ ëˆ„ë½ì€ ë˜í•œ \fBxz\fPì—서 다중\-스레드 모드로 ì••ì¶• 해제를 진행할 수 ì—†ìŒì„ ì˜ë¯¸í•˜ê¸°ë„ 합니다. +.TP +\fB\-\-block\-list=\fP\fI<항목>\fP +\&\fB.xz\fP 형ì‹ìœ¼ë¡œ ì••ì¶•í•  때, 압축하지 ì•Šì€ ë°ì´í„°ë¡œ 부터 ì¼ì • 간격 ì´í›„ì— ìƒˆ ë¸”ë¡ ì²˜ë¦¬ë¥¼ 시작합니다. +.IP "" +\fI<항목>\fPì€ ì‰¼í‘œë¡œ 구분한 목ë¡ìœ¼ë¡œ 지정합니다. ê° í•­ëª©ì€ ì½œë¡  (\fB:\fP)으로 구분한 0부터 9ê¹Œì§€ì˜ ì¶”ê°€ í•„í„° +ì²´ì¸ ë²ˆí˜¸ 값으로 ì´ë£¨ì–´ì ¸ 있으며, 압축하지 ì•Šì€ ë°ì´í„°ì˜ í¬ê¸° ê°’ì´ í•„ìš”í•©ë‹ˆë‹¤. í•­ëª©ì„ ìƒëžµí•˜ë©´(둘 ì´ìƒì˜ 쉼표 ì—°ì† í‘œê¸°) ì´ì „ +í•­ëª©ì˜ í¬ê¸°ì™€ 필터를 활용하겠다는 함축 ì˜ë¯¸ë¥¼ ë„£ì„ ìˆ˜ 있습니다. +.IP "" +ìž…ë ¥ 파ì¼ì´ \fI<항목>\fP í¬ê¸°ì˜ 합보다 í¬ë©´, 마지막 í•­ëª©ì„ íŒŒì¼ì˜ ë까지 반복합니다. 특별히 \fB0\fP ê°’ì„ ë§ˆì§€ë§‰ +값으로 사용하여 íŒŒì¼ ë‚˜ë¨¸ì§€ ë¶€ë¶„ì„ ë‹¨ì¼ ë¸”ë¡ìœ¼ë¡œ ì¸ì½”딩해야 한다는 ì˜ë¯¸ë¥¼ 나타낼 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. +.IP "" +\fB\-\-filters1=\fP\fI<í•„í„°>\fP \&...\& \fB\-\-filters9=\fP\fI<í•„í„°>\fP 옵션 조합으로 +ê° ë¸”ë¡ë³„ ë³„ë„ í•„í„° ì²´ì¸ì„ 지정할 수 있습니다. ì´ ì˜µì…˜ì€ 1\(en9번 í•„í„° ì²´ì¸ì„ 지정합니다. í•„í„° ì²´ì¸ 0ë²ˆì€ í•„í„° ì²´ì¸ì„ +지정하지 ì•Šì•˜ì„ ë•Œì™€ ë™ì¼í•œ 기본 í•„í„° ì²´ì¸ìœ¼ë¡œ 참조할 수 있습니다. í•„í„° ì²´ì¸ ì‹ë³„ 번호는 비 ì••ì¶• í¬ê¸° ì•žì— ì½œë¡ (\fB:\fP)ì„ ë¶™ì—¬ +사용할 수 있습니다. 예를 들면, \fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP ì˜µì…˜ì„ +ì§€ì •í–ˆì„ ê²½ìš° ë‹¤ìŒ ê·œì¹™ëŒ€ë¡œ 블ë¡ì„ 만듭니다: +.RS +.IP \(bu 3 +\fB\-\-filters1\fP í•„í„° ì²´ì¸ì—서는 2MiB ìž…ë ¥ì„ +.IP \(bu 3 +\fB\-\-filters3\fP í•„í„° ì²´ì¸ì—서는 2MiB ìž…ë ¥ì„ +.IP \(bu 3 +\fB\-\-filters2\fP í•„í„° ì²´ì¸ì—서는 4MiB ìž…ë ¥ì„ +.IP \(bu 3 +\fB\-\-filters2\fP í•„í„° ì²´ì¸ì—서는 4MiB ìž…ë ¥ì„ +.IP \(bu 3 +기본 í•„í„° ì²´ì¸ì—서는 2MiB ìž…ë ¥ì„ +.IP \(bu 3 +ìž…ë ¥ì´ ë나기 ì „ì˜ ëª¨ë“  블ë¡ì—는 기본 í•„í„° ì²´ì¸ê³¼ 4MiB ìž…ë ¥ì„ ì ìš©í•©ë‹ˆë‹¤. +.RE +.IP "" +ì¸ì½”ë” ë¸”ë¡ í¬ê¸°ë¥¼ 초과하는 í¬ê¸° ê°’ì„ ì§€ì •í•˜ë©´(스레드 모드 기본값 ë˜ëŠ” \fB\-\-block\-size=\fP\fI<í¬ê¸°>\fP +옵션으로 지정한 ê°’), ì¸ì½”ë”는 \fI<í¬ê¸°>\fP 지정 용량 범위는 유지하면서 추가 블ë¡ì„ 만듭니다. 예를 들면 +\fB\-\-block\-size=10MiB\fP \fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP ì˜µì…˜ì„ ì§€ì •í•˜ê³  +ìž…ë ¥ 파ì¼ì„ 80MiB 용량으로 전달하면, ê°ê° 5, 10, 8, 10, 2, 10, 10, 4, 10, 10, 1 MiB ìš©ëŸ‰ì„ +차지하는 ë¸”ë¡ 11개를 결과물로 ë‚´ì¤ë‹ˆë‹¤. +.IP "" +다중\-스레드 모드ì—서 ë¸”ë¡ í¬ê¸°ëŠ” ë¸”ë¡ í—¤ë”ì— ì €ìž¥í•©ë‹ˆë‹¤. 단ì¼\-스레드 모드ì—서는 저장하지 않기 ë•Œë¬¸ì— ì¸ì½”딩 처리한 ì¶œë ¥ì€ +다중\-스레드 ëª¨ë“œì˜ ì¶œë ¥ 결과물과는 다릅니다. +.TP +\fB\-\-flush\-timeout=\fP\fI<제한시간>\fP +ì••ì¶•í•  때, ì´ì „ ë°ì´í„°ë¥¼ 소거하고 ë‹¤ìŒ ìž…ë ¥ì„ ë¸”ë¡ ë‹¨ìœ„ë¡œ ë” ì½ëŠ”ë° \fI<제한시간>\fP 밀리초(ì–‘ì˜ ì •ìˆ˜ê°’)ê°€ ì§€ë‚¬ì„ +경우, 대기중ì´ë˜ 모든 ìž…ë ¥ ë°ì´í„°ë¥¼ ì¸ì½”ë”ì—서 소거한 ë‹¤ìŒ ì¶œë ¥ ìŠ¤íŠ¸ë¦¼ì— ì „ë‹¬í•©ë‹ˆë‹¤. ì´ëŸ° ë™ìž‘ì€ ë„¤íŠ¸ì›Œí¬ë¡œ 스트리ë°í•œ ë°ì´í„°ë¥¼ +\fBxz\fP로 ì••ì¶•í•  때 쓸만합니다. \fI<제한시간>\fP ê°’ì„ ì ê²Œ 지정하면 ì ì€ 지연 ì‹œê°„ì— ë°ì´í„°ë¥¼ 받아낼 수 있지만 +\fI<제한시간>\fP ê°’ì„ í¬ê²Œ 하면 ì••ì¶•ìœ¨ì„ ë†’ì¼ ìˆ˜ 있습니다. +.IP "" +ì´ ê¸°ëŠ¥ì€ ê¸°ë³¸ì ìœ¼ë¡œ 꺼져있습니다. ì´ ì˜µì…˜ì„ í•œë²ˆ ì´ìƒ 지정하면, 마지막 ì˜µì…˜ì˜ ê°’ëŒ€ë¡œ ë™ìž‘합니다. 특별히 +\fI<제한시간>\fP ê°’ì„ \fB0\fP으로 설정하면 ì´ ì„¤ì •ì„ ì™„ì „ížˆ ëŒ ìˆ˜ 있습니다. +.IP "" +ì´ ê¸°ëŠ¥ì€ POSIX ì‹œìŠ¤í…œì´ ì•„ë‹Œ ê³³ì—서는 사용할 수 없습니다. +.IP "" +.\" FIXME +\fBì´ ê¸°ëŠ¥ì€ ì—¬ì „ížˆ 시험중입니다\fP. 현재로서는, \fBxz\fP 버í¼ë§ 처리 ë°©ì‹ ë•Œë¬¸ì— \fBxz\fPì˜ ì‹¤ì‹œê°„ 스트림 ì••ì¶• í•´ì œ 기능 í™œìš©ì€ +ì ì ˆí•˜ì§€ 않습니다. +.TP +\fB\-\-no\-sync\fP +ì›ë³¸ 파ì¼ì„ 제거하기 전까지는 스토릿지 ìž¥ì¹˜ì— ëŒ€ìƒ íŒŒì¼ê³¼ 디렉터리를 ë™ê¸°í™”하지 않습니다. ìž‘ì€ ì—¬ëŸ¬ 파ì¼ì„ 압축하거나 압축해제할 때 +ì„±ëŠ¥ì„ ê°œì„ í•  수 있습니다. 그러나, ì‚­ì œ ê³¼ì •ì„ ì§„í–‰í•œ ë‹¤ìŒ ì‹œìŠ¤í…œì´ ë°”ë¡œ 치명ì ì¸ 오류가 나타난다면, ëŒ€ìƒ íŒŒì¼ì„ 스토릿지 ìž¥ì¹˜ì— +저장하지 않았지만 ì‚­ì œ ë™ìž‘ì´ ì´ë£¨ì–´ì¡Œì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. ì´ ê²½ìš° ì›ë³¸ íŒŒì¼ ë¿ë§Œ ì•„ë‹ˆë¼ ëŒ€ìƒ íŒŒì¼ë„ 나타나지 않습니다. +.IP "" +ì´ ì˜µì…˜ì€ \fBxz\fP í”„ë¡œê·¸ëž¨ì´ ì›ë³¸ 파ì¼ì„ 삭제할 때만 ë™ìž‘합니다. 다른 경우ì—는 전혀 ë™ê¸°í™”ê°€ ì´ë£¨ì–´ì§€ì§€ 않습니다. +.IP "" +ë™ê¸°í™” ë™ìž‘ê³¼ \fB\-\-no\-sync\fP ì˜µì…˜ì€ \fBxz\fP 5.7.1alphaì— ì¶”ê°€í–ˆìŠµë‹ˆë‹¤. +.TP +\fB\-\-memlimit\-compress=\fP\fI<제한용량>\fP +ì••ì¶• 수행시 메모리 사용 한계를 지정합니다. ì´ ì˜µì…˜ì„ ì—¬ëŸ¬ë²ˆ 지정하면 마지막 ê°’ì„ ì·¨í•©ë‹ˆë‹¤. +.IP "" +ì••ì¶• ì„¤ì •ì´ \fI<제한용량>\fPì„ ì´ˆê³¼í•˜ë©´, \fBxz\fP는 설정 ê°’ì˜ í•˜í–¥ ì¡°ì •ì„ ì‹œë„하여 한계 ê°’ì„ ë”ì´ìƒ 넘치지 않게 하고 +ìžë™ ì¡°ì ˆì„ ë냈다는 ì•Œë¦¼ì„ í‘œì‹œí•©ë‹ˆë‹¤. ì¡°ì •ì€ ë‹¤ìŒ ìˆœì„œëŒ€ë¡œ 진행합니다. 스레드 수를 줄입니다. 다중\-스레드 모드ì—서 스레드 í•˜ë‚˜ì˜ +할당 한계치가 \fI<제한용량>\fPì„ ë„˜ìœ¼ë©´ 단ì¼\-스레드 모드로 전환합니다. ê·¸ ë‹¤ìŒ ë§ˆì§€ë§‰ìœ¼ë¡œ LZMA2 딕셔너리 í¬ê¸°ë¥¼ +줄입니다. +.IP "" +\fB\-\-format=raw\fP ë˜ëŠ” \fB\-\-no\-adjust\fP 미지정 ìƒí™©ì—서 ì••ì¶•í•  때, ì••ì¶• ë°ì´í„° ì¶œë ¥ì— ì˜í–¥ì„ 주지 않고 스레드 +처리 수만 ì¤„ì¼ ìˆ˜ 있습니다. +.IP "" +\fI<제한용량>\fP ê°’ì´ ì•„ëž˜ 설명한 ì¡°ê±´ì— ë§žì§€ 않으면, 오류가 나타나고 \fBxz\fP ëª…ë ¹ì€ ì¢…ë£Œ ìƒíƒœ 1ë²ˆì„ ë°˜í™˜í•˜ë©° +빠져나갑니다. +.IP "" +\fI<제한용량>\fP ê°’ì€ ì—¬ëŸ¬ ë°©ì‹ìœ¼ë¡œ 지정할 수 있습니다: +.RS +.IP \(bu 3 +\fI<제한용량>\fP ê°’ì€ ë°”ì´íЏ 용량 절대값입니다. 정수 ê°’ì„ ì‚¬ìš©í•˜ë˜ \fBMiB\fP와 ê°™ì€ ì ‘ë¯¸ì‚¬ë¥¼ 사용하는게 좋습니다. +예: \fB\-\-memlimit\-compress=80MiB\fP +.IP \(bu 3 +\fI<제한용량>\fP ê°’ì€ ì´ ë¬¼ë¦¬ 메모리(RAM) ìš©ëŸ‰ì˜ ë°±ë¶„ìœ¨ë¡œ 지정할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 다른 컴퓨터ë¼ë¦¬ 공유하는 ì…¸ +초기화 스í¬ë¦½íŠ¸ì˜ \fBXZ_DEFAULTS\fP 환경 ë³€ìˆ˜ì— ê°’ì„ ì„¤ì •í•  때 특히 쓸만합니다. ì´ëŸ° ë°©ì‹ìœ¼ë¡œ 설정하면 ì‹œìŠ¤í…œì˜ ë©”ëª¨ë¦¬ 설치 +ìš©ëŸ‰ì— ë”°ë¼ ìžë™ìœ¼ë¡œ 늘어납니다. 예: \fB\-\-memlimit\-compress=70%\fP +.IP \(bu 3 +\fI<제한용량>\fP ê°’ì€ \fB0\fP 기본값으로 설정하여 초기화할 수 있습니다. 현재로서는 \fI<제한용량>\fP +ê°’ì´ \fImax\fP(최대) (메모리 사용 한계 ì—†ìŒ) ì¸ ìƒíƒœì™€ ë™ì¼í•©ë‹ˆë‹¤. +.RE +.IP "" +\fBxz\fP 32비트 버전ì—서는 몇가지 특별한 경우가 있습니다. \fI<제한용량>\fP ê°’ì´ \fB4020MiB\fP를 넘으면 +\fI<제한용량>\fPì„ \fB4020MiB\fP로 고정합니다. MIPS32ì—서는 \fB2000MiB\fP로 대신 고정합니다. +(\fB0\fPê³¼ \fBmax\fP는 ì´ ê²½ìš°ì— í•´ë‹¹í•˜ì§€ 않습니다. ì••ì¶• 해제시 비슷한 ê¸°ëŠ¥ì€ ì—†ìŠµë‹ˆë‹¤.) ì´ ê²½ìš° 32비트 실행 파ì¼ì´ +4GiB(MIPS32ì˜ ê²½ìš° 2GiB) 주소 ì˜ì—­ì— 접근할 때 매우 ìš©ì´í•˜ë©°, 다른 경우ì—는 ì›í•˜ëŠ”ëŒ€ë¡œ 문제를 ì¼ìœ¼í‚¤ì§€ 않습니다. +.IP "" +\fB메모리 활용\fP ì„¹ì…˜ë„ ì°¸ê³ í•˜ì‹­ì‹œì˜¤. +.TP +\fB\-\-memlimit\-decompress=\fP\fI<제한용량>\fP +ì••ì¶• 해제시 메모리 사용 한계 ìš©ëŸ‰ì„ ì„¤ì •í•©ë‹ˆë‹¤. \fB\-\-list\fP 모드ì—ë„ ì˜í–¥ì„ ì¤ë‹ˆë‹¤. \fI<제한용량>\fPì„ ë„˜ê¸°ì§€ +않고서는 ë™ìž‘ì´ ì§„í–‰ì´ ì•ˆë  ê²½ìš°, \fBxz\fP ì—서는 오류를 나타내고 íŒŒì¼ ì••ì¶• 해제를 실패로 +간주합니다. \fI<제한용량>\fPì„ ì§€ì •í•˜ëŠ” 가능한 ë°©ë²•ì— ëŒ€í•´ì„œëŠ” +\fB\-\-memlimit\-compress=\fP\fI<제한용량>\fP ì˜µì…˜ì„ ì°¸ê³ í•˜ì‹­ì‹œì˜¤. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fI<제한용량>\fP +다중\-스레드 모드 ì••ì¶• 해제시 메모리 사용 한계 ìš©ëŸ‰ì„ ì„¤ì •í•©ë‹ˆë‹¤. 스레드 ìˆ˜ì— ì˜í–¥ì„ 줄 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. \fBxz\fPì—서 íŒŒì¼ ì••ì¶• +해제를 거부하게 하진 않습니다. \fI<제한용량>\fP 수치가 다중\-스레드로 ì²˜ë¦¬í•˜ê¸°ì— ë„ˆë¬´ 낮다면, +\fI<제한용량>\fP ê°’ì„ ë¬´ì‹œí•˜ê³  \fBxz\fP ë™ìž‘ì„ ë‹¨ì¼\-스레드 모드로 ê³„ì† ì§„í–‰í•©ë‹ˆë‹¤. 참고로 +\fB\-\-memlimit\-decompress\fP ì˜µì…˜ë„ ì‚¬ìš©í•˜ë©´, 단ì¼\-스레드 모드와 다중\-스레드 모드 ë‘ ê²½ìš°ì— ëª¨ë‘ ì ìš©í•˜ê¸°ì—, +다중\-스레드 ëª¨ë“œì— ì ìš©í•  \fI<제한용량>\fP ê°’ì€ \fB\-\-memlimit\-decompress\fPì— ì„¤ì •í•˜ëŠ” 제한 값보다 ë” +í¬ë©´ 안ë©ë‹ˆë‹¤. +.IP "" +다른 메모리 사용 용량 제한 옵션과는 달리, \fB\-\-memlimit\-mt\-decompress=\fP\fI<제한용량>\fP ì˜µì…˜ì€ +시스템별 기본 \fI<제한용량>\fP ê°’ì„ ì§€ë‹™ë‹ˆë‹¤. 현재 설정 ê°’ì€ \fBxz \-\-info\-memory\fP 명령으로 확ì¸í•´ë³¼ 수 +있습니다. +.IP "" +ì´ ì˜µì…˜ê³¼ 기본 ê°’ì€ í•œê³„ ê°’ì„ ì£¼ì§€ 않으면 스레드 기반 ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì´ ì¼ë¶€ ìž…ë ¥ 파ì¼ì— 대해 정신나간 ìˆ˜ì¤€ì˜ ë©”ëª¨ë¦¬ ìš©ëŸ‰ì„ +할당해서 ë™ìž‘ì´ ë나버릴 수 있습니다. 기본 \fI<제한용량>\fPì´ ì‹œìŠ¤í…œì˜ ì‚¬ì–‘ì— ë¹„í•´ 낮다면, +\fI<제한용량>\fP ê°’ì„ ìžìœ ë¡­ê²Œ 올리시ë˜, \fBxz\fP ì—서 ì ì€ 스레드 수ì—ë„ ë©”ëª¨ë¦¬ 공간 í• ë‹¹ì„ ì‹œë„하는 ë§Œí¼, ìž…ë ¥ +파ì¼ì— ì ì ˆí•œ 수준으로 가용 RAM ìš©ëŸ‰ì„ ë„˜ëŠ” í° ê°’ì„ ì„¤ì •í•˜ì§€ 마십시오. 메모리나 스와핑 ì˜ì—­ ê³µê°„ì´ ì¤„ì–´ë“¤ë©´ ì••ì¶•í•´ì œ ì„±ëŠ¥ì„ +개선하지 못합니다. +.IP "" +\fI<제한용량>\fP ê°’ì„ ì§€ì •í•˜ëŠ” 가능한 ë°©ë²•ì„ ë³´ë ¤ë©´ +\fB\-\-memlimit\-compress=\fP\fI<제한용량>\fP ì˜µì…˜ì„ ì°¸ê³ í•˜ì‹­ì‹œì˜¤. \fI<제한용량>\fP ê°’ì„ +\fB0\fP으로 설정하면 \fI<제한용량>\fP ê°’ì´ ì‹œìŠ¤í…œ 지정 기본값으로 ë°”ë€ë‹ˆë‹¤. +.TP +\fB\-M\fP \fI<제한용량>\fP, \fB\-\-memlimit=\fP\fI<제한용량>\fP, \fB\-\-memory=\fP\fI<제한용량>\fP +\fB\-\-memlimit\-compress=\fP\fI<제한용량>\fP +\fB\-\-memlimit\-decompress=\fP\fI<제한용량>\fP +\fB\-\-memlimit\-mt\-decompress=\fP\fI<제한용량>\fP 지정과 ë™ì¼í•©ë‹ˆë‹¤. +.TP +\fB\-\-no\-adjust\fP +ì••ì¶• 출력 ê²°ê³¼ì— ì˜í–¥ì„ 주는 ì„¤ì •ì„ ì¡°ì •í•˜ì§€ 않고는 메모리 사용 용량 제한 ì¡°ê±´ì´ ë§žì§€ 않으면 오류를 표시하고 빠져나갑니다. ì´ +ì˜µì…˜ì€ \fBxz\fPê°€ 다중\-스레드 모드ì—서 단ì¼\-스레드 모드로 전환하고 LZMA2 딕셔너리 í¬ê¸°ë¥¼ 줄ì´ëŠ” ë™ìž‘ì„ ë§‰ì•„ì¤ë‹ˆë‹¤. 심지어 ì´ +ì˜µì…˜ì„ ì‚¬ìš©í•˜ë©´ 메모리 사용 한계를 만족하ë„ë¡ ìŠ¤ë ˆë“œ 수를 줄여 ì••ì¶• 결과물 ì¶œë ¥ì— ì˜í–¥ì´ 가지 않게 합니다. +.IP "" +ì›ì‹œ 스트림(\fB\-\-format=raw\fP)ì„ ë§Œë“¤ ë–„ ìžë™ ì¡°ì •ì€ í•­ìƒ êº¼ì§‘ë‹ˆë‹¤. +.TP +\fB\-T\fP \fI<스레드수>\fP, \fB\-\-threads=\fP\fI<스레드수>\fP +활용할 작업 스레드 수를 지정합니다. \fI<스레드수>\fP ê°’ì„ \fB0\fP 값으로 설정하면, \fBxz\fP는 시스템ì—서 ì§€ì›í•˜ëŠ” +최대 프로세서 스레드 수를 ëª¨ë‘ í™•ë³´í•©ë‹ˆë‹¤. 실제 스레드 수는 ìž…ë ¥ 파ì¼ì´ 주어진 설정대로 스레드 처리를 í•  ë§Œí¼ ê·¸ë ‡ê²Œ í¬ì§€ ì•Šì„ +경우, 내지는 ë” ë§Žì€ ìŠ¤ë ˆë“œë¥¼ ì‚¬ìš©í–ˆì„ ë•Œ 메모리 사용량 한계를 초과할 경우 \fI<스레드수>\fP 보다 ì ì„ 수 있습니다. +.IP "" +단ì¼\-스레드와 다중\-스레드 ì••ì¶• í”„ë¡œê·¸ëž¨ì€ ë‹¤ë¥¸ 출력 ê²°ê³¼ë¬¼ì„ ëƒ…ë‹ˆë‹¤. 단ì¼\-스레드 ì••ì¶• í”„ë¡œê·¸ëž¨ì€ ìž‘ì€ íŒŒì¼ í¬ê¸° ê²°ê³¼ë¬¼ì„ ë‚´ë†“ì§€ë§Œ, +다중\-스레드 ì••ì¶• í”„ë¡œê·¸ëž¨ì˜ ê²½ìš° 다중\-스레드 ì••ì¶• 프로그램ì—서 ë‚´ë†“ì€ ê²°ê³¼ë¬¼ì€ ë‹¤ì¤‘\-스레드로만 ì••ì¶•ì„ í•´ì œí•  수 있습니다. +\fI<스레드수>\fP를 \fB1\fP로 설정하면 단ì¼\-스레드 모드를 사용합니다. \fI<스레드수>\fP를 \fB0\fPê³¼ 다른 +값으로 설정하면, 시스템ì—서 실제로 하드웨어 스레드가 1개만 ì§€ì›í•œë‹¤ 하ë”ë¼ë„, 다중\-스레드 ì••ì¶• í”„ë¡œê·¸ëž¨ì„ ì‚¬ìš©í•©ë‹ˆë‹¤. (\fBxz\fP +5.2.xì—서는 ì´ ê²½ìš° 단ì¼\-스레드 모드를 활용합니다.) +.IP "" +단ì¼\-스레드로 다중\-스레드 모드를 사용하려면, \fI<스레드수>\fP를 \fB+1\fP로 설정하십시오. \fB+\fP ì ‘ë‘사는 \fB1\fP +ì´ì™¸ì˜ ê°’ì—는 ì˜í–¥ì„ 주지 않습니다. 메모리 사용량 한계 ì„¤ì •ì€ \fBxz\fPì„ \fB\-\-no\-adjust\fP ì˜µì…˜ì„ ì“°ê¸° 전까지는 +단ì¼\-스레드로 전환하게 합니다. \fB+\fP ì ‘ë‘사 ì§€ì›ì€ \fBxz\fP 5.4.0ì— ì¶”ê°€í–ˆìŠµë‹ˆë‹¤. +.IP "" +ìžë™ 스레드 수를 요청했고 메모리 사용 한계를 지정하지 않았다면, ì‹œìŠ¤í…œì— ë§žê²Œë” ê°€ëŠ¥í•œ 스레드 수를 제한하는 기본 소프트 제한 ê°’ì„ +사용합니다. 스레드 수가 한개가 ë˜ë©´ 무시하는 ì´ëŸ° ê°œë…ì´ ì†Œí”„íŠ¸ 제한ì´ê¸°ì—, \fBxz\fP로 하여금 ì••ì¶• ë™ìž‘ ë° ì••ì¶• í•´ì œ ë™ìž‘ 수행시 +멈추지 않습니다. ì´ ê°€ë³¸ 소프트 제한 ê°’ì€ \fBxz\fP 실행 ë„중 다중\-스레드 모드ì—서 단ì¼\-스레드 모드로 바뀌게 하지는 않습니다. +활성 제한 ê°’ì€ \fBxz \-\-info\-memory\fP 명령으로 ë³¼ 수 있습니다. +.IP "" +현재 스레딩 처리 ë°©ì‹ì€ ìž…ë ¥ì„ ë¸”ë¡ ë‹¨ìœ„ë¡œ 쪼개고 ê°ê°ì˜ 블ë¡ì„ ë…립ì ìœ¼ë¡œ 압축하는 ë™ìž‘ì„ ì·¨í•©ë‹ˆë‹¤. 기본 ë¸”ë¡ í¬ê¸°ëŠ” ì••ì¶• ìˆ˜ì¤€ì— +ë”°ë¼ ë‹¤ë¥´ë©° \fB\-\-block\-size=\fP\fI<í¬ê¸°>\fP 옵션으로 재지정할 수 있습니다. +.IP "" +스레드 ì••ì¶• í•´ì œ ë°©ì‹ì€ 여러 블ë¡ì´ ë¸”ë¡ í—¤ë”ì— ë„£ì€ í¬ê¸° 정보와 함께 들어간 파ì¼ì—ë§Œ ë™ìž‘합니다. 다중\-스레드 모드ì—서 압축한 +충분히 í° ëª¨ë“  파ì¼ì€ ì´ ì¡°ê±´ì— ë§Œì¡±í•˜ì§€ë§Œ, 단ì¼\-스레드 모드ì—서 압축한 파ì¼ì€ +\fB\-\-block\-size=\fP\fI<í¬ê¸°>\fP ì˜µì…˜ì„ ì§€ì •í•˜ë”ë¼ë„ ì¡°ê±´ì— ë§Œì¡±í•˜ì§€ 않습니다. +.IP "" +\fI스레드\fP 기본 ê°’ì€ \fB0\fP입니다. \fBxz\fP 5.4.x ì´ì „ì˜ ê¸°ë³¸ê°’ì€ \fB1\fP입니다. +. +.SS "개별 ì••ì¶• í•„í„° ì²´ì¸ ì„¤ì •" +개별 í•„í„° ì²´ì¸ì€ 사전 ì„¤ì •ì— ì—®ì¸ ì„¤ì •ì— ì˜ì¡´í•˜ëŠ” 대신 ì••ì¶• ì„¤ì •ì„ ì„¸ë¶€ì ìœ¼ë¡œ 하나하나 설정할 수 있게 합니다. 개별 í•„í„° ì²´ì¸ì„ +지정하면, ëª…ë ¹í–‰ì— ì•žì„œ 지정한 사전 설정 옵션(\fB\-0\fP \&...\& \fB\-9\fP ê³¼ \fB\-\-extreme\fP)ì€ ë¬´ì‹œí•©ë‹ˆë‹¤. 사전 +설정 ì˜µì…˜ì„ í•˜ë‚˜ ì´ìƒì˜ í•„í„° ì²´ì¸ ì˜µì…˜ 다ìŒì— 지정하면, 새 사전 ì„¤ì •ì„ ì·¨í•˜ë©°, 앞서 지정한 개별 í•„í„° ì²´ì¸ ì˜µì…˜ì€ ë¬´ì‹œí•©ë‹ˆë‹¤. +.PP +í•„í„° ì²´ì¸ì€ 명령행 파ì´í•‘ì— ë¹„êµí•  수 있습니다. ì••ì¶•í•  때, 압축하지 ì•Šì€ ìž…ë ¥ì„ ì²«ë²ˆì§¸ 필터로 놓고, 출력 대ìƒ(ì´ ìžˆìœ¼ë©´)ì„ ë‹¤ìŒ +필터로 지정합니다. 최종 í•„í„°ì˜ ì¶œë ¥ì€ ì••ì¶• 파ì¼ë¡œ 기옥합니다. ì²´ì¸ì˜ 최대 í•„í„° 수는 4ì´ì§€ë§Œ, í•„í„° ì²´ì¸ìƒ í•„í„° 갯수는 보통 +1~2개입니다. +.PP +ìˆ˜ë§Žì€ í•„í„°ê°€ í•„í„° ì²´ì¸ ìƒì—서 제약ì ì„ 가지고 있습니다. ì¼ë¶€ 필터는 ì²´ì¸ì˜ 마지막 필터로만 ë™ìž‘하며, ì¼ë¶€ 다른 필터는 ë§ˆì§€ë§‰ì´ ì•„ë‹Œ +필터로, ì–´ë–¤ ë™ìž‘ì€ ì²´ì¸ì˜ ì–´ë–¤ 위치ì—ë“  둡니다. í•„í„°ì— ë”°ë¼, ì´ ì œí•œì€ í•„í„° 설계를 따르거나 보안 문제를 막기 위해 ì¡´ìž¬í•˜ê¸°ë„ +합니다. +.PP +개별 í•„í„° ì²´ì¸ì€ ë‘가지 ë°©ì‹ìœ¼ë¡œ 지정할 수 있습니다. \fB\-\-filters=\fP\fI<í•„í„°>\fP와 +\fB\-\-filters1=\fP\fI<í•„í„°>\fP \&...\& \fB\-\-filters9=\fP\fI<í•„í„°>\fP 옵션으로 +liblzma í•„í„° 문ìžì—´ ë¬¸ë²•ì— ë”°ë¼ í•œê°€ì§€ ì˜µì…˜ì„ í•„í„° ì²´ì¸ ì „ì²´ë¥¼ 지정할 수 있습니다. 대신, 하나 ì´ìƒì˜ 개별 í•„í„° ì˜µì…˜ì„ +ì›í•˜ëŠ” í•„í„° ì²´ì¸ ìˆœì„œëŒ€ë¡œ 지정할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. ì´ ë§ì¸ 즉슨, 개별 í•„í„° ì˜µì…˜ì˜ ìˆœì„œê°€ 중요하단 뜻입니다! ì›ì‹œ ìŠ¤íŠ¸ë¦¼ì„ ë””ì½”ë”©í•  +때(\fB\-\-format=raw\fP), ì••ì¶•í–ˆì„ ë•Œ ì§€ì •í–ˆë˜ í•„í„°ì™€ ê°™ì€ ìˆœì„œë¡œ í•„í„° ì²´ì¸ì„ 지정해야 합니다. ì „ì²´ ì²´ì¸ +옵션(\fB\-\-filters=\fP\fI<í•„í„°>\fP) 보다 ìš°ì„  지정한 개별 í•„í„° ë˜ëŠ” 사전 설정 ì˜µì…˜ì€ ê¹Œë¨¹ì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. +ì „ì²´ ì²´ì¸ ì˜µì…˜ 다ìŒì— 개별 필터를 지정할 경우 í•„í„° ì²´ì¸ì˜ ë™ìž‘ì„ ë¬´íš¨ë¡œ 합니다. +.PP +필터는 쉼표로 구분하는 필터별 \fI<옵션>\fPì´ ìžˆìŠµë‹ˆë‹¤. \fI<옵션>\fPì— ì¶”ê°€ë¡œ 입력한 쉼표는 +무시합니다. 모든 옵션 ê°’ì—는 ê¸°ë³¸ê°’ì´ ìžˆì–´, ê°’ì„ ë°”ê¾¸ë ¤ë©´ 지정해야합니다. +.PP +ì „ì²´ í•„í„° ì²´ì¸ê³¼ \fI<옵션>\fPì„ ë³´ë ¤ë©´ \fBxz \-vv\fP (\fB\-\-verbose\fP ë‘ ë²ˆ)ëª…ë ¹ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤. ì´ +ëª…ë ¹ì€ ì‚¬ì „ ì„¤ì •ì´ ì‚¬ìš©í•˜ëŠ” í•„í„° ì²´ì¸ ì˜µì…˜ë„ ë³¼ 수 있습니다. +.TP +\fB\-\-filters=\fP\fI<í•„í„°>\fP +ì „ì²´ í•„í„° ì²´ì¸ ë˜ëŠ” 사전 ì„¤ì •ì„ ë‹¨ì¼ ì˜µì…˜ìœ¼ë¡œ 지정합니다. ê° í•„í„°ëŠ” 공백 ë¬¸ìž ë˜ëŠ” 대시 ë¬¸ìž ë‘번 ìž…ë ¥(\fB\-\-\fP)으로 +구분합니다. ì…¸ 명령행ì—서 \fIí•„í„°\fP는 따옴표로 ê°ì‹¸ì„œ ë‹¨ì¼ ì˜µì…˜ìœ¼ë¡œ í•´ì„하ë„ë¡ í•´ì•¼ 합니다. \fI옵션\fPì„ í‘œê¸°í•˜ë ¤ë©´ \fB:\fP ë˜ëŠ” +\fB=\fPì„ í™œìš©í•˜ì‹­ì‹œì˜¤. 사전 설정 ì•žì— \fB\-\fP를 ë¶™ì¼ ìˆ˜ 있고 0ê°œ ë˜ëŠ” 하나 ì´ìƒì˜ 플래그를 ë¶™ì¼ ìˆ˜ 있습니다. 유ì¼í•˜ê²Œ +ì§€ì›í•˜ëŠ” 플래그는 \fB\-\-extreme\fPê³¼ ë™ì¼í•œ \fBe\fP입니다. +.TP +\fB\-\-filters1\fP=\fI<í•„í„°>\fP ... \fB\-\-filters9\fP=\fI<í•„í„°>\fP +\fB\-\-block\-list\fP와 사용할 수 있는 추가 í•„í„° ì²´ì¸ì„ 최대 9개까지 지정합니다. +.IP "" +예를 들어 í…스트 파ì¼ê³¼ 실행 파ì¼ì˜ ì•„ì¹´ì´ë¸Œë¥¼ ì••ì¶•í•  때 실행 ë¶€ë¶„ì— BCJ í•„í„° ì²´ì¸ì„ 사용하고 í…스트 ë¶€ë¶„ì€ LZMA2 필터를 +사용할 수 있습니다. +.TP +\fB\-\-filters\-help\fP +\fB\-\-filters\fP와 \fB\-\-filters1=\fP\fI<í•„í„°>\fP \&...\& +\fB\-\-filters9=\fP\fI<í•„í„°>\fP ì˜µì…˜ì˜ ì‚¬ì „ 설정 필터와 개별 설정 í•„í„° ì²´ì¸ì„ 지정하는 ë°©ë²•ì„ ì„¤ëª…í•˜ëŠ” ë„ì›€ë§ +메시지를 출력하고 완전히 빠져나갑니다. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fI<옵션>\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fI<옵션>\fP] +.PD +LZMA1 ë˜ëŠ” LZMA2 필터를 í•„í„° ì²´ì¸ì— 추가합니다. ì´ í•„í„°ëŠ” í•„í„° ì²´ì¸ì˜ 마지막 요소로만 사용할 수 있습니다. +.IP "" +LZMA1ì€ ê³ ì „ 필터로, LZMA1ë§Œ ì§€ì›í•˜ëŠ” ê³ ì „ \fB.lzma\fP íŒŒì¼ í˜•ì‹ì—서만 ì§€ì›í•©ë‹ˆë‹¤. LZMA2는 LZMA1ì˜ ì—…ë°ì´íЏ +버전으로 LZMA1ì˜ ì‹¤ì§ˆì  ë¬¸ì œë¥¼ 해결했습니다. \fB.xz\fP 형ì‹ì€ LZMA2 필터를 사용하며 LZMA1 필터는 ì „ì ìœ¼ë¡œ ì§€ì›í•˜ì§€ +않습니다. ì••ì¶• ì†ë„와 ì••ì¶•ìœ¨ì€ LZMA1ê³¼ LZMA2ê°€ 실질ì ìœ¼ë¡œ ë™ì¼í•©ë‹ˆë‹¤. +.IP "" +LZMA1ê³¼ LZMA2는 ë™ì¼í•œ \fI<옵션>\fP ì§‘í•©ì„ ê³µìœ í•©ë‹ˆë‹¤: +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fI<사전설정>\fP +LZMA1 ë˜ëŠ” LZMA2ì˜ ëª¨ë“  \fI<옵션>\fPì„ \fI<사전설정>\fP으로 +초기화합니다. \fI<사전설정>\fP ê°’ì€ ì •ìˆ˜ 값으로 ì´ë£¨ì–´ì ¸ 있으며, 사전 ì„¤ì •ì— ë³€í˜•ì„ ì¤„ ë–„ ë‹¨ì¼ ë¬¸ìžê°€ ë”°ë¼ì˜¬ ìˆ˜ë„ +있습니다. 정수 ê°’ì€ \fB0\fPì—서 \fB9\fP 까지ì´ë©°, 명령행 옵션ì—서 \fB\-0\fP \&...\& \fB\-9\fP로 대ì‘합니다. 변형 옵션으로 +ì§€ì›í•˜ëŠ” 문ìžëŠ” 현재 \fBe\fP ë¿ì´ë©°, \fB\-\-extreme\fPì— ëŒ€ì‘합니다. \fI<사전설정>\fP ê°’ì„ ì§€ì •í•˜ì§€ 않으면, +LZMA1 ë˜ëŠ” LZMA2 ê¸°ë³¸ê°’ì„ ì‚¬ì „ 설정 \fB6\fPì—서 가져온 \fI<옵션>\fP으로 취합니다. +.TP +\fBdict=\fP\fI<í¬ê¸°>\fP +딕셔너리(ê¸°ë¡ ë²„í¼) \fI<í¬ê¸°>\fP는 최근 처리한 비압축 ë°ì´í„°ë¥¼ ë°”ì´íЏ 단위로 ë©”ëª¨ë¦¬ì— ì–¼ë§ˆë‚˜ 유지하는지 나타냅니다. +ì•Œê³ ë¦¬ì¦˜ì€ ë¹„ì••ì¶• ë°ì´í„°ìƒ ë°”ì´íЏ 시퀀스(ì¼ì¹˜ 항목) 반복 íƒìƒ‰ì„ 시ë„하며, 해당 ë¶€ë¶„ì„ ë”•ì…”ë„ˆë¦¬ì˜ í˜„ìž¬ 참조로 치환합니다. 딕셔너리가 +í¬ë©´ ì¼ì¹˜í•˜ëŠ” í•­ëª©ì„ ì°¾ì„ ê¸°íšŒê°€ ë” ë§Žì•„ì§‘ë‹ˆë‹¤. ë”°ë¼ì„œ, 딕셔너리 \fI<í¬ê¸°>\fP를 ë”ìš± í¬ê²Œ 설정하면 ì••ì¶•ìœ¨ì„ ì¦ê°€í•  +수는 있지만, 압축하지 ì•Šì€ íŒŒì¼ë³´ë‹¤ 딕셔너리가 í¬ë©´ 메모리 ë‚­ë¹„ìœ¨ì´ ì˜¬ë¼ê°‘니다. +.IP "" +보통 딕셔너리 \fI<í¬ê¸°>\fP는 64KiB ì—서 64MiB ì •ë„ ë©ë‹ˆë‹¤. 최소 4KiB 입니다. 압축시 최대 ìš©ëŸ‰ì€ í˜„ìž¬ +1.5GiB(1536MiB)로 나타납니다. ì••ì¶• í•´ì œ 프로그램ì—ë„ 4GiB 미만으로 딕셔너리 í¬ê¸°ë¥¼ ì´ë¯¸ ì§€ì›í•˜ë©° 4GiB ë¼ëŠ” 수치는 +LZMA1ê³¼ LZMA2 스트림 형ì‹ì˜ 최대값입니다. +.IP "" +딕셔너리 \fI<í¬ê¸°>\fP와 검색기(\fImf\fP)는 LZMA1 ë˜ëŠ” LZMA ì¸ì½”ë”ì˜ ë©”ëª¨ë¦¬ ì‚¬ìš©ëŸ‰ì„ í•¨ê»˜ 결정합니다. +ë™ì¼í•œ(ë˜ëŠ” ë” í°) 딕셔너리 \fI<í¬ê¸°>\fPê°€ ë°ì´í„°ë¥¼ ì••ì¶•í–ˆì„ ë•Œë§Œí¼ ì••ì¶• 해제할 ë–„ 필요하기 때문ì—, 디코ë”ì˜ ë©”ëª¨ë¦¬ +ì‚¬ìš©ëŸ‰ì€ ì••ì¶•í•  ë•Œì˜ ë”•ì…”ë„ˆë¦¬ í¬ê¸°ë¡œ 결정합니다. \fB.xz\fP í—¤ë”ì—는 딕셔너리 \fI<í¬ê¸°>\fP를 2^\fIn\fP ë˜ëŠ” +2^\fIn\fP + 2^(\fIn\fP\-1) 으로 저장하기ì—, ì´ \fI<í¬ê¸°>\fP ê°’ì„ ì••ì¶•í•  때 선호하는 편입니다. 다른 +\fI<í¬ê¸°>\fP ê°’ì€ \fB.xz\fP í—¤ë”ì— ì €ìž¥í•  때 반올림합니다. +.TP +\fBlc=\fP\fIlc\fP +리터럴 컨í…스트 비트 수를 지정합니다. 최소 ê°’ì€ 0ì´ê³  최대 ê°’ì€ 4입니다. 기본 ê°’ì€ 3입니다. 추가로, \fIlc\fP ê°’ê³¼ +\fIlp\fP ê°’ì˜ í•©ì€ 4를 넘으면 안ë©ë‹ˆë‹¤. +.IP "" +ì¡°ê±´ì´ ì¼ì¹˜í•˜ì§€ 않아 ì¸ì½”딩할 수 없는 모든 ë°”ì´íŠ¸ëŠ” 리터럴로 ì¸ì½”딩합니다. ì´ ë§ì¸ 즉슨, 간단히 8비트 ë°”ì´íŠ¸ë¡œì„œì˜ ë¦¬í„°ëŸ´ì„ í•œë²ˆì— +하나씩 ì¸ì½”딩합니다. +.IP "" +리터럴 ì½”ë”©ì„ í•  때 ì´ì „ 비압축 ë°”ì´íŠ¸ì™€ ë‹¤ìŒ ë°”ì´íŠ¸ì™€ì˜ ê´€ë ¨ì„±ì„ ê°€ì§„ 가장 ë§Žì€ \fIlc\fP 비트 수를 가정합니다. 예를 들면, 보통 +ì˜ë¬¸ ë¬¸ìž¥ì˜ ê²½ìš° ëŒ€ë¬¸ìž ë‹¤ìŒì— 종종 소문ìžê°€ 오고, ì†Œë¬¸ìž ë‹¤ìŒì— 다른 소문ìžê°€ ë”°ë¼ì˜µë‹ˆë‹¤. US\-ASCII ë¬¸ìž ì„¸íŠ¸ì—서는 가장 긴 +비트 3개는 대문ìžì— 대해 010, 소문ìžì— 대해 011입니다. \fIlc\fP ê°’ì´ ìµœì†Œí•œ 3ì´ë©´, 리터럴 코딩시 비압축 ë°ì´í„°ì— 대해 +ì´ëŸ° ì†ì„±ì˜ 장ì ì„ 취할 수 있습니다. +.IP "" +(어쨌거나) 기본값 (3)ì€ ë³´í†µ ì ì ˆí•©ë‹ˆë‹¤. 최대 ì••ì¶•ì„ ì›í•œë‹¤ë©´ \fBlc=4\fP ê°’ì„ ì‹œí—˜í•´ë³´ì‹­ì‹œì˜¤. 때로는 약간 ë„ì›€ì´ ë˜ê¸°ë„ +하겠지만, 오히려 결과가 ì•ˆì¢‹ì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 결과가 엄한 방향으로 간다면, \fBlc=2\fP ê°’ë„ ì‹œí—˜í•´ë³´ì‹­ì‹œì˜¤. +.TP +\fBlp=\fP\fIlp\fP +리터럴 위치 비트 수를 지정하빈다. 최소 ê°’ì€ 0ì´ê³  최대 ê°’ì€ 4입니다. 기본 ê°’ì€ 0입니다. +.IP "" +\fIlp\fP ê°’ì€ ë¦¬í„°ëŸ´ ì¸ì½”딩 진행시 비압축 ë°ì´í„° ì •ë ¬ ë°©ì‹ ê³ ë ¤ì— ì˜í–¥ì„ ì¤ë‹ˆë‹¤. ì •ë ¬ ë°©ì‹ì— 대한 ìžì„¸í•œ 정보는 하단 \fIpb\fP를 +참고하십시오. +.TP +\fBpb=\fP\fIpb\fP +위치 비트 수를 지정합니다. 최소 ê°’ì€ 0ì´ë©° 최대 ê°’ì€ 4입니다. ê¸°ë³¸ê°’ì€ 2입니다. +.IP "" +\fIpb\fP ê°’ì€ ë³´í†µ 압축하지 ì•Šì€ ë°ì´í„°ì— ì–´ë–¤ ì •ë ¬ ë°©ì‹ì„ 고려하ëŠëƒì— ì˜í–¥ì„ ì¤ë‹ˆë‹¤. 기본ì ìœ¼ë¡œ 4ë°”ì´íЏ +ì •ë ¬(2^\fIpb\fP=2^2=4)ì„ ì˜ë¯¸í•˜ëŠ”ë°, ì´ë³´ë‹¤ ë” ë‚˜ì€ ì¶”ì¸¡ ê°’ì´ ì—†ì–´ì„œ 종종 최ì ì˜ ì„ íƒìœ¼ë¡œ 간주합니다. +.IP "" +ì •ë ¬ ìƒíƒœë¥¼ 알지 못할 경우, \fIpb\fP 설정 ê°’ì´ íŒŒì¼ í¬ê¸°ë¥¼ 조금 ì¤„ì¼ ìˆ˜ 있습니다. 예를 들면, í…스트 파ì¼ì´ ë‹¨ì¼ ë°”ì´íЏ 단위로 +ì •ëˆëœ ìƒíƒœ(US\-ASCII, ISO\-8859\-*, UTF\-8)ë¼ë©´, \fBpb=0\fP 설정 값으로 ì••ì¶•ìœ¨ì„ ì¡°ê¸ˆ 개선할 수 있습니다. +UTF\-16 í…ìŠ¤íŠ¸ì˜ ê²½ìš°, \fBpb=1\fP 설정 ê°’ì´ ì¢‹ì€ ì„ íƒìž…니다. ì •ë ¬ ë°”ì´íŠ¸ê°€ 3 ë°”ì´íЏ ê°™ì€ í™€ìˆ˜ ë°”ì´íŠ¸ì¼ ê²½ìš°, +\fBpb=0\fP 설정 ê°’ì´ ìµœì ì˜ ì„ íƒì¼ì§€ë„ 모릅니다. +.IP "" +가정 ì •ë ¬ì„ \fIpb\fP ê°’ê³¼ \fIlp\fP 값으로 조정하긴 하지만, LZMA1ê³¼ LZMA2는 여전히 16ë°”ì´íЏ ì •ë ¬ ë°©ì‹ìœ¼ë¡œ 선호합니다. +LZMA1 ë˜ëŠ” LZMA2로 종종 압축하는 íŒŒì¼ í˜•ì‹ì´ë¼ê³  하면 고려해볼만 합니다. +.TP +\fBmf=\fP\fImf\fP +ì¼ì¹˜ 검색기는 ì¸ì½”ë” ì†ë„, 메모리 사용량, ì••ì¶•ìœ¨ì— ì£¼ëœ ì˜í–¥ì„ ì¤ë‹ˆë‹¤. 보통 해시 ì²´ì¸ ê²€ìƒ‰ê¸°ëŠ” ì´ì§„ 트리 검색기보다 빠르긴 +합니다. 기본 ê°’ì€ \fI<사전설정>\fPì— ë”°ë¼ ë‹¤ë¦…ë‹ˆë‹¤. 0ì€ \fBhc3\fPì„, 1\(en3ì€ \fBhc4\fP를, 나머지는 +\fBbt4\fP를 활용합니다. +.IP "" +ë‹¤ìŒ ê²€ìƒ‰ 필터를 ì§€ì›í•©ë‹ˆë‹¤. 메모리 사용 ê³µì‹ì€ \fIdict\fP ê°’ì´ 2ì˜ ìŠ¹ìˆ˜ì¼ ê²½ìš° ì‹¤ì œì— ê°€ê¹Œìš´ 근사치입니다. +.RS +.TP +\fBhc3\fP +2ë°”ì´íЏ, 3ë°”ì´íЏ 해싱 ì²´ì¸ +.br +\fInice\fP 최소값: 3 +.br +메모리 사용: +.br +\fIdict\fP * 7.5 (ì¡°ê±´: \fIdict\fP <= 16 MiB); +.br +\fIdict\fP * 5.5 + 64 MiB (ì¡°ê±´: \fIdict\fP > 16 MiB) +.TP +\fBhc4\fP +2ë°”ì´íЏ, 3ë°”ì´íЏ, 4ë°”ì´íЏ 해싱 ì²´ì¸ +.br +\fInice\fP 최소값: 4 +.br +메모리 사용: +.br +\fIdict\fP * 7.5 (ì¡°ê±´: \fIdict\fP <= 32 MiB); +.br +\fIdict\fP * 6.5 (ì¡°ê±´: \fIdict\fP > 32 MiB) +.TP +\fBbt2\fP +2ë°”ì´íЏ 해싱 ì´ì§„ 트리 +.br +\fInice\fP 최소값: 2 +.br +메모리 사용: \fIdict\fP * 9.5 +.TP +\fBbt3\fP +2ë°”ì´íЏ, 3ë°”ì´íЏ 해싱 ì´ì§„트리 +.br +\fInice\fP 최소값: 3 +.br +메모리 사용: +.br +\fIdict\fP * 11.5 (ì¡°ê±´: \fIdict\fP <= 16 MiB); +.br +\fIdict\fP * 9.5 + 64 MiB (ì¡°ê±´: \fIdict\fP > 16 MiB) +.TP +\fBbt4\fP +2ë°”ì´íЏ, 3ë°”ì´íЏ, 4ë°”ì´íЏ 해싱 ì´ì§„ 트리 +.br +\fInice\fP 최소값: 4 +.br +메모리 사용: +.br +\fIdict\fP * 11.5 (ì¡°ê±´: \fIdict\fP <= 32 MiB); +.br +\fIdict\fP * 10.5 (ì¡°ê±´: \fIdict\fP > 32 MiB) +.RE +.TP +\fBmode=\fP\fI<모드>\fP +ì••ì¶• \fI<모드>\fP ê°’ì€ ì¼ì¹˜ 검색기ì—서 ìƒì‚°í•˜ëŠ” ë°ì´í„° ë¶„ì„ ë°©ì‹ì„ 지정합니다. ì§€ì›í•˜ëŠ” \fI<모드>\fP는 +\fBfast\fP와 \fBnormal\fP 입니다. ê¸°ë³¸ê°’ì€ \fI<사전설정>\fPê°’ 0\(en3ì— ëŒ€í•´ \fBfast\fP, +\fI<사전설정>\fPê°’ 4\(en9ì— ëŒ€í•´ \fBnormal\fP입니다. +.IP "" +보통 \fBfast\fP는 해시 ì²´ì¸ ê²€ìƒ‰ê¸°ì—서 사용하며 \fBnormal\fPì€ ì´ì§„ 트리 검색기ì—서 사용합니다. ì´ ë™ìž‘ì€ ë˜í•œ +\fI<사전설정>\fP ê°’ì´ í•  ì¼ì´ê¸°ë„ 합니다. +.TP +\fBnice=\fP\fInice\fP +ì¼ì¹˜í•˜ëŠ” nice 길ì´ë¥¼ 지정합니다. 최소한 \fInice\fP ë°”ì´íЏ ì •ë„ ì¼ì¹˜í•˜ë©´, ì•Œê³ ë¦¬ì¦˜ì´ ê°€ëŠ¥í•œ ìµœì„ ì˜ ë¶€ë¶„ì„ ì°¾ëŠ” ë™ìž‘ì„ +멈춥니다. +.IP "" +\fInice\fP ê°’ì€ 2\(en273 ë°”ì´íŠ¸ìž…ë‹ˆë‹¤. ê°’ì´ í´ ìˆ˜ë¡ ì†ë„ ë©´ì—서는 ì†í•´ë¥¼ 보겠지만 ì••ì¶•ìœ¨ì€ ë”ìš± 올ë¼ê°‘니다. 기본 ê°’ì€ +\fI<사전설정>\fPê°’ì— ë”°ë¼ ë‹¤ë¦…ë‹ˆë‹¤. +.TP +\fBdepth=\fP\fI<깊ì´>\fP +ì¼ì¹˜ 검색기ì—ì„œì˜ ìµœëŒ€ 검색 깊ì´ë¥¼ 지정합니다. ê¸°ë³¸ê°’ì€ íŠ¹ë³„í•œ ê°’ 0으로 지정하며, ì´ ê°’ìœ¼ë¡œ ì••ì¶• í”„ë¡œê·¸ëž¨ì´ \fImf\fP 와 +\fInice\fPê°„ ì ì ˆí•œ \fI<깊ì´>\fP ê°’ì„ ê²°ì •í•©ë‹ˆë‹¤. +.IP "" +ì ì ˆí•œ 해시 ì²´ì¸ \fI<깊ì´>\fP ê°’ì€ ì´ì§„ 트리ì—서 4\(en100 그리고 16\(en1000 입니다. ìƒë‹¹ížˆ í° ê°’ì„ +\fI<깊ì´>\fP 값으로 사용하면 ì¼ë¶€ 파ì¼ì— 대해 ì¸ì½”ë”ê°€ 매우 ëŠë¦¬ê²Œ ë™ìž‘í•  수가 있습니다. ì••ì¶• ì‹œê°„ì´ ë„ˆë¬´ 오래걸려서 +ë™ìž‘ì„ ì¤‘ê°„ì— ëŠì„ 준비가 ë˜ì§€ ì•Šì€ ì´ìƒ \fI<깊ì´>\fP 설정 ê°’ì€ 1000ì„ ë„˜ì§€ 않게하십시오. +.RE +.IP "" +ì›ì‹œ 스트림(\fB\-\-format=raw\fP)ì„ ë””ì½”ë”©í•  때, LZMA2는 딕셔너리 \fI<í¬ê¸°>\fPë§Œ 필요합니다. LZMA1는 +\fIlc\fP, \fIlp\fP, \fIpb\fP ê°’ì´ ëª¨ë‘ í•„ìš”í•©ë‹ˆë‹¤. +.TP +\fB\-\-x86\fP[\fB=\fP\fI<옵션>\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fI<옵션>\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fI<옵션>\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fI<옵션>\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fI<옵션>\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fI<옵션>\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fI<옵션>\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIoptions\fP] +.PD +브랜치/호출/ì í”„(BCJ) 필터를 í•„í„° ì²´ì¸ì— 추가합니다. ì´ í•„í„°ëŠ” í•„í„° ì²´ì¸ì˜ 비종결 필터로만 사용할 수 있습니다. +.IP "" +BCJ 필터는 머신 ì½”ë“œì˜ ìƒëŒ€ 주소를 절대 주소로 변환합니다. ë°ì´í„° í¬ê¸°ë¥¼ 바꾸지는 않지만 LZMA2ì—서 \fB.xz\fP 파ì¼ì„ +0\(en15% ì •ë„ ì¤„ì—¬ì£¼ê²Œ 하는 ì¤‘ë³µì„±ì´ ëŠ˜ì–´ë‚©ë‹ˆë‹¤. BCJ 필터는 언제든 ë’¤ì§‘ì„ ìˆ˜ 있어, ë°ì´í„°ì— ì ì ˆí•˜ì§€ ì•Šì€ BCJ í•„í„° +형ì‹ì„ 활용하면, 그냥 가만히 ë‘ë©´ ì••ì¶•ìœ¨ì´ ì•½ê°„ 떨어지게 한다 하ë”ë¼ë„, ë°ì´í„°ë¥¼ ìžƒì„ ìˆ˜ê°€ 있습니다. BCJ 필터는 굉장히 빠르며 +메모리 ê³µê°„ì„ ì ê²Œ 활용합니다. +.IP "" +ì´ BCJ í•„í„°ì—는 압축율 관련 몇가지 문제가 있습니다: +.RS +.IP \(bu 3 +실행 코드가 들어있는 몇가지 íŒŒì¼ í˜•ì‹(예: ëª©ì  íŒŒì¼, ì •ì  ë¼ì´ë¸ŒëŸ¬ë¦¬, 리눅스 ì»¤ë„ ëª¨ë“ˆ)ì˜ ê²½ìš° í•„í„° 값으로 채운 명령 주소가 +있습니다. 여기 BCJ í•„í„°ì˜ ê²½ìš° 파ì¼ì˜ ì••ì¶•ìœ¨ì„ ë–¨ì–´ëœ¨ë¦¬ëŠ” 주소 ë³€í™˜ì„ ìˆ˜í–‰í•©ë‹ˆë‹¤. +.IP \(bu 3 +BCJ 필터를 ì•„ì¹´ì´ë¸Œì— ì ìš©í•˜ë©´, BCJ 필터를 사용하지 ì•Šì•˜ì„ ë•Œë³´ë‹¤ ì••ì¶•ìœ¨ì´ ë–¨ì–´ì§ˆ 수가 있습니다. 예를 들면, 유사하거나 ë™ì¼í•œ +실행 íŒŒì¼ ì—¬ëŸ¿ì´ ìžˆìœ¼ë©´ 필터를 사용하여 파ì¼ì„ ëœ ë¹„ìŠ·í•˜ê²Œ 만들어 ì••ì¶•ìœ¨ì´ ë–¨ì–´ì§€ê²Œ 합니다. ë™ì¼í•œ ì•„ì¹´ì´ë¸Œ 파ì¼ì—서 비 실행 파ì¼ì˜ +ë‚´ìš©ì— ëŒ€í•´ì„œë„ ë¹„ìŠ·í•œ ì¼ì´ 벌어질 수 있습니다. 실제로 하나는 BCJ 필터를 걸고 하나는 제외하여 ê° ê²½ìš°ì— ëŒ€í•´ ì–´ë–¤ 경우가 결과가 +우수한 ì§€ 살펴보겠습니다. +.RE +.IP "" +다른 명령 세트는 다른 ì •ë ¬ ìƒíƒœì— 놓여있습니다. 실행 파ì¼ì€ í•„í„°ê°€ 제대로 ë™ìž‘하게 하려면 ìž…ë ¥ ë°ì´í„°ì— 있는 ì´ ê°’ì˜ ë°°ìˆ˜ë¡œ +ì •ëˆí•´ì•¼í•©ë‹ˆë‹¤. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +í•„í„°;ì •ë ¬;참고 +x86;1;32\-bit ë˜ëŠ” 64\-bit x86 +ARM;4; +ARM\-Thumb;2; +ARM64;4;4096 ë°”ì´íЏ ì •ë ¬ì´ ê°€ìž¥ 좋습니다 +PowerPC;4;빅엔디안 ì „ìš© +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +BCJ 필터를 사용한 ë°ì´í„°ëŠ” LZMA2로 보통 압축하기 ë•Œë¬¸ì— LZMA2 ì˜µì…˜ì„ ì„ íƒí•œ BCJ í•„í„°ì˜ ì •ë ¬ê¸°ì¤€ì— ë§žì¶”ë„ë¡ ì„¤ì •í•˜ë©´ +ì••ì¶•ìœ¨ì„ ì¢€ ë” ê°œì„ í•  수 있습니다. 예를 들면: +.RS +.IP \(bu 3 +IA\-64 필터는 16\-ë°”ì´íЏ ì •ë ¬ ë°©ì‹ìœ¼ë¡œ ë™ìž‘í•˜ê¸°ì— LZMA2 í•„í„°ì— \fBpb=4,lp=4,lc=0\fP 옵션(2^4=16)ì„ ì£¼ëŠ”ê²Œ +좋습니다. +.IP \(bu 3 +RISC\-V 코드ì—는 16\-비트 ì••ì¶• 명령(C 확장) ì ìž¬ ì—¬ë¶€ì— ë”°ë¼ 2\-ë°”ì´íЏ ë˜ëŠ” 4\-ë°”ì´íЏ ì •ë ¬ ë°©ì‹ì„ 채íƒí•©ë‹ˆë‹¤. 16\-비트 +ëª…ë ¹ì„ ì‚¬ìš©í•˜ë©´, \fBpb=2,lp=1,lc=3\fP ë˜ëŠ” \fBpb=1,lp=1,lc=3\fP 옵션 ê°’ ì‚¬ìš©ì´ ë°”ëžŒì§í•©ë‹ˆë‹¤. 16\-비트 ëª…ë ¹ì´ +없다면, \fBpb=2,lp=2,lc=2\fP 옵션 ê°’ì„ í™œìš©í•˜ëŠ”ê²Œ 좋습니다. "RVC"ê°€ "Flags"í–‰ì— ë‚˜íƒ€ë‚˜ëŠ”ì§€ 확ì¸í•  때 +\fBreadelf \-h\fP ëª…ë ¹ì„ ì‚¬ìš©í•  수 있습니다. +.IP \(bu 3 +ARM64는 í•­ìƒ 4\-ë°”ì´íЏ ì •ë ¬ ë°©ì‹ì„ íƒí•˜ê¸°ì— \fBpb=2,lp=2,lc=2\fP 옵션 ê°’ì„ í™œìš©í•˜ëŠ”ê²Œ 좋습니다. +.IP \(bu 3 +x86 필터는 예외입니다. x86 실행 파ì¼ì„ ì••ì¶•í•  경우ì—는 보통 LZMA2 기본 옵션 ê°’(\fBpb=2,lp=0,lc=3\fP)ì„ ê·¸ëŒ€ë¡œ +사용하는게 좋습니다. +.RE +.IP "" +모든 BCJ 필터는 ë™ì¼í•œ \fI옵션\fPì„ ì§€ì›í•©ë‹ˆë‹¤: +.RS +.TP +\fBstart=\fP\fI<오프셋>\fP +ìƒëŒ€ 주소와 절대 주소를 변환할 때 사용할 시작 \fI<오프셋>\fPì„ ì§€ì •í•©ë‹ˆë‹¤. \fI<오프셋>\fPì—는 í•„í„° +ì •ë ¬ 배수여야 합니다(ìƒë‹¨ í…Œì´ë¸” 참조). ê¸°ë³¸ê°’ì€ 0입니다. 실제로 ê¸°ë³¸ê°’ì´ ë‚«ìŠµë‹ˆë‹¤. 개별 \fI<오프셋>\fP 지정 +ê°’ì€ ê±°ì˜ ì“¸ëª¨ê°€ 없습니다. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fI<옵션>\fP] +í•„í„° ì²´ì¸ì— ë¸íƒ€ 필터를 추가합니다. ë¸íƒ€ 필터는 í•„í„° ì²´ì¸ì—서 ë§ˆì§€ë§‰ì— ì§€ì •í•˜ì§€ ì•Šì€ í•„í„°ë¡œë§Œ 사용할 수 있습니다. +.IP "" +현재로서는 ë°”ì´íЏ 단위 단순 ë¸íƒ€ê³„ì‚° 결과만 ë³´ì—¬ì¤ë‹ˆë‹¤. 예를 들면, 압축하지 ì•Šì€ ë¹„íŠ¸ë§µ 그림 ë˜ëŠ” 압축하지 ì•Šì€ PCM 오디오를 +ì••ì¶•í•  때 쓸만합니다. 그러나 특별한 목ì ìœ¼ë¡œ 활용하는 ì•Œê³ ë¦¬ì¦˜ì€ ë¸íƒ€ + LZMA2 보다 ë” ë‚˜ì€ ê²°ê³¼ë¥¼ 가져다 ì£¼ê¸°ë„ í•©ë‹ˆë‹¤. +ì´ëŠ” 특히 ì˜¤ë””ì˜¤ì˜ ê²½ìš° 맞는 ì´ì•¼ê¸°ì¸ë°, \fBflac\fP(1)ì˜ ê²½ìš° ë” ë¹ ë¥´ê³  우수한 ì••ì¶•ìœ¨ì„ ë³´ì—¬ì¤ë‹ˆë‹¤. +.IP "" +ì§€ì› \fI옵션\fP: +.RS +.TP +\fBdist=\fP\fI<ì°¨ì´>\fP +ë°”ì´íЏ 단위 ë¸í„° 계산 \fI<ì°¨ì´>\fP를 지정합니다. \fI<ì°¨ì´>\fPê°’ì€ 1\(en256 ì´ì–´ì•¼í•©ë‹ˆë‹¤. 기본 +ê°’ì€ 1입니다. +.IP "" +예를 들어, \fBdist=2\fP 옵션과 A1 B1 A2 B3 A3 B5 A4 B7 ìž…ë ¥ ê°’ì„ ì£¼ë©´, 출력 ê°’ì€ A1 B1 01 02 01 +02 01 02 입니다. +.RE +. +.SS "기타 옵션" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +경고 ë° ì•Œë¦¼ì„ ë•니다. ë‘ ë²ˆ 지정하면 오류 메시지 í‘œì‹œë„ ë•니다. ì´ ì˜µì…˜ì€ ì¢…ë£Œ ìƒíƒœì— ì˜í–¥ì„ 주지 않습니다. 경고 표시를 +ë„ë”ë¼ë„, 종료 ìƒíƒœì—서는 여전히 경고가 나타났ìŒì„ 알려ì¤ë‹ˆë‹¤. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +출력 ë‚´ìš©ì´ ë§Žì•„ì§‘ë‹ˆë‹¤. 표준 오류를 터미ë„ì— ì—°ê²°í–ˆë‹¤ë©´ \fBxz\fP는 ì§„í–‰ 표시를 나타냅니다. \fB\-\-verbose\fP를 ë‘번 지정하면 +ë” ë§Žì€ ë‚´ìš©ì„ í‘œì‹œí•©ë‹ˆë‹¤. +.IP "" +ì§„í–‰ 표시ì—서는 ë‹¤ìŒ ì •ë³´ë¥¼ 나타냅니다: +.RS +.IP \(bu 3 +ìž…ë ¥ 파ì¼ì˜ í¬ê¸°ë¥¼ 알고 ìžˆì„ ê²½ìš° 완료 백분율. 파ì´í”„ 처리시ì—는 ë°±ë¶„ìœ¨ì„ ë‚˜íƒ€ë‚¼ 수 없습니다. +.IP \(bu 3 +ì‚°ì¶œ ì••ì¶• ë°ì´í„° 용량 (ì••ì¶•) ë˜ëŠ” 소모 공간 용량 (ì••ì¶• í•´ì œ). +.IP \(bu 3 +비압축 ë°ì´í„° 소모 용량 (ì••ì¶•) ë˜ëŠ” ì‚°ì¶œ 용량 (ì••ì¶• í•´ì œ). +.IP \(bu 3 +ì••ì¶• ë°ì´í„° ì‚°ì¶œ ìš©ëŸ‰ì„ ë¹„ì••ì¶• ë°ì´í„° 처리 용량으로 나누어 계산한 압축율. +.IP \(bu 3 +ì••ì¶• ë˜ëŠ” ì••ì¶• í•´ì œ ì†ë„. 초당 비압축 ë°ì´í„° 소모량(ì••ì¶•) ë˜ëŠ” ì‚°ì¶œ 용량(ì••ì¶• í•´ì œ)를 측정한 값입니다. \fBxz\fPì—서 íŒŒì¼ +처리를 시작한 몇 ì´ˆ 후 나타납니다. +.IP \(bu 3 +경과 시간 형ì‹ì€ M:SS ë˜ëŠ” H:MM:SS 입니다. +.IP \(bu 3 +추산 여분 ì‹œê°„ì€ \fBxz\fPê°€ 파ì¼ì„ 처리하기 시작한 ì´í›„ ìž…ë ¥ 파ì¼ì˜ í¬ê¸°ë¥¼ 알고 몇 초가 지난 후ì—야 ë³´ì—¬ì¤ë‹ˆë‹¤. ì‹œê°„ì€ ì½œë¡  +문ìžë¥¼ 사용하지 않고 ëœ ìžì„¸í•œ 형ì‹ìœ¼ë¡œ, 예를 들면, 2ë¶„ 30ì´ˆ 와 ê°™ì€ í˜•ì‹ìœ¼ë¡œ ë³´ì—¬ì¤ë‹ˆë‹¤. +.RE +.IP "" +표준 오류가 터미ë„ì´ ì•„ë‹ˆë¼ë©´ \fB\-\-verbose\fP는 \fBxz\fPì—서 íŒŒì¼ ì´ë¦„, ì••ì¶• í¬ê¸°, ì••ì¶• í•´ì œ 용량, 압축율, 그리고 +가능하다면 파ì¼ì„ ì••ì¶• ë˜ëŠ” ì••ì¶• 해제한 후 표준 오류로 ì†ë„와 걸린 ì‹œê°„ì„ ë‚˜íƒ€ë‚´ë„ë¡ í•©ë‹ˆë‹¤. ì†ë„와 걸린 시간 정보는 ë™ìž‘ì„ +ì²˜ë¦¬í•˜ëŠ”ë° ìµœì†Œí•œ 몇초 ì •ë„ ì†Œìš”í–ˆì„ ê²½ìš°ì—ë§Œ 들어갑니다. ë™ìž‘ì´ ë나지 않았다면, ì´ë¥¼í…Œë©´ 사용ìžì˜ 중단 ìš”ì²­ì´ ìžˆì—ˆì„ ê²½ìš° ìž…ë ¥ +파ì¼ì˜ í¬ê¸°ë¥¼ 알고 ìžˆì„ ë•Œ ì••ì¶• 백분율 ì •ë³´ë„ ë“¤ì–´ê°‘ë‹ˆë‹¤. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +경고로 알릴 만한 ìƒí™©ì„ 만났다 하ë”ë¼ë„ 종료 ìƒíƒœ 2ë²ˆì„ ì„¤ì •í•˜ì§€ 않습니다. ì´ ì˜µì…˜ì€ ì¶œë ¥ ìˆ˜ì¤€ì— ì˜í–¥ì„ 주지 않기 때문ì—, +\fB\-\-quiet\fP 옵션과 \fB\-\-no\-warn\fP ì˜µì…˜ì„ ê²½ê³  표시를 막고 종료 ìƒíƒœë¥¼ 바꾸지 ì•Šì„ ëª©ì ìœ¼ë¡œ 사용합니다. +.TP +\fB\-\-robot\fP +머신ì—서 í•´ì„í•  형ì‹ìœ¼ë¡œ 메시지를 나타냅니다. liblzma 대신 \fBxz\fP를 활용하려는 ë‹¤ì–‘ìƒ ìŠ¤í¬ë¦½íŠ¸ë¡œì„œì˜ í”„ë¡ íŠ¸ì—”ë“œë¥¼ 쉽게 +작성하ë„ë¡ í•˜ê¸° 위함입니다. ì´ ì˜µì…˜ì„ ì§€ì •í•œ ì¶œë ¥ì€ \fBxz\fP 릴리스가 어떻게 ë˜ë“  안정 버전ì´ëž€ ì˜ë¯¸ìž…니다. ìžì„¸í•œ ë‚´ìš©ì€ +\fB로봇 모드\fP ì„¹ì…˜ì„ ì°¸ê³ í•˜ì‹­ì‹œì˜¤. +.TP +\fB\-\-info\-memory\fP +ì••ì¶• ë° ì••ì¶• 해제시 물리 메모리 용량 (RAM), \fBxz\fPì—서 파악하는 프로세서 스레드 갯수, 메모리 사용량 한계를 파악하기 쉬운 +형ì‹ìœ¼ë¡œ 나타내고 무사히 나갑니다. +.TP +\fB\-h\fP, \fB\-\-help\fP +보통 사용하는 ì˜µì…˜ì„ ì„¤ëª…í•˜ëŠ” ë„ì›€ë§ ë©”ì‹œì§€ë¥¼ 출력한 후, 완전히 빠져나갑니다. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +\fBxz\fPì˜ ëª¨ë“  ê¸°ëŠ¥ì„ ì„¤ëª…í•˜ëŠ” ë„ì›€ë§ ë©”ì‹œì§€ë¥¼ 출력한 후, 완전히 빠져나갑니다 +.TP +\fB\-V\fP, \fB\-\-version\fP +\fBxz\fP와 liblzma 버전 번호를 ê°€ë… í˜•ì‹ìœ¼ë¡œ 출력합니다. 기계 í•´ì„ ê°€ëŠ¥ 형ì‹ì„ 가져오려면 \fB\-\-version\fP ì•žì— +\fB\-\-robot\fPì„ ì§€ì •í•˜ì‹­ì‹œì˜¤. +. +.SH "로봇 모드" +로봇 모드는 \fB\-\-robot\fP 옵션으로 ë™ìž‘합니다. \fBxz\fP ì¶œë ¥ì„ ë‹¤ë¥¸ 프로그램ì—서 í•´ì„하기 쉽게 í•´ì¤ë‹ˆë‹¤. 현재로서는 +\fB\-\-robot\fP ì˜µì…˜ì€ \fB\-\-list\fP, \fB\-\-filters\-help\fP, \fB\-\-info\-memory\fP, \fB\-\-version\fP +옵션하고만 사용할 수 있습니다. 앞으로는 ì••ì¶• ë° ì••ì¶• í•´ì œ ë™ìž‘ì— ëŒ€í•´ì„œë„ ì§€ì›í•©ë‹ˆë‹¤. +. +.SS "ëª©ë¡ ëª¨ë“œ" +\fBxz \-\-robot \-\-list\fP ëª…ë ¹ì€ íƒ­ìœ¼ë¡œ 구분한 출력 형태를 활용합니다. 모든 í–‰ì˜ ì²«ë²ˆì§¸ 컬럼ì—는 해당 í–‰ì—서 ì°¾ì„ ìˆ˜ +있는 ì •ë³´ì˜ í˜•ì‹ì„ 나타냅니다: +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP +ì´ í–‰ì€ í•­ìƒ íŒŒì¼ ëª©ë¡ ì‹œìž‘ ë¶€ë¶„ì˜ ì²«ë²ˆì§¸ ì¤„ì— ìžˆìŠµë‹ˆë‹¤. ì´ í–‰ì˜ ë‘번째 ì»¬ëŸ¼ì— íŒŒì¼ ì´ë¦„ì´ ë“¤ì–´ìžˆìŠµë‹ˆë‹¤. +.TP +\fBfile\fP +ì´ í–‰ì—는 \fB.xz\fP 파ì¼ì˜ ì „ë°˜ì ì¸ ì •ë³´ê°€ 들어있습니다. ì´ í–‰ì€ í•­ìƒ \fBname\fP í–‰ 다ìŒì— 있습니다. +.TP +\fBstream\fP +ì´ í–‰ 형ì‹ì€ \fB\-\-verbose\fP ì˜µì…˜ì„ ì§€ì •í–ˆì„ ë•Œë§Œ 사용합니다. \fB.xz\fP 파ì¼ì˜ \fBstream\fP í–‰ ìˆ˜ë§Œí¼ ë‚˜íƒ€ë‚©ë‹ˆë‹¤. +.TP +\fBblock\fP +ì´ í–‰ 형ì‹ì€ \fB\-\-verbose\fP ì˜µì…˜ì„ ì§€ì •í–ˆì„ ë•Œë§Œ 사용합니다. \fB.xz\fP 파ì¼ì˜ ë¸”ë¡ ìˆ˜ë§Œí¼ \fBblock\fP í–‰ì´ +나타납니다. \fBblock\fP í–‰ì€ ëª¨ë“  \fBstream\fP í–‰ 다ìŒì— 나타납니다. 다른 형ì‹ì˜ í–‰ì´ ë¼ì–´ë“¤ì§€ëŠ” 않습니다. +.TP +\fBsummary\fP +ì´ í–‰ 형ì‹ì€ \fB\-\-verbose\fP ì˜µì…˜ì„ ë‘번 ì§€ì •í–ˆì„ ë•Œë§Œ 사용합니다. ì´ í–‰ì€ ëª¨ë“  \fBblock\fP í–‰ 다ìŒì— 출력합니다. +\fBfile\fP 행과 비슷하게, \fBsummary\fP í–‰ì—는 \fB.xz\fP 파ì¼ì˜ ì „ë°˜ì ì¸ ì •ë³´ê°€ 담겨있습니다. +.TP +\fBtotals\fP +ì´ í–‰ì€ ëª©ë¡ ì¶œë ¥ì˜ ê°€ìž¥ ë§ˆì§€ë§‰ì— í•­ìƒ ë‚˜íƒ€ë‚©ë‹ˆë‹¤. ì´ ê°¯ìˆ˜ì™€ í¬ê¸°ë¥¼ 나타냅니다. +.PP +\fBfile\fP í–‰ 컬럼: +.PD 0 +.RS +.IP 2. 4 +íŒŒì¼ ìŠ¤íŠ¸ë¦¼ 갯수 +.IP 3. 4 +ìŠ¤íŠ¸ë¦¼ì˜ ë¸”ë¡ ì´ ê°¯ìˆ˜ +.IP 4. 4 +íŒŒì¼ ì••ì¶• í¬ê¸° +.IP 5. 4 +íŒŒì¼ ì••ì¶• í•´ì œ í¬ê¸° +.IP 6. 4 +예를 들면, \fB0.123\fPê³¼ ê°™ì€ ì••ì¶•ìœ¨ 입니다. ë¹„ìœ¨ì´ 9.999ë¼ë©´, 대시 ë¬¸ìž 3ê°œ (\fB\-\-\-\fP)를 비율 ê°’ 대신 나타냅니다. +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +쉼표로 구분한 무결성 검사 ì´ë¦„ 목ë¡ìž…니다. \fBNone\fP, \fBCRC32\fP, \fBCRC64\fP, \fBSHA\-256\fP 문ìžì—´ì„ 알려진 +검사 형ì‹ìœ¼ë¡œ 사용합니다. 알 수 없는 검사 형ì‹ì— 대해서는 \fBUnknown\-\fP\fIN\fPì„ ì‚¬ìš©í•˜ë©°, 여기서 \fIN\fPì€ (한 ë‘ìžë¦¬) +정수형 숫ìžê°’으로 ì´ë£¨ì–´ì§„ 검사 ID 입니다. +.IP 8. 4 +파ì¼ì˜ 스트림 패딩 ì´ ê¸¸ì´ +.RE +.PD +.PP +\fBstream\fP í–‰ 컬럼: +.PD 0 +.RS +.IP 2. 4 +스트림 번호 (첫 ìŠ¤íŠ¸ë¦¼ì€ 1번) +.IP 3. 4 +ìŠ¤íŠ¸ë¦¼ì˜ ë¸”ë¡ ì´ ê°¯ìˆ˜ +.IP 4. 4 +ì••ì¶• 시작 오프셋 +.IP 5. 4 +비압축 시작 오프셋 +.IP 6. 4 +ì••ì¶• í¬ê¸° (스트림 패딩 미í¬í•¨) +.IP 7. 4 +ì••ì¶• í•´ì œ 용량 +.IP 8. 4 +압축율 +.IP 9. 4 +무결성 검사 ì´ë¦„ +.IP 10. 4 +스트림 패딩 ê¸¸ì´ +.RE +.PD +.PP +\fBblock\fP í–‰ 컬럼: +.PD 0 +.RS +.IP 2. 4 +ì´ ë¸”ë¡ì´ 들어간 스트림 갯수 +.IP 3. 4 +스트림 시작 ë¶€ë¶„ì˜ ë¸”ë¡ ë²ˆí˜¸ (첫번째 블ë¡ì€ 1번) +.IP 4. 4 +íŒŒì¼ ì‹œìž‘ ë¶€ë¶„ì˜ ë¸”ë¡ ë²ˆí˜¸ +.IP 5. 4 +íŒŒì¼ ì‹œìž‘ ë¶€ë¶„ì˜ ì••ì¶• 시작 오프셋 +.IP 6. 4 +íŒŒì¼ ì‹œìž‘ ë¶€ë¶„ì˜ ë¹„ì••ì¶• 시작 오프셋 +.IP 7. 4 +ì´ ë¸”ë¡ ì••ì¶• í¬ê¸° (í—¤ë” í¬í•¨) +.IP 8. 4 +ì••ì¶• í•´ì œ 용량 +.IP 9. 4 +압축율 +.IP 10. 4 +무결성 검사 ì´ë¦„ +.RE +.PD +.PP +\fB\-\-verbose\fP를 ë‘ ë²ˆ 지정하면, 추가 ì»¬ëŸ¼ì„ \fBblock\fP í–‰ì— ë„£ìŠµë‹ˆë‹¤. \fB\-\-verbose\fP ë‹¨ì¼ ì§€ì •ì‹œì—는 ì´ +정보를 ë³¼ 때 íƒìƒ‰ì„ 여러번 수행해야 하기 ë•Œë¬¸ì— ì‹¤í–‰ ê³¼ì •ì´ ëŠë ¤ì§ˆ 수 있어서 나타내지 않습니다: +.PD 0 +.RS +.IP 11. 4 +16진수 무결성 검사값 +.IP 12. 4 +ë¸”ë¡ í—¤ë” í¬ê¸° +.IP 13. 4 +ë¸”ë¡ í”Œëž˜ê·¸: \fBc\fP는 ì••ì¶• í¬ê¸°ê°€ 현재 ê°’ìž„ì„ ë‚˜íƒ€ë‚´ê³ , \fBu\fP는 ì••ì¶• ì „ ì›ë³¸ í¬ê¸°ê°€ 현재 ê°’ìž„ì„ ë‚˜íƒ€ëƒ…ë‹ˆë‹¤. 플래그를 설정하지 +않았다면, 문ìžì—´ 길ì´ë¥¼ 유지할 목ì ìœ¼ë¡œ 대시 \fB\-\fP 를 대신 나타냅니다. 새 플래그는 ë‚˜ì¤‘ì— ë¬¸ìžì—´ ë ë¶€ë¶„ì— ì¶”ê°€í•  예정입니다. +.IP 14. 4 +블ë¡ì— ì••ì¶• 해서 ë„£ì€ ë°ì´í„°ì˜ 실제 츠기 (ë¸”ë¡ í—¤ë”, ë¸”ë¡ íŒ¨ë”©, 검사 필드 제외) +.IP 15. 4 +ì´ \fBxz\fP 버전ì—서 ì´ ë¸”ë¡ì˜ ì••ì¶•ì„ í•´ì œí•  때 필요한 (ë°”ì´íЏ 단위) 메모리 용량 +.IP 16. 4 +í•„í„° ì²´ì¸. 대부분 사용하는 ì˜µì…˜ì€ ì••ì¶• 해제시 필요한 ì˜µì…˜ë§Œì„ \fB.xz\fP í—¤ë”ì— ì €ìž¥í•˜ê¸° ë•Œë¬¸ì— ì••ì¶• ì‹œê°„ì— ì•Œ 수 없습니다. +.RE +.PD +.PP +\fBsummary\fP í–‰ 컬럼: +.PD 0 +.RS +.IP 2. 4 +ì´ \fBxz\fP 버전ì—서 ì´ íŒŒì¼ ì••ì¶•ì„ í•´ì œí•  때 필요한 (ë°”ì´íЏ 단위) 메모리 용량 +.IP 3. 4 +모든 ë¸”ë¡ í—¤ë”ì— ì••ì¶• í¬ê¸°ì™€ ì••ì¶• ì „ ì›ë³¸ í¬ê¸° ì •ë³´ê°€ 들어갔는지 여부를 나타내는 \fByes\fP ë˜ëŠ” \fBno\fP ê°’ +.PP +\fBxz\fP \fI5.1.2alpha\fP \fI부터:\fP +.IP 4. 4 +íŒŒì¼ ì••ì¶• 해제시 필요한 최소 \fBxz\fP 버전 +.RE +.PD +.PP +\fBtotals\fP í–‰ 컬럼: +.PD 0 +.RS +.IP 2. 4 +스트림 갯수 +.IP 3. 4 +ë¸”ë¡ ê°¯ìˆ˜ +.IP 4. 4 +ì••ì¶• í¬ê¸° +.IP 5. 4 +ì••ì¶• í•´ì œ 용량 +.IP 6. 4 +í‰ê·  압축율 +.IP 7. 4 +파ì¼ì— 들어 있어 쉼표로 구분한 무결성 검사 ì´ë¦„ ëª©ë¡ +.IP 8. 4 +스트림 패딩 ê¸¸ì´ +.IP 9. 4 +íŒŒì¼ ê°¯ìˆ˜. \fBfile\fP í–‰ì˜ ì»¬ëŸ¼ 순서를 ë”°ë¼ê°‘니다. +.PD +.RE +.PP +\fB\-\-verbose\fP ì˜µì…˜ì„ ë‘ ë²ˆ 지정하면, \fBtotals\fP í–‰ì— ì¶”ê°€ ì»¬ëŸ¼ì´ ë“¤ì–´ê°‘ë‹ˆë‹¤: +.PD 0 +.RS +.IP 10. 4 +ì´ \fBxz\fP 버전ì—서 íŒŒì¼ ì••ì¶•ì„ í•´ì œí•  ë–„ 필요한 (ë°”ì´íЏ 단위) 최대 메모리 사용량 +.IP 11. 4 +모든 ë¸”ë¡ í—¤ë”ì— ì••ì¶• í¬ê¸°ì™€ ì••ì¶• ì „ ì›ë³¸ í¬ê¸° ì •ë³´ê°€ 들어갔는지 여부를 나타내는 \fByes\fP ë˜ëŠ” \fBno\fP ê°’ +.PP +\fBxz\fP \fI5.1.2alpha\fP \fI부터:\fP +.IP 12. 4 +íŒŒì¼ ì••ì¶• 해제시 필요한 최소 \fBxz\fP 버전 +.RE +.PD +.PP +차후 버전ì—서는 새 í–‰ 형ì‹ì„ 추가하고 기존 í–‰ 형ì‹ì— 추가할 수 있는 새 ì»¬ëŸ¼ì„ ë„£ê¸° 까지는 알 수 있겠지만, 기존 ì»¬ëŸ¼ì€ ë°”ê¾¸ì§€ ì•Šì„ +예정입니다. +. +.SS "í•„í„° ë„움ë§" +\fBxz \-\-robot \-\-filters\-help\fP 는 ë‹¤ìŒ í˜•ì‹ì˜ ì§€ì› í•„í„° 목ë¡ì„ 출력합니다: +.PP +\fI<í•„í„°>\fP\fB:\fP\fI<옵션>\fP\fB=<\fP\fIê°’\fP\fB>,\fP\fI<옵션>\fP\fB=<\fP\fIê°’\fP\fB>\fP... +.TP +\fI<í•„í„°>\fP +í•„í„° ì´ë¦„ +.TP +\fI<옵션>\fP +필터별 옵션 ì´ë¦„ +.TP +\fI<ê°’>\fP +ìˆ«ìž \fIê°’\fP 범위는 \fB<\fP\fI최소\fP\fB\-\fP\fI최대\fP\fB>\fP입니다. 문ìžì—´ \fIê°’\fPì€ \fB< >\fP 범위 +ë‚´ì—서 ì„ íƒí•˜ë©° \fB|\fP 문ìžë¡œ 구분합니다. +.PP +ê° í•„í„°ëŠ” 한 ì¤„ì— í•˜ë‚˜ì”© 출력합니다. +. +.SS "메모리 제한 ì •ë³´" +\fBxz \-\-robot \-\-info\-memory\fP ëª…ë ¹ì€ íƒ­ìœ¼ë¡œ 나뉜 여러 ì»¬ëŸ¼ì„ ë‹¨ì¼ í–‰ìœ¼ë¡œ 나타냅니다: +.IP 1. 4 +물리 메모리(RAM)ì˜ ë°”ì´íЏ 단위 ì´ëŸ‰. +.IP 2. 4 +ì••ì¶• 진행시 ë°”ì´íЏ 단위 메모리 사용 한계값 (\fB\-\-memlimit\-compress\fP). 특수 ê°’ \fB0\fPì€ ë‹¨ì¼\-스레드 모드ì—서 +ì œí•œì„ ë‘ì§€ 않는 기본 ì„¤ì •ìž„ì„ ë‚˜íƒ€ëƒ…ë‹ˆë‹¤. +.IP 3. 4 +ì••ì¶• 해제시 ë°”ì´íЏ 단위 메모리 사용 한계값 (\fB\-\-memlimit\-decompress\fP). 특수 ê°’ \fB0\fPì€ ë‹¨ì¼\-스레드 모드ì—서 +ì œí•œì„ ë‘ì§€ 않는 기본 ì„¤ì •ìž„ì„ ë‚˜íƒ€ëƒ…ë‹ˆë‹¤. +.IP 4. 4 +\fBxz\fP 5.3.4alpha ì´í›„: 다중\-스레드 기반 ì••ì¶• 해제시 ë°”ì´íЏ 단위 메모리 +사용량(\fB\-\-memlimit\-mt\-decompress\fP). 분명하게 ì œí•œì„ ê±¸ì–´ë‘ì§€ ì•Šì•˜ì„ ê²½ìš° 5번째 ì»¬ëŸ¼ì— ë‚˜íƒ€ë‚œ 시스템별 +ê¸°ë³¸ê°’ì„ ì‚¬ìš©í•˜ê¸° ë•Œë¬¸ì— 0 ê°’ì„ ì§€ì •í•˜ë©´ 안ë©ë‹ˆë‹¤. ë˜í•œ \fB\-\-memlimit\-mt\-decompress\fP로 세번째 컬럼 값보다 ë” +í¬ê²Œ ì§€ì •ì„ í•œë‹¤ í• ì§€ë¼ë„ ì´ ê°’ì´ ì„¸ë²ˆì§¸ 컬럼 값보다 í¬ë©´ 안ë©ë‹ˆë‹¤. +.IP 5. 4 +\fBxz\fP 5.3.4alpha ì´í›„: A system\-specific default memory usage limit that is +used to limit the number of threads when compressing with an automatic +number of threads (\fB\-\-threads=0\fP) and no memory usage limit has been +specified (\fB\-\-memlimit\-compress\fP). This is also used as the default value +for \fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +\fBxz\fP 5.3.4alpha ì´í›„: Number of available processor threads. +.PP +차후, \fBxz \-\-robot \-\-info\-memory\fP 출력ì—는 ë” ë§Žì€ ë‚´ìš©ì´ ë“¤ì–´ê°€ì§€ë§Œ, 한 줄 ì´ìƒì€ 넘어가지 않습니다. +. +.SS 버전 +\fBxz \-\-robot \-\-version\fP ì€ \fBxz\fP 와 liblzmaì˜ ë²„ì „ 번호를 ë‹¤ìŒ í˜•ì‹ìœ¼ë¡œ 나타냅니다: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +주 버전. +.TP +\fIYYY\fP +ë¶€ 버전. ì§ìˆ˜ê°€ 안정 버전입니다. 홀수는 알파 ë˜ëŠ” 베타 버전입니다. +.TP +\fIZZZ\fP +안정 ë¦´ë¦¬ìŠ¤ì˜ íŒ¨ì¹˜ 수준 ë˜ëŠ” 개발 ë¦´ë¦¬ìŠ¤ì˜ íšŸìˆ˜ìž…ë‹ˆë‹¤. +.TP +\fIS\fP +안정ë„. 0ì€ ì•ŒíŒŒ 버전, 1ì€ ë² íƒ€ ë²„ì „ì„ ë‚˜íƒ€ë‚´ë©°, 2는 안정 ë²„ì „ì„ ë‚˜íƒ€ëƒ…ë‹ˆë‹¤. \fIS\fP는 \fIYYY\fP ê°’ì´ ì§ìˆ˜ë¼ í•´ë„ í•­ìƒ +2여야 합니다. +.PP +\fBxz\fP 명령과 liblzmaì´ ë™ì¼í•œ XZ 유틸리티 릴리스ì—서 나왔다면 ë‘ í–‰ì˜ \fIXYYYZZZS\fP ê°’ì€ ê°™ìŠµë‹ˆë‹¤. +.PP +예제: 4.999.9beta는 \fB49990091\fPì´ë©°, 5.0.0ì€ \fB50000002\fP입니다. +. +.SH "종료 ìƒíƒœ" +.TP +\fB0\fP +모든 ìƒíƒœ 양호. +.TP +\fB1\fP +오류 ë°œìƒ. +.TP +\fB2\fP +눈여겨볼 경고가 나타났지만, 실제 오류는 ì¼ì–´ë‚˜ì§€ 않ìŒ. +.PP +표준 ì˜¤ë¥˜ì— ì¶œë ¥í•˜ëŠ” 알림(경고 ë˜ëŠ” 오류 아님)는 종료 ìƒíƒœì— ì˜í–¥ì„ 주지 않습니다. +. +.SH 환경 +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP는 빈칸으로 구분한 옵션 ê°’ 목ë¡ì„ \fBXZ_DEFAULTS\fP, \fBXZ_OPT\fP 환경 변수ì—서 순서대로, 명령행ì—서 ì˜µì…˜ì„ +í•´ì„하기 ì „ì— ë¶ˆëŸ¬ì˜µë‹ˆë‹¤. 참고로 환경 변수ì—서 옵션만 í•´ì„하며, ì˜µì…˜ì´ ì•„ë‹Œ ë¶€ë¶„ì€ ì¡°ìš©ížˆ 무시합니다. í•´ì„ì€ +\fBgetopt_long\fP(3)으로 가능하며, 명령행 ì¸ìžë¡œ í™œìš©í•˜ê¸°ë„ í•©ë‹ˆë‹¤. +.PP +\fB경고:\fP 환경 변수를 설정하면, 프로그램과 \fBxz\fP를 실행하는 스í¬ë¦½íŠ¸ì˜ ë™ìž‘ì´ ë°”ë€ë‹ˆë‹¤. ëŒ€ë¶€ë¶„ì˜ ê²½ìš° 메모리 사용 제한량, +스레드 수, ì••ì¶• ì˜µì…˜ì„ í™˜ê²½ 변수로 설정하는게 안전합니다. 그러나 ì¼ë¶€ ì˜µì…˜ì€ ìŠ¤í¬ë¦½íŠ¸ì˜ ë™ìž‘ì„ ë§ê°€ëœ¨ë¦´ 수 있습니다. 분명한 +예제로는 \fBxz\fPì—서 파ì¼ì˜ ì••ì¶• ë° í•´ì œ 대신 ë„ì›€ë§ ë‚´ìš©ì„ í‘œì‹œí•˜ëŠ” \fB\-\-help\fP ì˜µì…˜ì´ ìžˆìŠµë‹ˆë‹¤. 좀 ë” ë¬˜í•œ 예제로는 +\fB\-\-quiet\fP 와 \fB\-\-verbose\fP ì˜µì…˜ì´ ìžˆìŠµë‹ˆë‹¤. ëŒ€ë¶€ë¶„ì˜ ê²½ìš° \fB\-\-verbose\fP ì˜µì…˜ì„ ì‚¬ìš©í•˜ì—¬ 프로세스 ìƒí™©ì„ +í‘œì‹œí•˜ëŠ”ë° ìž˜ ë™ìž‘하지만, ì–´ë–¤ 경우ì—는 추가 메시지가 나타나는 문제가 있습니다. 출력 ìƒì„¸ ìˆ˜ì¤€ì€ \fB\-\-list\fPì˜ ë™ìž‘ì—ë„ ì˜í–¥ì„ +ì¤ë‹ˆë‹¤. +.TP +\fBXZ_DEFAULTS\fP +사용ìžë³„, 시스템 범위 기본 옵션입니다. 보통 \fBxz\fPì˜ ë©”ëª¨ë¦¬ 사용량 ì œí•œì„ ê¸°ë³¸ìœ¼ë¡œ 걸어ë‘거나 기본 스레드 수를 설정할 경우 ì…¸ +초기화 스í¬ë¦½íŠ¸ì— ì„¤ì •í•©ë‹ˆë‹¤. ì…¸ 초기화 스í¬ë¦½íŠ¸ì™€ 별ë„ì˜ ìœ ì‚¬í•œ 경우를 제외하고ë¼ë©´, 스í¬ë¦½íЏì—서는 \fBXZ_DEFAULTS\fP 환경 +변수를 설정하지 않거나 ì„¤ì •ì„ í•´ì œí•´ì•¼í•©ë‹ˆë‹¤. +.TP +\fBXZ_OPT\fP +\fBxz\fP 명령행으로 옵션 설정 ê°’ì„ ì§ì ‘ 전달할 수 ì—†ì„ ê²½ìš° \fBxz\fPì— ì˜µì…˜ì„ ì „ë‹¬í•˜ëŠ” 환경 변수입니다. 예를 들어, \fBxz\fP를 +스í¬ë¦½íЏ ë˜ëŠ” ë„구ì—서 실행할 경우 GNU \fBtar\fP(1) ë¼ë©´: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +예를 들면, 스í¬ë¦½íЏì—서 \fBXZ_OPT\fP 를 활용하여, 스í¬ë¦½íŠ¸ë³„ë¡œ 기본 ì••ì¶• ì˜µì…˜ì„ ì§€ì •í•  수 있습니다. ì ì ˆí•œ ì´ìœ ê°€ 있다면 +\fBXZ_OPT\fP 옵션 ê°’ì„ ì‚¬ìš©ìžê°€ 바꾸는걸 추천합니다. 예를 들면, \fBsh\fP(1) 스í¬ë¦½íЏì—서 다ìŒì²˜ëŸ¼ 활용할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "LZMA 유틸리티 호환성" +\fBxz\fPì˜ ëª…ë ¹í–‰ ë¬¸ë²•ì€ ì‹¤ì œë¡œ LZMA 유틸리티 4.32.xì—서 ì°¾ì„ ìˆ˜ 있는 \fBlzma\fP, \fBunlzma\fP \fBlzcat\fPì˜ +ìƒìœ„ 집합입니다. ëŒ€ë¶€ë¶„ì˜ ê²½ìš° LZMA 유틸리티를 XZ 유틸리티로 ê¸°ì¡´ì— ìž‘ì„±í•œ 스í¬ë¦½íŠ¸ë¥¼ 깨지 ì•Šê³ ë„ ë°”ê¿€ 수 있습니다. 몇가지 +비호환성 문제 ë•Œë¬¸ì— ë¬¸ì œê°€ ì¼ì–´ë‚  수는 있습니다. +. +.SS "ì••ì¶• 사전 설정 단계" +ì••ì¶• 수준 사전 ì„¤ì •ì˜ ë²ˆí˜¸ 부여 ë°©ì‹ì€ \fBxz\fP와 LZMA 유틸리티가 ë™ì¼í•˜ì§€ 않습니다. 가장 중요한 ì°¨ì´ëŠ” 다른 사전 ì„¤ì •ì— ëŒ€í•´ +딕셔너리 í¬ê¸°ë¥¼ 어떻게 대ì‘í–ˆëŠëƒ 여부입니다. 딕셔너리 í¬ê¸°ëŠ” ì••ì¶• 해제시 메모리 사용량과 ê±°ì˜ ë¹„ìŠ·í•©ë‹ˆë‹¤. +.RS +.PP +.TS +tab(;); +c c c +c n n. +단계;xz;LZMA 유틸리티 +\-0;256 KiB;ì—†ìŒ +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +딕셔너리 í¬ê¸° ì°¨ì´ëŠ” ì••ì¶• 프로그램 메모리 ì‚¬ìš©ì— ì˜í–¥ì„ 주지만, LZMA 유틸리티와 XZ 유틸리티ì—서 ì‚¬ìš©ëŸ‰ì´ ëŠ˜ì–´ë‚˜ëŠ” 다른 ì°¨ì´ì ì´ +있습니다: +.RS +.PP +.TS +tab(;); +c c c +c n n. +단계;xz;LZMA 유틸리티 4.32.x +\-0;3 MiB;ì—†ìŒ +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +XZ ìœ í‹¸ë¦¬í‹°ì˜ ê¸°ë³¸ 사전 설정 ìˆ˜ì¤€ê°’ì€ \fB\-6\fPì´ì§€ë§Œ LZMA ìœ í‹¸ë¦¬í‹°ì˜ ê¸°ë³¸ 사전 설정 ìˆ˜ì¤€ê°’ì€ \fB\-7\fP입니다. ë‘ í”„ë¡œê·¸ëž¨ì˜ +딕셔너리 메모리 기본 ì‚¬ìš©ëŸ‰ì€ 8MiB입니다. +. +.SS "스트림 vs 비스트림 .lzma 파ì¼" +파ì¼ì„ 압축하지 ì•Šì€ í¬ê¸°ëŠ” \fB.lzma\fP í—¤ë”ì— ì €ìž¥í•©ë‹ˆë‹¤. LZMA 유틸리티는 ì¼ë°˜ 파ì¼ì„ ì••ì¶•í•  때 압축하지 ì•Šì€ íŒŒì¼ì˜ í¬ê¸°ë¥¼ +저장합니다. ì´ ëŒ€ì‹  압축하지 ì•Šì€ í¬ê¸°ë¥¼ '알 수 ì—†ìŒ' 으로 저장하고 ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì´ ë©ˆì¶°ì•¼ í•  ì§€ì ì— +end\-of\-payload 마커를 사용하는 ë°©ë²•ë„ ìžˆìŠµë‹ˆë‹¤. LZMA 유틸리티는 파ì´í”„로 들어온 입력과 ê°™ì´ ì••ì¶•í•˜ì§€ ì•Šì€ íŒŒì¼ì˜ +í¬ê¸°ë¥¼ 알 수 ì—†ì„ ë•Œ ì´ëŸ° ë°©ì‹ì„ 활용합니다. +.PP +\fBxz\fP는 \fB.lzma\fP 파ì¼ì„ end\-of\-payload ë§ˆì»¤ì˜ ìœ ë¬´ì™€ ê´€ê³„ì—†ì´ ì••ì¶• í•´ì œ ë°©ì‹ì„ ëª¨ë‘ ì§€ì›í•˜ì§€ë§Œ, \fBxz\fP로 +만든 모든 \fB.lzma\fP 파ì¼ì€ end\-of\-payload 마커를 사용하며, \fB.lzma\fP í—¤ë”ì— ì••ì¶•í•˜ì§€ ì•Šì€ íŒŒì¼ í¬ê¸°ë¥¼ '알 수 +ì—†ìŒ'으로 표기합니다. ì´ ë°©ì‹ì€ 드문 ìƒí™©ì—서 문제를 야기할 수 있습니다. 예를 들면, 임베디드 ìž¥ì¹˜ì˜ \fB.lzma\fP ì••ì¶• í•´ì œ +í”„ë¡œê·¸ëž¨ì€ ì••ì¶•ì„ í•´ì œí–ˆì„ ë•Œ í¬ê¸°ë¥¼ 알아야 ë™ìž‘합니다. ì´ ë¬¸ì œë¥¼ 만나면, LZMA 유틸리티 ë˜ëŠ” LZMA SDK를 활용하여 +\&\fB.lzma\fP 파ì¼ì— ì••ì¶• ì „ íŒŒì¼ í¬ê¸° 정보를 저장해야합니다. +. +.SS "ì§€ì›í•˜ì§€ 않는 .lzma 파ì¼" +\&\fB.lzma\fP 형ì‹ì€ \fIlc\fP ê°’ì„ 8까지 받아들ì´ë©°, \fIlp\fP ê°’ì€ 4까지 받아들입니다. LZMA 유틸리티는 ì–´ë–¤ \fIlc\fP ê°’ê³¼ +\fIlp\fP ê°’ì„ ë°›ì•„ë“¤ì´ê³ ë„ ì••ì¶•ì„ í•´ì œí•  수 있지만, 파ì¼ì„ 만들 때는 늘 \fBlc=3\fP ê°’ê³¼ \fBlp=0\fP ê°’ì„ í™œìš©í•©ë‹ˆë‹¤. 다른 +\fIlc\fP ê°’ê³¼ \fIlp\fP ê°’ìœ¼ë¡œì˜ íŒŒì¼ ì••ì¶•ì€ \fBxz\fP와 LZMA SDKì—서만 가능합니다. +.PP +liblzmaì˜ LZMA1 í•„í„° 구현체ì—서는 \fIlc\fP ê°’ê³¼ \fIlp\fP ê°’ì˜ í•©ì´ 4를 넘어가면 안ë©ë‹ˆë‹¤. 그래서 \fB.lzma\fP +파ì¼ì˜ 경우 ì´ ì œí•œì„ ë„˜ì–´ê°€ë©´ \fBxz\fP로 ì••ì¶•ì„ í•´ì œí•  수 없습니다. +.PP +LZMA 유틸리티는 2^\fIn\fP (2ì˜ ìŠ¹ìˆ˜)í¬ê¸°ë¥¼ 지닌 딕셔너리를 가진 \fB.lzma\fP 파ì¼ë§Œ 만들지만 받아들ì´ëŠ” 파ì¼ì˜ 딕셔너리 +í¬ê¸°ëŠ” ì–´ë–¤ í¬ê¸°ë“  ìƒê´€ 없습니다. liblzmaì—서는 2^\fIn\fP, 2^\fIn\fP + 2^(\fIn\fP\-1) 딕셔너리 í¬ê¸°ë¥¼ 가진 +\&\fB.lzma\fP íŒŒì¼ ë§Œ 받아들입니다. ì´ë¡œ ì¸í•´ \fB.lzma\fP 파ì¼ì„ 확ì¸í•  때 ê±°ì§“ ì–‘ì„±ìœ¨ì´ ëŠ˜ì–´ë‚©ë‹ˆë‹¤. +.PP +모든 \fB.lzma\fP 파ì¼ì„ liblzma ì—서 ë°›ì•„ë“¤ì¼ ìˆ˜ 있ë„ë¡ ì••ì¶•í•˜ê¸° ë•Œë¬¸ì— ì´ ì œí•œì´ ì‹¤ì œë¡œëŠ” 문제가 ë˜ì§€ 않습니다. +. +.SS "뒤따ë¼ì˜¤ëŠ” 쓰레기 ê°’" +ì••ì¶• 해제할 때, LZMA 유틸리티는 \fB.lzma\fP 스트림 ì²˜ìŒ ë¶€ë¶„ ë‹¤ìŒ ë‚˜ë¨¸ì§€ë¥¼ 다 조용히 무시합니다. ëŒ€ë¶€ë¶„ì˜ ê²½ìš°, +버그입니다. LZMA 유틸리티ì—서 \fB.lzma\fP ê²°í•© íŒŒì¼ ì••ì¶• 해제를 ì§€ì›í•˜ì§€ 않ìŒì„ ì˜ë¯¸í•˜ê¸°ë„ 합니다. +.PP +\&\fB.lzma\fP 스트림 처ìŒë¶€ë¶„ 바로 다ìŒì— ë°ì´í„°ê°€ ë‚¨ì•„ìžˆì„ ê²½ìš°, \fBxz\fP ì—서는 \fB\-\-single\-stream\fP ì˜µì…˜ì„ ì‚¬ìš©í•˜ì§€ +않으면 깨진 파ì¼ë¡œ 간주합니다. ì´ ë™ìž‘으로 하여금 뒤따ë¼ì˜¤ëŠ” 쓰레기 ê°’ì„ ë¬´ì‹œí•˜ë„ë¡ ê°„ì£¼í•˜ëŠ” 애매한 스í¬ë¦½íЏ ë™ìž‘ì„ ê¹° 수가 +있습니다. +. +.SH 참고 +. +.SS "출력 ê²°ê³¼ë¬¼ì´ ë‹¬ë¼ì§" +압축하지 ì•Šì€ ìž…ë ¥ 파ì¼ë¡œë¶€í„° 얻어낸 정확한 ì••ì¶• 출력 ê²°ê³¼ë¬¼ì€ ì••ì¶• ì˜µì…˜ì´ ì™„ì „ížˆ ë™ì¼í•˜ë”ë¼ë„ XZ ìœ í‹¸ë¦¬í‹°ì˜ ë²„ì „ì— ë”°ë¼ ë‹¬ë¼ì§ˆ 수 +있습니다. íŒŒì¼ í˜•ì‹ì— ì˜í–¥ì„ 주지 않고 ì¸ì½”ë” ê·¸ ìžì²´ë¥¼ 개선(ë” ë¹ ë¥´ê²Œ 하거나 ë” ë‚˜ì€ ì••ì¶•ìœ¨ë¡œ)하기 때문입니다. XZ 유틸리티 +ë²„ì „ì´ ë™ì¼í•˜ë”ë¼ë„ 빌드 ì˜µì…˜ì„ ë‹¬ë¦¬í•˜ì—¬ 빌드 ìƒíƒœê°€ ì œê°ê°ì¸ 경우 출력 ê²°ê³¼ë¬¼ì´ ë‹¬ë¼ì§ˆ 수 있습니다. +.PP +\fB\-\-rsyncable\fP ê¸°ëŠ¥ì„ ë„£ì—ˆì„ ê²½ìš° ë™ì¼í•œ xz 버전ì—서 ì´ì „ 파ì¼ê³¼ 새 파ì¼ë¡œ 별ë„로 압축하지 않는 한 ê²°ê³¼ 파ì¼ì„ (ë‘ +파ì¼ì´ 서로 다른 파ì¼ì´ 아니므로) rsync 처리할 필요가 없습니다. ì´ ë¬¸ì œëŠ” ì¸ì½”ë” êµ¬í˜„ì²´ 기능 ê°œë°œì´ ë나서 xz ë²„ì „ì´ +다르ë”ë¼ë„ 안정ì ì¸ rsync 가능한 출력 ê²°ê³¼ë¬¼ì„ ìœ ì§€í•  수 ìžˆì„ ë•Œì—¬ì•¼ í•´ê²°í•  수 있습니다. +. +.SS "내장 .xz ì••ì¶• í•´ì œ 프로그램" +XZ 임베디드와 ê°™ì€ ë‚´ìž¥ \fB.xz\fP ì••ì¶• í•´ì œ 구현체는 ì§€ì› íŒŒì¼ì˜ 무결성 \fI검사\fP 형ì‹ì„ \fInone\fPê³¼ \fIcrc32\fP ì´ì™¸ì˜ +설정으로 만들 필요가 없습니다. ê¸°ë³¸ê°’ì´ \fB\-\-check=crc64\fPì¼ ê²½ìš°ì—ë§Œ, 임베디드 시스템ì—서 파ì¼ì„ 만들 때 +\fB\-\-check=none\fP ë˜ëŠ” \fB\-\-check=crc32\fP ì˜µì…˜ì„ ì‚¬ìš©í•´ì•¼í•©ë‹ˆë‹¤. +.PP +임베디드 ì‹œìŠ¤í…œì´ ì•„ë‹ˆë¼ë©´, 모든 \fB.xz\fP í˜•ì‹ ì••ì¶• í•´ì œ 프로그램ì—서는 모든 \fI검사\fP 형ì‹ì„ ì§€ì›í•˜ê±°ë‚˜, ì¼ë¶€ \fI검사\fP ë°©ì‹ì„ +ì§€ì›í•˜ì§€ 않는다면, 최소한, 무결성 검사로 ê²€ì¦í•˜ì§€ 않고 ì••ì¶•ì„ í•´ì œí•  수 있습니다. +.PP +XZ 임베디드는 BCJ 필터를 ì§€ì›í•˜ì§€ë§Œ, 기본 시작 오프셋만 지정할 수 있습니다. +. +.SH 예제 +. +.SS 기본 +\fIfoo\fP 파ì¼ì„ 기본 ì••ì¶• 수준 (\fB\-6\fP) 으로 \fIfoo.xz\fP 파ì¼ì— ì••ì¶•í•´ 넣고, ì••ì¶• ê³¼ì •ì´ ë¬´ì‚¬ížˆ ë나면 \fIfoo\fP를 +삭제합니다: +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +\fIbar.xz\fP를 \fIbar\fP ì— ì••ì¶•ì„ í•´ì œí•œ 후 ì••ì¶• 해제가 무사히 ëë‚˜ë„ \fIbar.xz\fP를 삭제하지 않습니다: +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +기본 사전 설정 \fB\-6\fP 보다는 ëŠë¦¬ì§€ë§Œ, ì••ì¶• ë° ì••ì¶• 해제시 메모리를 ì ê²Œ 차지(ê°ê° 48\ Mib, 5\MiB)는 \fB\-4e\fP +사전 설정(\fB\-4 \-\-extreme\fP)ì„ í™œìš©í•˜ì—¬ \fIbaz.tar.xz\fP 파ì¼ì„ 만듭니다: +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +ì••ì¶• ë° ë¹„ì••ì¶• 파ì¼ì„ ë‹¨ì¼ ëª…ë ¹ìœ¼ë¡œ 표준 ì¶œë ¥ì— ì••ì¶•í•´ì œí•  수 있습니다: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "다중 íŒŒì¼ ë³‘ë ¬ ì••ì¶•" +GNU와 *BSDì—서는 \fBfind\fP(1) 명령과 \fBxargs\fP(1) 명령으로 여러 파ì¼ì˜ ì••ì¶•ì„ ë³‘ë ¬ 처리할 수 있습니다: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +\fBxargs\fP(1) ì˜ \fB\-P\fP 옵션으로 \fBxz\fP í”„ë¡œì„¸ìŠ¤ì˜ ë³‘ë ¬ 처리 갯수를 지정합니다. \fB\-n\fP ì˜µì…˜ì˜ ìµœì  ê°’ì€ ì••ì¶•í•  +íŒŒì¼ ìˆ˜ì— ë‹¬ë ¤ìžˆìŠµë‹ˆë‹¤. ì••ì¶•í•  파ì¼ì´ ëª‡ê°œë°–ì— ì—†ë‹¤ë©´ 1ì´ì–´ì•¼í•©ë‹ˆë‹¤. 파ì¼ì´ 수천 수만개 ì •ë„ ëœë‹¤ë©´ \fBxargs\fP(1) ì´ +ì–´ì¨Œë“ ì§€ê°„ì— ë§Œë“¤ì–´ë‚¼ \fBxz\fP í”„ë¡œì„¸ìŠ¤ì˜ ê²Ÿìˆ˜ë¥¼ 100으로 하거나 아니면 ì ë‹¹í•œ ê°’ì„ ì§€ì •í•˜ì—¬ 줄ì´ëŠ”ê²Œ 좋습니다. +.PP +\fBxz\fPì— \fB\-T1\fPì˜µì…˜ì„ ì§€ì •í•˜ë©´ 단ì¼\-스레드 모드로 강제합니다. \fBxargs\fP(1) ì—서 병렬 처리 갯수를 제어할 수 있기 +때문입니다. +. +.SS "로봇 모드" +여러 파ì¼ì„ 압축한 후 저장할 ë°”ì´íЏ ìš©ëŸ‰ì„ ê³„ì‚°í•©ë‹ˆë‹¤: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +ì´ ìŠ¤í¬ë¦½íЏì—서는 충분히 ìµœì‹ ì˜ \fBxz\fP ëª…ë ¹ì„ ì‚¬ìš©í•˜ëŠ”ì§€ 알아보려 합니다. ë‹¤ìŒ \fBsh\fP(1) 스í¬ë¦½íЏì—서는 \fBxz\fP ë„êµ¬ì˜ +버전 번호가 최소한 5.0.0ì¸ì§€ 여부를 검사합니다. ì´ ë°©ì‹ì€ \fB\-\-robot\fP ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않는 ì˜¤ëž˜ëœ ë² íƒ€ ë²„ì „ê³¼ë„ í˜¸í™˜ì„±ì´ +있습니다: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Your xz is too old." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +\fBXZ_OPT\fP 환경 변수로 ì••ì¶• 해제시 메뢰 사용량 한계를 설정하지만, 한계 ê°’ì„ ì´ë¯¸ 설정했다면, ê°’ì„ ëŠ˜ë¦¬ì§€ 않습니다: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "개별 ì••ì¶• í•„í„° ì²´ì¸ ì„¤ì •" +개별 설정 í•„í„° ì²´ì¸ì˜ 초단순 사용방ì‹ì€ LZMA2 사전 설정 ê°’ì„ ë³„ë„로 설정하는 ë°©ì‹ìž…니다. 사전 ì„¤ì •ì€ ìž ìž¬ì ìœ¼ë¡œ 쓸만한 ì••ì¶• +설정 ì¡°í•©ë§Œ 다루기 ë•Œë¬¸ì— ê½¤ 쓸모가 ìžˆì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. +.PP +\fB\-0\fP ... \fB\-9\fP ì˜µì…˜ì˜ ì„¤ëª…ì—서 í…Œì´ë¸”ì˜ CompCPU 컬럼과 \fB\-\-extreme\fP ì˜µì…˜ì€ LZMA2 사전 ì„¤ì •ì„ +개별ì ìœ¼ë¡œ ë§žì·„ì„ ë•Œ 쓸만할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 여기 ê´€ë ¨ë‚´ìš©ì„ í…Œì´ë¸” 둘로 정리해서 모아보았습니다: +.RS +.PP +.TS +tab(;); +c c +n n. +Preset;CompCPU +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +ì–´ë–¤ 파ì¼ì„ ì••ì¶•í•  때 ìƒë‹¹ížˆ í° ë”•ì…”ë„ˆë¦¬(예: 32MiB)ê°€ í•„ìš” 하다는걸 알아채셨지만, \fBxz \-8\fP ëª…ë ¹ì´ ì••ì¶•í•  때보다 ë” ë¹ ë¥¸ +ì†ë„로 압축하려 한다면, ë” í° ë”•ì…”ë„ˆë¦¬ ì‚¬ìš©ì„ ìœ„í•´ ë” ë‚®ì€ CompCPU 사전 설정 ê°’(예: 1)으로 수정할 수 있습니다: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +ê° íŒŒì¼ì— 대해, 위 ëª…ë ¹ì€ ì••ì¶•ìœ¨ì´ ë” ì¢‹ì•„ì§€ë©´ì„œë„ \fBxz \-6\fP보다 ë” ë¹¨ë¼ì§‘니다. 그러나, CompCPU ê°’ì„ ë‚®ê²Œ 유지하는 +대신 í° ë”•ì…”ë„ˆë¦¬ì—서 ì¼ë¶€ 파ì¼ì„ 강조해야 합니다. í° ë”•ì…”ë„ˆë¦¬ê°€ ëŒ€ë¶€ë¶„ì˜ ë„ì›€ì„ ì£¼ëŠ” 매우 명백한 ìƒí™©ì—서는 최소한 몇 메가바ì´íŠ¸ì˜ +매우 유사한 ê° íŒŒì¼ì´ ì•„ì¹´ì´ë¸Œì— 들어갑니다. 딕셔너리 í¬ê¸°ëŠ” LZMA2ê°€ ì—°ì†ìœ¼ë¡œ 존재하는 ê° íŒŒì¼ì˜ 유사성으로부터 얻는 장ì ì„ 취할 +수 ìžˆì„ ë•Œ ì¼ë¶€ 개별 파ì¼ë³´ë‹¤ 훨씬 ë” ì»¤ì§‘ë‹ˆë‹¤. +.PP +ì••ì¶• 프로그램과 ì••ì¶• í•´ì œ 프로그램ì—서 메모리를 ì—„ì²­ ë§Žì´ ì‚¬ìš©í•´ë„ ìƒê´€ 없고, 파ì¼ì„ 수백 메가 ë°”ì´íЏ 메모리 ìš©ëŸ‰ì„ í™œìš©í•˜ì—¬ +압축한다면, \fBxz \-9\fP ëª…ë ¹ì— 64MiB ìš©ëŸ‰ì„ ì´ˆê³¼í•˜ëŠ” 딕셔너리를 사용할 수 있게 하는 ë°©ë²•ë„ ì“¸ë§Œí•  ì§€ë„ ëª¨ë¦…ë‹ˆë‹¤: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +위 예제ì—서와 ê°™ì´ \fB\-vv\fP (\fB\-\-verbose \-\-verbose\fP) ì˜µì…˜ì„ ì‚¬ìš©í•˜ë©´ ì••ì¶• ë° ì••ì¶• í•´ì œ 과정ì—서 필요한 메모리 +ìš©ëŸ‰ì„ ì‚´íŽ´ë³´ëŠ”ë° ìš”ê¸´í•  수 있습니다. ì••ì¶• 해제한 íŒŒì¼ í¬ê¸°ë³´ë‹¤ ë” í° ë”•ì…”ë„ˆë¦¬ë¥¼ 사용하면 불필요한 메모리 ì†Œëª¨ëŸ‰ì´ ë°œìƒí•˜ì—¬ 위 +ëª…ë ¹ì´ ìž‘ì€ íŒŒì¼ì—는 쓸모 ì—†ìŒì„ 기억하십시오. +.PP +때로는 ì••ì¶• ì‹œê°„ì´ ë”±ížˆ ìƒê´€ì´ ì—†ì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤ë§Œ, ì••ì¶• 해제시 메모리 ì‚¬ìš©ëŸ‰ì„ ì ê²Œ 유지해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 예를 들면, +임베디드 시스템ì—서 íŒŒì¼ ì••ì¶•ì„ í•´ì œí•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. ë‹¤ìŒ ëª…ë ¹ì˜ ê²½ìš° \fB\-6e\fP (\fB\-6 \-\-extreme\fP) ì˜µì…˜ì„ ê¸°ë°˜ +ì˜µì…˜ì„ ì‚¬ìš©í•˜ë©° 딕셔너리 í¬ê¸°ë¥¼ 64KiBë§Œ 사용하ë„ë¡ ì œí•œí•©ë‹ˆë‹¤. ê²°ê³¼ 파ì¼ì€ XZ 임베디드(ì´ê²Œ \fB\-\-check=crc32\fP +ì˜µì…˜ì´ ìžˆëŠ” ì´ìœ )로 100KiB 메모리 ìš©ëŸ‰ì„ í™œìš©í•˜ì—¬ 풀어낼 수 있습니다. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +가능한 한 수 ë°”ì´íŠ¸ë¥¼ ë” ì¥ì–´ 짜내고 ì‹¶ì„ ë•Œ, 리터럴 문맥 비트 수(\fIlc\fP)와 위치 비트 수(\fIpb\fP)를 조정하면 ë„ì›€ì´ ë  +ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 리터럴 위치 비트 수(\fIlp\fP)를 조금 건드리는 것 ë˜í•œ ë„ì›€ì´ ë  ì§€ë„ ëª¨ë¥´ê² ì§€ë§Œ 보통 \fIlc\fP ê°’ê³¼ \fIpb\fP +ê°’ì´ ë” ì¤‘ìš”í•©ë‹ˆë‹¤. 예를 들면, 소스 코드 저장 파ì¼ì—는 US\-ASCII í…스트가 대부분ì´ê¸°ì—, 다ìŒê³¼ ê°™ì€ ê²½ìš°ëŠ” \fBxz \-6e\fP +ëª…ë ¹ì„ ì‹¤í–‰í–ˆì„ ë•Œë¶€ë‹¤ëŠ” 아주 약간(ê±°ì˜ 0.1% 수준) ìž‘ì€ íŒŒì¼ì„ 얻어낼 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤(\fBlc=4\fP를 ë¹¼ê³ ë„ ì‹œë„해보십시오): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar\fR +.fi +.RE +.PP +LZMA2와 다른 필터를 함께 사용하면 ì¼ë¶€ íŒŒì¼ í˜•ì‹ì— 대해 ì••ì¶•ìœ¨ì„ ê°œì„ í•  수 있습니다. 예를 들면 x86\-32 ë˜ëŠ” x86\-64 +공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ x86 BCJ 필터를 활용하여 ì••ì¶•í•  경우: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +참고로 í•„í„° ì˜µì…˜ì˜ ìˆœì„œëŠ” ìƒë‹¹ížˆ 중요합니다. \fB\-\-x86\fPì„ \fB\-\-lzma\fP ì´ì „ì— ì§€ì •í•˜ë©´ \fBxz\fPì—서 오류가 나는ë°, +LZMA2 다ìŒì—는 ì–´ë–¤ í•„í„°ë“  설정할 수 없고, 옵션 ì²´ì¸ìƒ 마지막 필터로 x86 BCJ 필터를 사용할 수 없기 때문입니다. +.PP +LZMA2와 ë¸íƒ€ 필터는 비트맵 ê·¸ë¦¼ì— ìµœì ì˜ 결과를 가져다줄 수 있습니다. PNGì— ë³´í†µ 안성맞춥ì¸ë°, PNGì—는 단순 ë¸íƒ€ 필터보단 +약간 ë” ê³ ê¸‰ì§„ 필터를 사용하지만, 실제 ì••ì¶•ì„ ì§„í–‰í•  때는 Deflate를 사용하기 때문입니다. +.PP +예를 들어 ì´ë¯¸ì§€ë¥¼ 압축하지 ì•Šì€ ë¹„ì••ì¶• TIFF로 저장해야 하는 경우가 있습니다. ë¸íƒ€ í•„í„°ì˜ ê±°ë¦¬ 매개변수는 그림ì—서 픽셀당 ë°”ì´íЏ +ìˆ˜ì— ì¼ì¹˜í•˜ë„ë¡ ì„¤ì •í•©ë‹ˆë‹¤. 예를 들면, 24비트 RGB ë¹„íŠ¸ë§µì˜ ê²½ìš° \fBdist=3\fP 거리 매개변수 ê°’ì„ ì„¤ì •í•´ì•¼ 하며, LZMA2 +압축시 3ë°”ì´íЏ ì •ë ¬ì„ ë”°ë¥´ë„ë¡ \fBpb=0\fP ê°’ì„ ì „ë‹¬í•˜ëŠ” ë°©ë²•ë„ ë°”ëžŒì§í•©ë‹ˆë‹¤: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +여러 ì´ë¯¸ì§€ë¥¼ ë‹¨ì¼ ì•„ì¹´ì´ë¸Œë¡œ 넣고 싶다면(예: \fB.tar\fP), 모든 ì´ë¯¸ì§€ì— 대해 ë™ì¼í•œ 픽셀당 ë°”ì´íЏ 수가 들어가는 경우ì—ë„ ë¸íƒ€ +í•„í„°ê°€ ë™ìž‘합니다. +. +.SH "추가 참조" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ 유틸리티: +.br +XZ 임베디드: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ko/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzdec.1 new file mode 100644 index 000000000..a9e112792 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzdec.1 @@ -0,0 +1,72 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Korean translation for the xz-man +.\" Seong-ho Cho , 2023, 2024. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 2024\-04\-08 Tukaani "XZ 유틸리티" +.SH ì´ë¦„ +xzdec, lzmadec \- .xz와 .lzmaìš© ìž‘ì€ ì••ì¶• í•´ì œ 프로그램 +.SH 요약 +\fBxzdec\fP [\f\fI옵션\fP...\fP] [\fI<파ì¼>...\fP] +.br +\fBlzmadec\fP [\f\fI옵션\fP...\fP] [\fI<파ì¼>...\fP] +.SH 설명 +\fBxzdec\fPì€ liblzma 기반 \fB.xz\fP (그리고 \fB.xz\fP 확장ìžë§Œ) íŒŒì¼ ì••ì¶• í•´ì œ ì „ìš© ë„구 프로그램입니다. +\fBxzdec\fP ì€ \fBxz\fP(1) ëª…ë ¹ì„ í™œìš©í•˜ì—¬ \fB.xz\fP 파ì¼ì˜ ì••ì¶•ì„ í•´ì œí•  때 ì“°ë˜ \fBxz \-\-decompress \-\-stdout\fP (그리고 ì¼ë°˜ì ìœ¼ë¡œ ì“°ë˜ ëª‡ê°€ì§€ 다른 ì˜µì…˜ë„ ê°™ì´) ëª…ë ¹ì„ ìž‘ì„±í•˜ë˜ ì¼ìƒì ì¸ 경우를 대신하려 만든 결과물입니다. +\fBlzmadec\fP 는 \fB.xz\fP íŒŒì¼ ëŒ€ì‹  \fB.lzma\fP 파ì¼ì„ ì§€ì›í•˜ëŠ” ì ë§Œ 다르며, 나머지는 \fBxzdec\fPê³¼ ë™ì¼í•©ë‹ˆë‹¤. +.PP +실행 íŒŒì¼ í¬ê¸°ë¥¼ 줄ì´ë ¤ëŠ” 목ì ìœ¼ë¡œ, \fBxzdec\fP ì—서는 다중\-스레드 실행 ë˜ëŠ” 현지 언어 표기를 ì§€ì›í•˜ì§€ 않으며 +\fBXZ_DEFAULTS\fP 환경 변수와 \fBXZ_OPT\fP 환경 ë³€ìˆ˜ì˜ ì˜µì…˜ ê°’ì„ ì½ì§€ 않습니다. \fBxzdec\fPì€ ë‹¨ê³„ë³„ ì§„í–‰ 정보를 +표시하지 않습니다. \fBxzdec\fP 명령어로 \fBSIGINFO\fP 시그ë„ì„ ë³´ë‚´ë©´ 아무 ë™ìž‘ë„ ì·¨í•˜ì§€ 않지만, \fBSIGUSR1\fP 시그ë„ì„ +ë³´ë‚´ë©´ 프 정보를 표시하는 대신 프로세스를 ë냅니다. +.SH 옵션 +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +\fBxz\fP(1) í˜¸í™˜ì„±ì„ ë¬¸ì œë¡œ 무시합니다. \fBxzdec\fPì€ ì••ì¶• í•´ì œ 기능만 ì§€ì›í•©ë‹ˆë‹¤. +.TP +\fB\-k\fP, \fB\-\-keep\fP +\fBxz\fP(1) í˜¸í™˜ì„±ì„ ë¬¸ì œë¡œ 무시합니다. \fBxzdec\fPì€ ì–´ë–¤ 파ì¼ë„ 만들거나 제거하지 않습니다. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +\fBxz\fP(1) í˜¸í™˜ì„±ì„ ë¬¸ì œë¡œ 무시합니다. \fBxzdec\fPì€ í•­ìƒ ì••ì¶• 해제한 ë°ì´í„°ë¥¼ 표준 출력으로만 기ë¡í•©ë‹ˆë‹¤. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +ì´ ì˜µì…˜ì„ í•œë²ˆ 지정하면 \fBxzdec\fPì—서 ì–´ë–¤ 경고나 ì•Œë¦¼ì„ í‘œì‹œí•˜ì§€ 않기 ë•Œë¬¸ì— ì•„ë¬´ëŸ° ë™ìž‘ë„ ì·¨í•˜ì§€ 않습니다. 오류 메시지를 +표시하지 않으려면 ì´ ì˜µì…˜ì„ ë‘번 지정하십시오. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +\fBxz\fP(1) í˜¸í™˜ì„±ì„ ë¬¸ì œë¡œ 무시합니다. \fBxzdec\fPì€ ì¢…ë£Œ 코드 2ë²ˆì„ ì‚¬ìš©í•˜ì§€ 않습니다. +.TP +\fB\-h\fP, \fB\-\-help\fP +ë„ì›€ë§ ë©”ì‹œì§€ë¥¼ 나타내고 무사히 나갑니다. +.TP +\fB\-V\fP, \fB\-\-version\fP +\fBxzdec\fPê³¼ liblzmaì˜ ë²„ì „ 번호를 나타냅니다. +.SH "종료 ìƒíƒœ" +.TP +\fB0\fP +모든 ìƒíƒœ 양호. +.TP +\fB1\fP +오류 ë°œìƒ. +.PP +\fBxzdec\fP ì€ \fBxz\fPì— ìžˆëŠ” 경고 메시지를 출력하지 않기 ë•Œë¬¸ì— \fBxzdec\fP ì—서는 종료 코드 2ë²ˆì„ ì‚¬ìš©í•˜ì§€ 않습니다. +.SH 참고 +보통 ë§¤ì¼ ì‚¬ìš©í•˜ì‹¤ 목ì ì´ë¼ë©´ \fBxzdec\fP ë˜ëŠ” \fBlzmadec\fP 대신 \fBxz\fP ëª…ë ¹ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤. \fBxzdec\fP ë˜ëŠ” +\fBlzmadec\fPì€ ì™„ì „í•œ ê¸°ëŠ¥ì„ ê°–ì¶˜ \fBxz\fP(1) 보다는 ìž‘ì€ ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì„ ì‚¬ìš©í•´ì•¼ í•  경우ì—ë§Œ 사용하ë¼ê³  있는 +명령입니다. +.PP +\fBxzdec\fP ê³¼ \fBlzmadec\fP ì€ ì‹¤ì œë¡œ 그렇게 ìž‘ì€ê±´ 아닙니다. ì»´íŒŒì¼ ì‹œê°„ì— liblzmaì—서 얼마나 ê¸°ëŠ¥ì„ ë–¨ê¶ˆë‚´ëŠëƒì— +ë”°ë¼ ë” ì¤„ì–´ë“¤ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤ë§Œ, 보통 임베디드 ìš´ì˜ì²´ì œ ë°°í¬íŒì´ 아닌 경우는 ì´ë ‡ê²Œ í•  수가 없습니다. 실제로 ìž‘ì€ \fB.xz\fP ì••ì¶• +í•´ì œ í”„ë¡œê·¸ëž¨ì´ í•„ìš”í•˜ë‹¤ë©´ XZ 임베디드 ì‚¬ìš©ì„ ê³ ë ¤í•˜ì‹­ì‹œì˜¤. +.SH "추가 참조" +\fBxz\fP(1) +.PP +XZ 임베디드: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ko/xzdiff.1 b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzdiff.1 new file mode 100644 index 000000000..8921034b8 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzdiff.1 @@ -0,0 +1,52 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Korean translation for the xz-man +.\" Seong-ho Cho , 2023, 2024. +.\" +.\" (Note that this file is not based on gzip's zdiff.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDIFF 1 2025\-03\-06 Tukaani "XZ 유틸리티" +.SH ì´ë¦„ +xzcmp, xzdiff, lzcmp, lzdiff \- ì••ì¶• 파ì¼ì„ 비êµí•©ë‹ˆë‹¤ +. +.SH 요약 +\fBxzcmp\fP [\fI<옵션>...\fP] \fI<파ì¼1>\fP [\fI<파ì¼2>\fP] +.br +\fBxzdiff\fP \&... +.br +\fBlzcmp\fP \&... (사용 안 함) +.br +\fBlzdiff\fP \&... (사용 안 함) +. +.SH 설명 +\fBxzcmp\fP 와 \fBxzdiff\fP ëª…ë ¹ì€ ì••ì¶• 해제한 ë‘ íŒŒì¼ì˜ ë‚´ìš©ì„ ë¹„êµí•©ë‹ˆë‹¤. ì••ì¶• 해제한 파ì¼ì˜ ë°ì´í„°ì™€ ì˜µì…˜ì€ +\fB\-\-help\fP 옵션 ë˜ëŠ” \fB\-\-version\fP ì˜µì…˜ì„ ì§€ì •í•˜ì§€ 않는다면, \fBcmp\fP(1) ë˜ëŠ” \fBdiff\fP(1) 명령으로 +전달합니다. +.PP +\fI<파ì¼1>\fP ê³¼ \fI<파ì¼2>\fP를 ëª¨ë‘ ì§€ì •í–ˆë‹¤ë©´, 지정한 파ì¼ì€ ì´ë¯¸ 압축해제한 파ì¼ì´ê±°ë‚˜, +\fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), \fBlz4\fP(1) 명령으로 +압축해제할 수 있는 형ì‹ì˜ 파ì¼ì¼ 수 있습니다. 필요한 ì••ì¶• í•´ì œ ëª…ë ¹ì€ \fI<파ì¼1>\fP ê³¼ +\fI<파ì¼2>\fPì˜ íŒŒì¼ ì´ë¦„ 확장ìžë¡œ 결정합니다. 알 수 없는 확장ìžë¥¼ 지닌 파ì¼ì€ ì´ë¯¸ ì••ì¶•ì„ í•´ì œí–ˆê±°ë‚˜ +\fBxz\fP(1) 명령으로 ì••ì¶• 해제할 수 있는 형ì‹ìœ¼ë¡œ 간주합니다. +.PP +íŒŒì¼ ì´ë¦„ì„ í•˜ë‚˜ë§Œ 지정한다면, \fI<파ì¼1>\fPì˜ í™•ìž¥ìžëŠ” ì§€ì› ì••ì¶• 형ì‹ì˜ 확장ìžì—¬ì•¼ 하며, +\fI<파ì¼2>\fP는 \fI<파ì¼1>\fPì—서 ì••ì¶• íŒŒì¼ í™•ìž¥ìžë¥¼ 제거한 파ì¼ë¡œ 간주합니다. +.PP +\fBlzcmp\fP와 \fBlzdiff\fP ëª…ë ¹ì€ LZMA 유틸리티 하위 호환용으로 제공합니다. 해당 ëª…ë ¹ì€ ì˜¤ëž˜ë˜ì–´ ì´í›„ 버전ì—서 +제거합니다. +. +.SH "종료 ìƒíƒœ" +ì••ì¶• í•´ì œ 오류가 나타나는 경우, 종료 코드는 \fB2\fP입니다. 그렇지 ì•Šì„ ê²½ìš° \fBcmp\fP(1) ë˜ëŠ” \fBdiff\fP(1) ëª…ë ¹ì˜ +종료 코드를 활용합니다. +. +.SH "추가 참조" +\fBcmp\fP(1), \fBdiff\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), +\fBzstd\fP(1), \fBlz4\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ko/xzgrep.1 b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzgrep.1 new file mode 100644 index 000000000..1953e55b7 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzgrep.1 @@ -0,0 +1,85 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Korean translation for the xz-man +.\" Seong-ho Cho , 2023, 2024. +.\" +.\" (Note that this file is not based on gzip's zgrep.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZGREP 1 2025\-03\-06 Tukaani "XZ 유틸리티" +.SH ì´ë¦„ +xzgrep \- íŒ¨í„´ì„ í™œìš©í•˜ì—¬ 가능한 ë°©ì‹ìœ¼ë¡œ 압축한 파ì¼ì˜ ë‚´ìš©ì„ ê²€ìƒ‰í•©ë‹ˆë‹¤ +. +.SH 요약 +\fBxzgrep\fP [\fI<옵션>...\fP] [\fI<패턴목ë¡>\fP] [\fI<파ì¼>...\fP] +.br +\fBxzegrep\fP \&... +.br +\fBxzfgrep\fP \&... +.br +\fBlzgrep\fP \&... (사용 안 함) +.br +\fBlzegrep\fP \&... (사용 안 함) +.br +\fBlzfgrep\fP \&... (사용 안 함) +. +.SH 설명 +\fBxzgrep\fPì€ ì••ì¶• 해제한 파ì¼ì˜ ë‚´ìš©ì— \fBgrep\fP(1)ì„ ì‹¤í–‰í•©ë‹ˆë‹¤. \fI<파ì¼>\fP 형ì‹ì€ íŒŒì¼ ì´ë¦„ 확장으로 +결정합니다. \fI<파ì¼>\fPì—서 ì§€ì›í•˜ëŠ” 확장ìžëŠ” \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), +\fBlzop\fP(1), \fBzstd\fP(1), \fBlz4\fP(1)로 ì••ì¶• 해제할 수 있는 파ì¼ì˜ 확장ìžìž…니다. 다른 파ì¼ì€ ì´ë¯¸ ì••ì¶•ì„ í•´ì œí•œ +파ì¼ë¡œ 간주합니다. +.PP +지정한 \fI<파ì¼>\fPì´ ì—†ê±°ë‚˜ \fI<파ì¼>\fP ê°’ì´ \fB\-\fPì´ë¼ë©´ 표준 ìž…ë ¥ì„ ì½ì–´ë“¤ìž…니다. 표준 ìž…ë ¥ì„ +ì½ì–´ë“¤ì¼ 때, \fBxz\fP(1) ë°©ì‹ìœ¼ë¡œ ì••ì¶•ì„ í•´ì œí•˜ëŠ” 파ì¼ë§Œ ì§€ì›í•©ë‹ˆë‹¤. 다른 파ì¼ì€ ì´ë¯¸ ì••ì¶•ì„ í•´ì œí•œ 파ì¼ë¡œ 간주합니다. +.PP +ëŒ€ë¶€ë¶„ì˜ \fBgrep\fP(1)ì˜ \fI<옵션>\fPì„ ì§€ì›í•©ë‹ˆë‹¤. 그러나 ë‹¤ìŒ ì˜µì…˜ì€ ì§€ì›í•˜ì§€ 않습니다: +.IP "" 4 +\fB\-r\fP, \fB\-\-recursive\fP +.IP "" 4 +\fB\-R\fP, \fB\-\-dereference\-recursive\fP +.IP "" 4 +\fB\-d\fP, \fB\-\-directories=\fP\fIaction\fP +.IP "" 4 +\fB\-Z\fP, \fB\-\-null\fP +.IP "" 4 +\fB\-z\fP, \fB\-\-null\-data\fP +.IP "" 4 +\fB\-\-include=\fP\fIglob\fP +.IP "" 4 +\fB\-\-exclude=\fP\fIglob\fP +.IP "" 4 +\fB\-\-exclude\-from=\fP\fIfile\fP +.IP "" 4 +\fB\-\-exclude\-dir=\fP\fIglob\fP +.PP +\fBxzegrep\fPì€ \fBxzgrep \-E\fP ëª…ë ¹ì˜ ë³„ì¹­ìž…ë‹ˆë‹¤. \fBxzfgrep\fPì€ \fBxzgrep \-F\fP ëª…ë ¹ì˜ ë³„ì¹­ìž…ë‹ˆë‹¤. +.PP +\fBlzgrep\fP, \fBlzegrep\fP, \fBlzfgrep\fP ëª…ë ¹ì€ LZMA 유틸리티 하위 호환용으로 제공합니다. 해당 ëª…ë ¹ì€ ì˜¤ëž˜ë˜ì–´ +ì´í›„ 버전ì—서 제거합니다. +. +.SH "종료 ìƒíƒœ" +.TP +0 +최소한 하나 ì´ìƒì˜ 파ì¼ì—서 하나 ì´ìƒì˜ ì¼ì¹˜í•˜ëŠ” 결과를 찾았습니다. 오류가 없습니다. +.TP +1 +ì–´ë–¤ ìž…ë ¥ 파ì¼ì—서든 ì¼ì¹˜í•˜ëŠ” ë‚´ìš©ì´ ì—†ìŠµë‹ˆë‹¤. 오류가 없습니다. +.TP +>1 +하나 ì´ìƒì˜ 오류가 나타납니다. ì¼ì¹˜í•˜ëŠ” í•­ëª©ì„ ì°¾ì•„ë‚¼ ì§€ 여부는 알 수 없습니다. +. +.SH 환경 +.TP +\fBGREP\fP +\fBGREP\fP 환경변수 ê°’ì´ ë¹„ì–´ìžˆì§€ 않으면, \fBgrep\fP, \fBgrep \-E\fP, \fBgrep \-F\fP 명령 대신 활용합니다. +. +.SH "추가 참조" +\fBgrep\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), +\fBlz4\fP(1), \fBzgrep\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ko/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzless.1 new file mode 100644 index 000000000..b439e657f --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzless.1 @@ -0,0 +1,41 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Korean translation for the xz-man +.\" Seong-ho Cho , 2023, 2024. +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 2025\-03\-06 Tukaani "XZ 유틸리티" +.SH ì´ë¦„ +xzless, lzless \- xz ë˜ëŠ” lzma ì••ì¶• (í…스트) 파ì¼ì„ 봅니다 +.SH 요약 +\fBxzless\fP [\fI<파ì¼>\fP...] +.br +\fBlzless\fP [\fIfile\fP...] (사용 안 함) +.SH 설명 +\fBxzless\fP는 ì••ì¶• íŒŒì¼ ë‚´ìš©ì„ í„°ë¯¸ë„ì— ë‚˜íƒ€ë‚´ëŠ” í•„í„° 프로그램입니다. \fBxz\fP(1) ë°©ì‹ìœ¼ë¡œ ì••ì¶•ì„ í•´ì œí•˜ëŠ” 파ì¼ë§Œ +ì§€ì›í•©ë‹ˆë‹¤. 다른 파ì¼ì€ ì´ë¯¸ ì••ì¶•ì„ í•´ì œí•œ 파ì¼ë¡œ 간주합니다. 주어진 \fI<파ì¼>\fP ê°’ì´ ì—†ë‹¤ë©´, \fBxzless\fP는 +표준 ìž…ë ¥ì„ ì½ì–´ë“¤ìž…니다. +.PP +\fBxzless\fP 는 \fBless\fP(1) 를 사용하여 ì¶œë ¥ì„ ë§‰ìŠµë‹ˆë‹¤. \fBxzmore\fP 와는 다르게, 환경 변수 설정으로 ì„ íƒí•œ +페ì´ì €ë¥¼ 바꿀 수 없습니다. ëª…ë ¹ì€ \fBmore\fP(1) 와 \fBvi\fP(1) ê°€ 기반ì´ë©°, 앞뒤로 움ì§ì´ê³  검색할 수 있습니다. +ìžì„¸í•œ 정보는 \fBless\fP(1) 설명서를 참고하십시오. +.PP +\fBlzless\fP ëª…ë ¹ì€ LZMA 유틸리티 하위 호환용으로 제공합니다. 해당 ëª…ë ¹ì€ ì˜¤ëž˜ë˜ì–´ ì´í›„ 버전ì—서 제거합니다. +.SH 환경 +.TP +\fBLESSMETACHARS\fP +ì…¸ì—서 ë™ìž‘í•  ìˆ˜ë„ ìžˆëŠ” 특수 ë¬¸ìž ëª©ë¡ìž…니다. í™˜ê²½ì— ë¯¸ë¦¬ 설정해ë‘ì§€ 않았다면 \fBxzless\fPì—서 설정합니다. +.TP +\fBLESSOPEN\fP +ìž…ë ¥ 파ì¼ì„ \fBless\fP(1) ì— ì „ë‹¬í•˜ê¸° ì „ì— \fBxz\fP(1) ì••ì¶• í•´ì œ í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰í•´ì„œ 미리 처리하는 ëª…ë ¹í–‰ì„ ì„¤ì •í•©ë‹ˆë‹¤. +.SH "추가 참조" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ko/xzmore.1 b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzmore.1 new file mode 100644 index 000000000..1c6ab445f --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ko/xzmore.1 @@ -0,0 +1,44 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Korean translation for the xz-man +.\" Seong-ho Cho , 2023, 2024. +.\" +.\" (Note that this file is based on xzless.1 instead of gzip's zmore.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZMORE 1 2025\-03\-06 Tukaani "XZ 유틸리티" +.SH ì´ë¦„ +xzmore, lzmore \- xz ì••ì¶• (í…스트) íŒŒì¼ ë˜ëŠ” lzma ì••ì¶• (í…스트) 파ì¼ì„ 봅니다 +. +.SH 요약 +\fBxzmore\fP [\fI<파ì¼>\fP...] +.br +\fBlzmore\fP [\fIfile\fP...] (사용 안 함) +. +.SH 설명 +\fBxzmore\fP ëª…ë ¹ì€ ì••ì¶• 파ì¼ì— 들어있는 í…스트를 \fBmore\fP(1) 명령으로 터미ë„ì— ë‚˜íƒ€ëƒ…ë‹ˆë‹¤. \fBxz\fP(1) ë°©ì‹ìœ¼ë¡œ +ì••ì¶•ì„ í•´ì œí•˜ëŠ” 파ì¼ë§Œ ì§€ì›í•©ë‹ˆë‹¤. 다른 파ì¼ì€ ì´ë¯¸ ì••ì¶•ì„ í•´ì œí•œ 파ì¼ë¡œ 간주합니다. \fI<파ì¼>\fPì„ ì§€ì •í•˜ì§€ +않으면, \fBxzmore\fP 프로그램ì—서는 표준 ìž…ë ¥ì„ ì½ì–´ë“¤ìž…니다. 키보드 명령 정보는 \fBmore\fP(1) 설명서를 참고하십시오. +.PP +참고로 \fBmore\fP(1) 명령 êµ¬í˜„ì²´ì— ë”°ë¼ ë°˜ëŒ€ ë°©í–¥(윗방향)ìœ¼ë¡œì˜ ìŠ¤í¬ë¡¤ì€ 못할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. \fBxzmore\fP ëª…ë ¹ì´ +\fBmore\fP(1) ëª…ë ¹ì— ì••ì¶• 해제한 ë°ì´í„°ë¥¼ 파ì´í”„로 전달하기 때문입니다. \fBxzless\fP(1)는 좀 ë” ë‚˜ì€ ê¸°ëŠ¥ì„ ê°€ì§„ +\fBless\fP(1) ëª…ë ¹ì„ í™œìš©í•©ë‹ˆë‹¤. +.PP +\fBlzmore\fP ëª…ë ¹ì€ LZMA 유틸리티 하위 호환용으로 제공합니다. 해당 ëª…ë ¹ì€ ì˜¤ëž˜ë˜ì–´ ì´í›„ 버전ì—서 제거합니다. +. +.SH 환경 +.TP +.\" TRANSLATORS: Don't translate the uppercase PAGER. +.\" It is a name of an environment variable. +\fBPAGER\fP +\fBPAGER\fP 환경변수 ê°’ì„ ì„¤ì •í–ˆë‹¤ë©´, \fBmore\fP(1) 대신 해당 환경변수 ê°’ì„ í™”ë©´ 표시 프로그램으로 사용합니다. +. +.SH "추가 참조" +\fBmore\fP(1), \fBxz\fP(1), \fBxzless\fP(1), \fBzmore\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/lzmainfo.1 new file mode 100644 index 000000000..5566566aa --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/lzmainfo.1 @@ -0,0 +1,45 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Brazilian Portuguese translations for xz package +.\" Traduções em português brasileiro para o pacote xz. +.\" Rafael Fontenelle , 2022-2023. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 2013\-06\-30 Tukaani "XZ Utils" +.SH NOME +lzmainfo \- mostra informações armazenadas no cabeçalho do arquivo .lzma +.SH SINOPSE +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fIarquivo...\fP] +.SH DESCRIÇÃO +\fBlzmainfo\fP mostra as informações armazenadas no cabeçalho do arquivo +\&\fB.lzma\fP. Ele lê os primeiros 13 bytes do \fIarquivo\fP especificado, +decodifica o cabeçalho e o imprime na saída padrão em formato legível por +humanos. Se nenhum \fIarquivo\fP for fornecido ou \fIarquivo\fP for \fB\-\fP, a +entrada padrão será lida. +.PP +Normalmente, as informações mais interessantes são o tamanho descompactado e +o tamanho do dicionário. O tamanho não compactado pode ser mostrado apenas +se o arquivo estiver na variante de formato \fB.lzma\fP não transmitido. A +quantidade de memória necessária para descompactar o arquivo é de algumas +dezenas de kilobytes mais o tamanho do dicionário. +.PP +\fBlzmainfo\fP está incluído no XZ Utils principalmente para compatibilidade +com versões anteriores do LZMA Utils. +.SH "STATUS DE SAÃDA" +.TP +\fB0\fP +Está tudo bem. +.TP +\fB1\fP +Ocorreu um erro. +.SH BUGS +\fBlzmainfo\fP usa \fBMB\fP enquanto o sufixo correto seria \fBMiB\fP (2^20 +bytes). Isso é para manter a saída compatível com LZMA Utils. +.SH "VEJA TAMBÉM" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xz.1 new file mode 100644 index 000000000..0f85fc96a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xz.1 @@ -0,0 +1,1994 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Brazilian Portuguese translations for xz package +.\" Traduções em português brasileiro para o pacote xz. +.\" Rafael Fontenelle , 2022-2023. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 2025\-03\-08 Tukaani "XZ Utils" +. +.SH NOME +xz, unxz, xzcat, lzma, unlzma, lzcat \- Compacta ou descompacta arquivos .xz +e .lzma +. +.SH SINOPSE +\fBxz\fP [\fIopção...\fP] [\fIarquivo...\fP] +. +.SH "COMANDOS APELIDOS" +\fBunxz\fP é equivalente a \fBxz \-\-decompress\fP. +.br +\fBxzcat\fP é equivalente a \fBxz \-\-decompress \-\-stdout\fP. +.br +\fBlzma\fP é equivalente a \fBxz \-\-format=lzma\fP. +.br +\fBunlzma\fP é equivalente a \fBxz \-\-format=lzma \-\-decompress\fP. +.br +\fBlzcat\fP é equivalente a \fBxz \-\-format=lzma \-\-decompress \-\-stdout\fP. +.PP +Ao escrever scripts que precisam descompactar arquivos, é recomendável +sempre usar o nome \fBxz\fP com os argumentos apropriados (\fBxz \-d\fP ou \fBxz \-dc\fP) em vez dos nomes \fBunxz\fP e \fBxzcat\fP. +. +.SH DESCRIÇÃO +\fBxz\fP é uma ferramenta de compactação de dados de uso geral com sintaxe de +linha de comando semelhante ao \fBgzip\fP(1) e ao \fBbzip2\fP(1). O formato de +arquivo nativo é o formato \fB.xz\fP, mas o formato legado \fB.lzma\fP usado por +LZMA Utils e fluxos compactados brutos sem cabeçalhos de formato de +contêiner também são suportados. Além disso, a descompactação do formato +\&\fB.lz\fP usado por \fBlzip\fP é suportada. +.PP +\fBxz\fP compacta ou descompacta cada \fIarquivo\fP de acordo com o modo de +operação selecionado. Se nenhum \fIarquivo\fP for fornecido ou \fIarquivo\fP for +\fB\-\fP, \fBxz\fP lê da entrada padrão e grava os dados processados na saída +padrão. \fBxz\fP recusará (exibirá um erro e ignorará o \fIarquivo\fP) para gravar +dados compactados na saída padrão se for um terminal. Da mesma forma, \fBxz\fP +se recusará a ler dados compactados da entrada padrão se for um terminal. +.PP +A menos que \fB\-\-stdout\fP seja especificado, \fIarquivos\fP diferentes de \fB\-\fP +são gravados em um novo arquivo cujo nome é derivado do nome \fIarquivo\fP de +origem: +.IP \(bu 3 +Ao compactar, o sufixo do formato de arquivo de destino (\fB.xz\fP ou \fB.lzma\fP) +é anexado ao nome do arquivo de origem para obter o nome do arquivo de +destino. +.IP \(bu 3 +Ao descompactar, o sufixo \fB.xz\fP, \fB.lzma\fP ou \fB.lz\fP é removido do nome do +arquivo para obter o nome do arquivo de destino. \fBxz\fP também reconhece os +sufixos \fB.txz\fP e \fB.tlz\fP e os substitui pelo sufixo \fB.tar\fP. +.PP +Se o arquivo de destino já existir, um erro será exibido e \fIarquivo\fP será +ignorado. +.PP +A menos que grave na saída padrão, \fBxz\fP exibirá um aviso e pulará o +\fIarquivo\fP se qualquer um dos seguintes se aplicar: +.IP \(bu 3 +\fIArquivo\fP não é um arquivo normal. Links simbólicos não são seguidos e, +portanto, não são considerados arquivos comuns. +.IP \(bu 3 +\fIArquivo\fP tem mais de um link físico. +.IP \(bu 3 +\fIFile\fP tem setuid, setgid ou sticky bit definido. +.IP \(bu 3 +O modo de operação está definido para compactar e o \fIarquivo\fP já possui um +sufixo do formato de arquivo de destino (\fB.xz\fP ou \fB.txz\fP ao compactar para +o formato \fB.xz\fP e \fB.lzma \fP ou \fB.tlz\fP ao compactar para o formato +\&\fB.lzma\fP). +.IP \(bu 3 +O modo de operação está definido para descompactar e o \fIarquivo\fP não possui +um sufixo de nenhum dos formatos de arquivo suportados (\fB.xz\fP, \fB.txz\fP, +\&\fB.lzma\fP, \fB.tlz\fP , ou \fB.lz\fP). +.PP +Depois de compactar ou descompactar com êxito o \fIarquivo\fP, o \fBxz\fP copia o +dono, grupo, permissões, horário de acesso e horário de modificação do +\fIarquivo\fP de origem para o arquivo de destino. Se a cópia do grupo falhar, +as permissões serão modificadas para que o arquivo de destino não se torne +acessível a usuários que não têm permissão para acessar o \fIarquivo\fP de +origem. \fBxz\fP ainda não oferece suporte à cópia de outros metadados, como +listas de controle de acesso ou atributos estendidos. +.PP +Depois que o arquivo de destino for fechado com êxito, o \fIarquivo\fP de +origem será removido, a menos que \fB\-\-keep\fP tenha sido especificado. O +\fIarquivo\fP de origem nunca é removido se a saída for gravada na saída padrão +ou se ocorrer um erro. +.PP +O envio de \fBSIGINFO\fP ou \fBSIGUSR1\fP para o processo do \fBxz\fP faz com que ele +imprima informações de andamento para erro padrão. Isso tem uso limitado, +pois quando o erro padrão é um terminal, usar \fB\-\-verbose\fP exibirá um +indicador de progresso de atualização automática. +. +.SS "Uso de memória" +O uso de memória de \fBxz\fP varia de algumas centenas de kilobytes a vários +gigabytes, dependendo das configurações de compactação. As configurações +usadas ao compactar um arquivo determinam os requisitos de memória do +descompactador. Normalmente, o descompactador precisa de 5\ % a 20\ % da +quantidade de memória que o compactador precisou ao criar o arquivo. Por +exemplo, descompactar um arquivo criado com \fBxz \-9\fP atualmente requer 65\ MiB de memória. Ainda assim, é possível ter arquivos \fB.xz\fP que requerem +vários gigabytes de memória para descompactar. +.PP +Especialmente os usuários de sistemas mais antigos podem achar irritante a +possibilidade de uso de memória muito grande. Para evitar surpresas +desconfortáveis, o \fBxz\fP possui um limitador de uso de memória embutido, que +está desabilitado por padrão. Embora alguns sistemas operacionais forneçam +maneiras de limitar o uso de memória dos processos, confiar nele não foi +considerado flexível o suficiente (por exemplo, usar \fBulimit\fP(1) para +limitar a memória virtual tende a prejudicar \fBmmap\fP(2)). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +O limitador de uso de memória pode ser ativado com a opção de linha de +comando \fB\-\-memlimit=\fP\fIlimite\fP. Geralmente é mais conveniente habilitar o +limitador por padrão definindo a variável de ambiente \fBXZ_DEFAULTS\fP, por +exemplo, \fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP. É possível definir os limites +separadamente para compactação e descompactação usando +\fB\-\-memlimit\-compress=\fP\fIlimite\fP e \fB\-\-memlimit\-decompress=\fP\fIlimite\fP. Usar +essas duas opções fora de \fBXZ_DEFAULTS\fP raramente é útil porque uma única +execução de \fBxz\fP não pode fazer compactação e descompactação e +\fB\-\-memlimit=\fP\fIlimite\fP (ou \fB\-M\fP \fIlimite\fP ) é mais curto para digitar na +linha de comando. +.PP +Se o limite de uso de memória especificado for excedido durante a +descompactação, \fBxz\fP exibirá um erro e a descompactação do arquivo +falhará. Se o limite for excedido durante a compactação, \fBxz\fP tentará +reduzir as configurações para que o limite não seja mais excedido (exceto ao +usar \fB\-\-format=raw\fP ou \fB\-\-no\-adjust\fP). Dessa forma, a operação não +falhará, a menos que o limite seja muito pequeno. A escala das configurações +é feita em etapas que não correspondem às predefinições do nível de +compactação, por exemplo, se o limite for apenas um pouco menor que o valor +necessário para \fBxz \-9\fP, as configurações serão reduzidas apenas um pouco , +não até \fBxz \-8\fP. +. +.SS "Concatenação e preenchimento com arquivos .xz" +É possível concatenar arquivos \fB.xz\fP como estão. \fBxz\fP irá descompactar +tais arquivos como se fossem um único arquivo \fB.xz\fP. +.PP +É possível inserir preenchimento entre as partes concatenadas ou após a +última parte. O preenchimento deve consistir em bytes nulos e o tamanho do +preenchimento deve ser um múltiplo de quatro bytes. Isso pode ser útil, por +exemplo, se o arquivo \fB.xz\fP for armazenado em uma mídia que mede tamanhos +de arquivo em blocos de 512 bytes. +.PP +Concatenação e preenchimento não são permitidos com arquivos \fB.lzma\fP ou +fluxos brutos. +. +.SH OPÇÕES +. +.SS "Sufixos inteiros e valores especiais" +Na maioria dos lugares onde um argumento inteiro é esperado, um sufixo +opcional é suportado para indicar facilmente números inteiros grandes. Não +deve haver espaço entre o número inteiro e o sufixo. +.TP +\fBKiB\fP +Multiplica o inteiro por 1.024 (2^10). \fBKi\fP, \fBk\fP, \fBkB\fP, \fBK\fP e \fBKB\fP são +aceitos como sinônimos de \fBKiB\fP. +.TP +\fBMiB\fP +Multiplica o número inteiro por 1.048.576 (2^20). \fBMi\fP, \fBm\fP, \fBM\fP e \fBMB\fP +são aceitos como sinônimos de \fBMiB\fP. +.TP +\fBGiB\fP +Multiplica o número inteiro por 1.073.741.824 (2^30). \fBGi\fP, \fBg\fP, \fBG\fP e +\fBGB\fP são aceitos como sinônimos de \fBGiB\fP. +.PP +O valor especial \fBmax\fP pode ser usado para indicar o valor inteiro máximo +suportado pela opção. +. +.SS "Modo de operação" +Se várias opções de modo de operação forem dadas, a última entrará em vigor. +.TP +\fB\-z\fP, \fB\-\-compress\fP +Compacta. Este é o modo de operação padrão quando nenhuma opção de modo de +operação é especificada e nenhum outro modo de operação está implícito no +nome do comando (por exemplo, \fBunxz\fP implica em \fB\-\-decompress\fP). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +After successful compression, the source file is removed unless writing to +standard output or \fB\-\-keep\fP was specified. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Decompress. After successful decompression, the source file is removed +unless writing to standard output or \fB\-\-keep\fP was specified. +.TP +\fB\-t\fP, \fB\-\-test\fP +Testa a integridade de \fIarquivos\fP compactados. Esta opção é equivalente a +\fB\-\-decompress \-\-stdout\fP exceto que os dados descompactados são descartados +em vez de serem gravados na saída padrão. Nenhum arquivo é criado ou +removido. +.TP +\fB\-l\fP, \fB\-\-list\fP +Imprime informações sobre \fIarquivos\fP compactados. Nenhuma saída +descompactada é produzida e nenhum arquivo é criado ou removido. No modo de +lista, o programa não pode ler os dados compactados da entrada padrão ou de +outras fontes não pesquisáveis. +.IP "" +A listagem padrão mostra informações básicas sobre \fIarquivos\fP, um arquivo +por linha. Para obter informações mais detalhadas, use também a opção +\fB\-\-verbose\fP. Para obter ainda mais informações, use \fB\-\-verbose\fP duas +vezes, mas observe que isso pode ser lento, porque obter todas as +informações extras requer muitas buscas. A largura da saída detalhada excede +80 caracteres, portanto, canalizar a saída para, por exemplo, \fBless\ \-S\fP +pode ser conveniente se o terminal não tiver largura o suficiente. +.IP "" +A saída exata pode variar entre versões \fBxz\fP e localidades diferentes. Para +saída legível por máquina, \fB\-\-robot \-\-list\fP deve ser usado. +. +.SS "Modificadores de operação" +.TP +\fB\-k\fP, \fB\-\-keep\fP +Não exclui os arquivos de entrada. +.IP "" +Desde \fBxz\fP 5.2.6, esta opção também faz \fBxz\fP compactar ou descompactar +mesmo se a entrada for um link simbólico para um arquivo comum, tiver mais +de um link físico ou tiver o setuid, setgid ou sticky bit definir. Os bits +setuid, setgid e sticky não são copiados para o arquivo de destino. Nas +versões anteriores, isso era feito apenas com \fB\-\-force\fP. +.TP +\fB\-f\fP, \fB\-\-force\fP +Esta opção tem vários efeitos: +.RS +.IP \(bu 3 +Se o arquivo de destino já existir, o exclui antes de compactar ou +descompactar. +.IP \(bu 3 +Compacta ou descompacta, mesmo que a entrada seja um link simbólico para um +arquivo normal, tenha mais de um link físico ou tenha setuid, setgid ou +sticky bit definido. Os bits setuid, setgid e sticky não são copiados para o +arquivo de destino. +.IP \(bu 3 +Quando usado com \fB\-\-decompress\fP \fB\-\-stdout\fP e \fBxz\fP não consegue reconhecer +o tipo do arquivo de origem, copia o arquivo de origem como está na saída +padrão. Isso permite que \fBxzcat\fP \fB\-\-force\fP seja usado como \fBcat\fP(1) para +arquivos que não foram compactados com \fBxz\fP. Observe que, no futuro, o +\fBxz\fP pode oferecer suporte a novos formatos de arquivo compactado, o que +pode fazer com que o \fBxz\fP descompacte mais tipos de arquivos em vez de +copiá\-los como na saída padrão. \fB\-\-format=\fP\fIformato\fP pode ser usado para +restringir \fBxz\fP para descompactar apenas um único formato de arquivo. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Grava os dados compactados ou descompactados na saída padrão em vez de em um +arquivo. Isso implica em \fB\-\-keep\fP. +.TP +\fB\-\-single\-stream\fP +Descompacta apenas o primeiro fluxo de \fB.xz\fP e ignora silenciosamente +possíveis dados de entrada restantes após o fluxo. Normalmente, esse +restante posterior sem uso faz com que \fBxz\fP exiba um erro. +.IP "" +\fBxz\fP nunca descompacta mais de um fluxo de arquivos \fB.lzma\fP ou fluxos +brutos, mas esta opção ainda faz \fBxz\fP ignorar os possíveis dados +posteriores após o arquivo \fB.lzma\fP ou fluxo bruto. +.IP "" +Esta opção não tem efeito se o modo de operação não for \fB\-\-decompress\fP ou +\fB\-\-test\fP. +.IP "" +Since \fBxz\fP 5.7.1alpha, \fB\-\-single\-stream\fP implies \fB\-\-keep\fP. +.TP +\fB\-\-no\-sparse\fP +Desativa a criação de arquivos esparsos. Por padrão, ao descompactar em um +arquivo normal, \fBxz\fP tenta tornar o arquivo esparso se os dados +descompactados contiverem longas sequências de zeros binários. Ele também +funciona ao gravar na saída padrão, desde que a saída padrão esteja +conectada a um arquivo normal e certas condições adicionais sejam atendidas +para torná\-la segura. A criação de arquivos esparsos pode economizar espaço +em disco e acelerar a descompactação, reduzindo a quantidade de E/S do +disco. +.TP +\fB\-S\fP \fI.suf\fP, \fB\-\-suffix=\fP\fI.suf\fP +Ao compactar, usa \fI.suf\fP como sufixo para o arquivo de destino em vez de +\&\fB.xz\fP ou \fB.lzma\fP. Se não estiver gravando na saída padrão e o arquivo de +origem já tiver o sufixo \fI.suf\fP, um aviso será exibido e o arquivo será +ignorado. +.IP "" +Ao descompactar, reconhece arquivos com o sufixo \fI.suf\fP além de arquivos +com o sufixo \fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP ou \fB.lz\fP . Se o arquivo de +origem tiver o sufixo \fI.suf\fP, o sufixo será removido para obter o nome do +arquivo de destino. +.IP "" +Ao compactar ou descompactar fluxos brutos (\fB\-\-format=raw\fP), o sufixo +sempre deve ser especificado, a menos que seja gravado na saída padrão, +porque não há sufixo padrão para fluxos brutos. +.TP +\fB\-\-files\fP[\fB=\fP\fIarquivo\fP] +Lê os nomes dos arquivos a serem processados em \fIarquivo\fP; se \fIarquivo\fP +for omitido, os nomes dos arquivos serão lidos da entrada padrão. Os nomes +de arquivo devem terminar com o caractere de nova linha. Um traço (\fB\-\fP) é +considerado um nome de arquivo regular; não significa entrada padrão. Se os +nomes de arquivo forem fornecidos também como argumentos de linha de +comando, eles serão processados antes da leitura dos nomes de arquivo de +\fIarquivo\fP. +.TP +\fB\-\-files0\fP[\fB=\fP\fIarquivo\fP] +Isso é idêntico a \fB\-\-files\fP[\fB=\fP\fIarquivo\fP], exceto que cada nome de +arquivo deve ser finalizado com o caractere nulo. +. +.SS "Opções básicas de formato de arquivo e de compactação" +.TP +\fB\-F\fP \fIformato\fP, \fB\-\-format=\fP\fIformato\fP +Especifica o \fIformato\fP de arquivo para compactar ou descompactar: +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +Este é o padrão. Ao compactar, \fBauto\fP é equivalente a \fBxz\fP. Ao +descompactar, o formato do arquivo de entrada é detectado +automaticamente. Observe que os fluxos brutos (criados com \fB\-\-format=raw\fP) +não podem ser detectados automaticamente. +.TP +\fBxz\fP +Compacta no formato de arquivo \fB.xz\fP ou aceite apenas arquivos \fB.xz\fP ao +descompactar. +.TP +\fBlzma\fP, \fBalone\fP +Compacta no formato de arquivo legado \fB.lzma\fP ou aceite apenas arquivos +\&\fB.lzma\fP ao descompactar. O nome alternativo \fBalone\fP é fornecido para +compatibilidade com versões anteriores do LZMA Utils. +.TP +\fBlzip\fP +Aceita apenas arquivos \fB.lz\fP ao descompactar. Sem suporte a compactação. +.IP "" +The \fB.lz\fP format versions 0 and 1 are supported. Version 0 files were +produced by \fBlzip\fP 1.3 and older. Such files aren't common but may be +found from file archives as a few source packages were released in this +format. People might have old personal files in this format too. +Decompression support for the format version 0 was removed in \fBlzip\fP 1.18. +\fBlzip\fP 1.4 and later create files in the format version 1. +.TP +\fBraw\fP +Compacta ou descompacta um fluxo bruto (sem cabeçalhos). Isso é destinado +apenas a usuários avançados. Para decodificar fluxos brutos, você precisa +usar \fB\-\-format=raw\fP e especificar explicitamente a cadeia de filtros, que +normalmente seria armazenada nos cabeçalhos do contêiner. +.RE +.TP +\fB\-C\fP \fIverificação\fP, \fB\-\-check=\fP\fIverificação\fP +Especifica o tipo de verificação de integridade. A verificação é calculada a +partir dos dados descompactados e armazenados no arquivo \fB.xz\fP. Esta opção +tem efeito somente ao compactar no formato \fB.xz\fP; o formato \fB.lzma\fP não +oferece suporte a verificações de integridade. A verificação de integridade +(se for o caso) é verificada quando o arquivo \fB.xz\fP é descompactado. +.IP "" +Tipos de \fIverificação\fP suportados: +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +Não calcula uma verificação de integridade. Isso geralmente é uma má +ideia. Pode ser útil quando a integridade dos dados é verificada por outros +meios. +.TP +\fBcrc32\fP +Calcula CRC32 usando o polinômio do IEEE\-802.3 (Ethernet). +.TP +\fBcrc64\fP +Calcula CRC64 usando o polinômio de ECMA\-182. Este é o padrão, pois é um +pouco melhor que o CRC32 na detecção de arquivos danificados e a diferença +de velocidade é insignificante. +.TP +\fBsha256\fP +Calcula SHA\-256. Isso é um pouco mais lento do que CRC32 e CRC64. +.RE +.IP "" +A integridade dos cabeçalhos de \fB.xz\fP é sempre verificada com CRC32. Não é +possível alterá\-la ou desativá\-la. +.TP +\fB\-\-ignore\-check\fP +Não confere a verificação de integridade dos dados compactados ao +descompactar. Os valores CRC32 nos cabeçalhos \fB.xz\fP ainda serão conferidos +normalmente. +.IP "" +\fBNão use esta opção a menos que saiba o que está fazendo.\fP Possíveis razões +para usar esta opção: +.RS +.IP \(bu 3 +Tentativa de recuperar dados de um arquivo .xz corrompido. +.IP \(bu 3 +Acelerar a descompactação. Isso é importante principalmente com SHA\-256 ou +com arquivos extremamente bem compactados. É recomendável não usar essa +opção para essa finalidade, a menos que a integridade do arquivo seja +verificada externamente de alguma outra forma. +.RE +.TP +\fB\-0\fP ... \fB\-9\fP +Seleciona um nível de predefinição de compactação. O padrão é \fB\-6\fP. Se +vários níveis de predefinição forem especificados, o último terá efeito. Se +uma cadeia de filtro personalizada já foi especificada, especificar um nível +de predefinição de compactação limpa a cadeia de filtro personalizada. +.IP "" +As diferenças entre as predefinições são mais significativas do que com +\fBgzip\fP(1) e \fBbzip2\fP(1). As configurações de compactação selecionadas +determinam os requisitos de memória do descompactador, portanto, usar um +nível de predefinição muito alto pode dificultar a descompactação do arquivo +em um sistema antigo com pouca RAM. Especificamente, \fBnão é uma boa ideia usar cegamente \-9 para tudo\fP como costuma acontecer com \fBgzip\fP(1) e +\fBbzip2\fP(1). +.RS +.TP +\fB\-0\fP ... \fB\-3\fP +Estas são predefinições um tanto rápidas. \fB\-0\fP às vezes é mais rápida que +\fBgzip \-9\fP ao mesmo tempo que compacta muito melhor. As mais altas +geralmente têm velocidade comparável ao \fBbzip2\fP(1) com taxa de compactação +comparável ou melhor, embora os resultados dependam muito do tipo de dados +que estão sendo compactados. +.TP +\fB\-4\fP ... \fB\-6\fP +Compactação boa a muito boa, mantendo o uso de memória do descompactador +razoável mesmo para sistemas antigos. \fB\-6\fP é o padrão, que geralmente é uma +boa escolha para distribuir arquivos que precisam ser descompactáveis, mesmo +em sistemas com apenas 16\ MiB de RAM. (\fB\-5e\fP ou \fB\-6e\fP também vale a pena +considerar. Veja \fB\-\-extreme\fP.) +.TP +\fB\-7 ... \-9\fP +Eles são como \fB\-6\fP, mas com requisitos de memória de compressor e +descompressor mais altos. Eles são úteis apenas ao compactar arquivos +maiores que 8\ MiB, 16\ MiB e 32\ MiB, respectivamente. +.RE +.IP "" +No mesmo hardware, a velocidade de descompactação é aproximadamente um +número constante de bytes de dados compactados por segundo. Em outras +palavras, quanto melhor a compactação, mais rápida será a +descompactação. Isso também significa que a quantidade de saída não +compactada produzida por segundo pode variar muito. +.IP "" +A tabela a seguir resume os recursos das predefinições: +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Predefinição;DicTam;CompCPU;CompMem;DecMem +\-0;256 KiB;0;3 MiB;1 MiB +\-1;1 MiB;1;9 MiB;2 MiB +\-2;2 MiB;2;17 MiB;3 MiB +\-3;4 MiB;3;32 MiB;5 MiB +\-4;4 MiB;4;48 MiB;5 MiB +\-5;8 MiB;5;94 MiB;9 MiB +\-6;8 MiB;6;94 MiB;9 MiB +\-7;16 MiB;6;186 MiB;17 MiB +\-8;32 MiB;6;370 MiB;33 MiB +\-9;64 MiB;6;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Descrições das colunas: +.RS +.IP \(bu 3 +DicTam é o tamanho do dicionário LZMA2. É desperdício de memória usar um +dicionário maior que o tamanho do arquivo descompactado. É por isso que é +bom evitar usar as predefinições \fB\-7\fP ... \fB\-9\fP quando não há real +necessidade deles. Em \fB\-6\fP e inferior, a quantidade de memória desperdiçada +geralmente é baixa o suficiente para não importar. +.IP \(bu 3 +CompCPU é uma representação simplificada das configurações LZMA2 que afetam +a velocidade de compactação. O tamanho do dicionário também afeta a +velocidade, portanto, embora o CompCPU seja o mesmo para os níveis \fB\-6\fP +\&... \fB\-9\fP, níveis mais altos ainda tendem a ser um pouco mais lentos. Para +obter uma compactação ainda mais lenta e possivelmente melhor, consulte +\fB\-\-extreme\fP. +.IP \(bu 3 +CompMem contains the compressor memory requirements in the single\-threaded +mode. It may vary slightly between \fBxz\fP versions. +.IP \(bu 3 +DecMem contém os requisitos de memória do descompactador. Ou seja, as +configurações de compactação determinam os requisitos de memória do +descompactador. O uso exato da memória do descompactador é um pouco maior do +que o tamanho do dicionário LZMA2, mas os valores na tabela foram +arredondados para o próximo MiB completo. +.RE +.IP "" +Memory requirements of the multi\-threaded mode are significantly higher than +that of the single\-threaded mode. With the default value of +\fB\-\-block\-size\fP, each thread needs 3*3*DictSize plus CompMem or DecMem. For +example, four threads with preset \fB\-6\fP needs 660\(en670\ MiB of memory. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +Usa uma variante mais lenta do nível de predefinição de compactação +selecionado (\fB\-0\fP ... \fB\-9\fP) para obter uma taxa de compactação um pouco +melhor, mas, com azar, isso também pode piorar. O uso da memória do +descompressor não é afetado, mas o uso da memória do compactador aumenta um +pouco nos níveis de predefinição \fB\-0\fP ... \fB\-3\fP. +.IP "" +Como existem duas predefinições com tamanhos de dicionário 4\ MiB e 8\ MiB, +as predefinições \fB\-3e\fP e \fB\-5e\fP usam configurações um pouco mais rápidas +(CompCPU inferior) do que \fB\-4e\fP e \fB\-6e\fP, respectivamente. Dessa forma, não +há duas predefinições idênticas. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Predefinição;DicTam;CompCPU;CompMem;DecMem +\-0e;256 KiB;8;4 MiB;1 MiB +\-1e;1 MiB;8;13 MiB;2 MiB +\-2e;2 MiB;8;25 MiB;3 MiB +\-3e;4 MiB;7;48 MiB;5 MiB +\-4e;4 MiB;8;48 MiB;5 MiB +\-5e;8 MiB;7;94 MiB;9 MiB +\-6e;8 MiB;8;94 MiB;9 MiB +\-7e;16 MiB;8;186 MiB;17 MiB +\-8e;32 MiB;8;370 MiB;33 MiB +\-9e;64 MiB;8;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Por exemplo, há um total de quatro predefinições que usam o dicionário 8\ MiB, cuja ordem do mais rápido ao mais lento é \fB\-5\fP, \fB\-6\fP, \fB\-5e\fP e +\fB\-6e\fP. +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +Esses são apelidos um tanto enganosos para \fB\-0\fP e \fB\-9\fP, +respectivamente. Eles são fornecidos apenas para compatibilidade com versões +anteriores do LZMA Utils. Evite usar essas opções. +.TP +\fB\-\-block\-size=\fP\fItamanho\fP +Ao compactar para o formato \fB.xz\fP, divida os dados de entrada em blocos de +\fItamanho\fP bytes. Os blocos são compactados independentemente uns dos +outros, o que ajuda no multi\-threading e torna possível a descompactação +limitada de acesso aleatório. Essa opção normalmente é usada para substituir +o tamanho de bloco padrão no modo multi\-thread, mas também pode ser usada em +thread única. +.IP "" +In multi\-threaded mode about three times \fIsize\fP bytes will be allocated in +each thread for buffering input and output. The default \fIsize\fP is three +times the LZMA2 dictionary size or 1 MiB, whichever is more. Typically a +good value is 2\(en4 times the size of the LZMA2 dictionary or at least 1 +MiB. Using \fIsize\fP less than the LZMA2 dictionary size is waste of RAM +because then the LZMA2 dictionary buffer will never get fully used. In +multi\-threaded mode, the sizes of the blocks are stored in the block +headers. This size information is required for multi\-threaded +decompression. +.IP "" +In single\-threaded mode no block splitting is done by default. Setting this +option doesn't affect memory usage. No size information is stored in block +headers, thus files created in single\-threaded mode won't be identical to +files created in multi\-threaded mode. The lack of size information also +means that \fBxz\fP won't be able decompress the files in multi\-threaded mode. +.TP +\fB\-\-block\-list=\fP\fIitems\fP +When compressing to the \fB.xz\fP format, start a new block with an optional +custom filter chain after the given intervals of uncompressed data. +.IP "" +The \fIitems\fP are a comma\-separated list. Each item consists of an optional +filter chain number between 0 and 9 followed by a colon (\fB:\fP) and a +required size of uncompressed data. Omitting an item (two or more +consecutive commas) is a shorthand to use the size and filters of the +previous item. +.IP "" +If the input file is bigger than the sum of the sizes in \fIitems\fP, the last +item is repeated until the end of the file. A special value of \fB0\fP may be +used as the last size to indicate that the rest of the file should be +encoded as a single block. +.IP "" +An alternative filter chain for each block can be specified in combination +with the \fB\-\-filters1=\fP\fIfilters\fP \&...\& \fB\-\-filters9=\fP\fIfilters\fP options. +These options define filter chains with an identifier between 1\(en9. +Filter chain 0 can be used to refer to the default filter chain, which is +the same as not specifying a filter chain. The filter chain identifier can +be used before the uncompressed size, followed by a colon (\fB:\fP). For +example, if one specifies \fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP +then blocks will be created using: +.RS +.IP \(bu 3 +The filter chain specified by \fB\-\-filters1\fP and 2 MiB input +.IP \(bu 3 +The filter chain specified by \fB\-\-filters3\fP and 2 MiB input +.IP \(bu 3 +The filter chain specified by \fB\-\-filters2\fP and 4 MiB input +.IP \(bu 3 +The filter chain specified by \fB\-\-filters2\fP and 4 MiB input +.IP \(bu 3 +The default filter chain and 2 MiB input +.IP \(bu 3 +The default filter chain and 4 MiB input for every block until end of input. +.RE +.IP "" +If one specifies a size that exceeds the encoder's block size (either the +default value in threaded mode or the value specified with +\fB\-\-block\-size=\fP\fIsize\fP), the encoder will create additional blocks while +keeping the boundaries specified in \fIitems\fP. For example, if one specifies +\fB\-\-block\-size=10MiB\fP \fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP and the +input file is 80 MiB, one will get 11 blocks: 5, 10, 8, 10, 2, 10, 10, 4, +10, 10, and 1 MiB. +.IP "" +No modo multi\-thread, os tamanhos dos blocos são armazenados nos cabeçalhos +dos blocos. Isso não é feito no modo de thread única, portanto, a saída +codificada não será idêntica à do modo multi\-thread. +.TP +\fB\-\-flush\-timeout=\fP\fItempo_limite\fP +Ao compactar, se mais de \fItempo_limite\fP milissegundos (um número inteiro +positivo) se passaram desde a liberação anterior e a leitura de mais entrada +seria bloqueada, todos os dados de entrada pendentes serão liberados do +codificador e disponibilizados no fluxo de saída. Isso pode ser útil se +\fBxz\fP for usado para compactar dados transmitidos por uma rede. Valores +\fItempo_limite\fP pequenos tornam os dados disponíveis na extremidade +receptora com um pequeno atraso, mas valores \fItempo_limite\fP grandes +oferecem melhor taxa de compactação. +.IP "" +Esse recurso está desabilitado por padrão. Se esta opção for especificada +mais de uma vez, a última terá efeito. O valor especial \fItempo_limite\fP de +\fB0\fP pode ser usado para desabilitar explicitamente esse recurso. +.IP "" +Este recurso não está disponível em sistemas não\-POSIX. +.IP "" +.\" FIXME +\fBEste recurso ainda é experimental.\fP Atualmente, \fBxz\fP não é adequado para +descompactar o fluxo em tempo real devido à forma como \fBxz\fP faz o buffer. +.TP +\fB\-\-no\-sync\fP +Do not synchronize the target file and its directory to the storage device +before removing the source file. This can improve performance if +compressing or decompressing many small files. However, if the system +crashes soon after the deletion, it is possible that the target file was not +written to the storage device but the delete operation was. In that case +neither the original source file nor the target file is available. +.IP "" +This option has an effect only when \fBxz\fP is going to remove the source +file. In other cases synchronization is never done. +.IP "" +The synchronization and \fB\-\-no\-sync\fP were added in \fBxz\fP 5.7.1alpha. +.TP +\fB\-\-memlimit\-compress=\fP\fIlimite\fP +Define um limite de uso de memória para compactação. Se esta opção for +especificada várias vezes, a última entrará em vigor. +.IP "" +Se as configurações de compactação excederem o \fIlimite\fP, \fBxz\fP tentará +ajustar as configurações para baixo para que o limite não seja mais excedido +e exibirá um aviso de que o ajuste automático foi feito. Os ajustes são +feitos nesta ordem: reduzindo o número de encadeamentos, alternando para o +modo sigle\-thread se até mesmo uma thread no modo multi\-thread exceder o +\fIlimite\fP e, finalmente, reduzindo o tamanho do dicionário LZMA2. +.IP "" +Ao compactar com \fB\-\-format=raw\fP ou se \fB\-\-no\-adjust\fP tiver sido +especificado, apenas o número de threads pode ser reduzido, pois isso pode +ser feito sem afetar a saída compactada. +.IP "" +Se o \fIlimite\fP não puder ser alcançado mesmo com os ajustes descritos acima, +um erro será exibido e \fBxz\fP sairá com status de saída 1. +.IP "" +O \fIlimite\fP pode ser especificado de várias maneiras: +.RS +.IP \(bu 3 +O \fIlimite\fP pode ser um valor absoluto em bytes. Usar um sufixo inteiro como +\fBMiB\fP pode ser útil. Exemplo: \fB\-\-memlimit\-compress=80MiB\fP +.IP \(bu 3 +O \fIlimite\fP pode ser especificado como uma porcentagem da memória física +total (RAM). Isso pode ser útil especialmente ao definir a variável de +ambiente \fBXZ_DEFAULTS\fP em um script de inicialização de shell que é +compartilhado entre diferentes computadores. Dessa forma o limite é +automaticamente maior em sistemas com mais memória. Exemplo: +\fB\-\-memlimit\-compress=70%\fP +.IP \(bu 3 +O \fIlimite\fP pode ser redefinido para seu valor padrão, definindo\-o como +\fB0\fP. Atualmente, isso equivale a definir \fIlimite\fP como \fBmax\fP (sem limite +de uso de memória). +.RE +.IP "" +Para \fBxz\fP de 32 bits, há um caso especial: se o \fIlimite\fP estiver acima de +\fB4020\ MiB\fP, o \fIlimite\fP é definido como \fB4020\ MiB\fP. No MIPS32 \fB2000\ MiB\fP é usado em seu lugar. (Os valores \fB0\fP e \fBmax\fP não são afetados por +isso. Um recurso semelhante não existe para descompactação.) Isso pode ser +útil quando um executável de 32 bits tem acesso a espaço de endereço de 4\ GiB (2 GiB no MIPS32) enquanto espero não causar danos em outras situações. +.IP "" +Consulte também a seção \fBUso de memória\fP. +.TP +\fB\-\-memlimit\-decompress=\fP\fIlimite\fP +Define um limite de uso de memória para descompactação. Isso também afeta o +modo \fB\-\-list\fP. Se a operação não for possível sem exceder o \fIlimite\fP, +\fBxz\fP exibirá um erro e a descompactação do arquivo falhará. Consulte +\fB\-\-memlimit\-compress=\fP\fIlimite\fP para possíveis maneiras de especificar o +\fIlimite\fP. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fIlimite\fP +Define um limite de uso de memória para descompactação multi\-thread. Isso +pode afetar apenas o número de threads; isso nunca fará com que \fBxz\fP se +recuse a descompactar um arquivo. Se \fIlimite\fP for muito baixo para permitir +qualquer multi\-thread, o \fIlimite\fP será ignorado e \fBxz\fP continuará no modo +de thread única. Observe que se \fB\-\-memlimit\-decompress\fP também for usado, +ele sempre se aplicará aos modos de thread única e multi\-thread e, portanto, +o \fIlimite\fP efetivo para multi\-threading nunca será maior que o limite +definido com \fB\-\-memlimit\-decompress\fP. +.IP "" +Em contraste com as outras opções de limite de uso de memória, +\fB\-\-memlimit\-mt\-decompress=\fP\fIlimite\fP tem um padrão \fIlimite\fP específico do +sistema. \fBxz \-\-info\-memory\fP pode ser usado para ver o valor atual. +.IP "" +Esta opção e seu valor padrão existem porque, sem qualquer limite, o +descompactador usando threads pode acabar alocando uma quantidade insana de +memória com alguns arquivos de entrada. Se o \fIlimite\fP padrão for muito +baixo em seu sistema, sinta\-se à vontade para aumentar o \fIlimite\fP, mas +nunca defina\-o para um valor maior que a quantidade de RAM utilizável, pois +com os arquivos de entrada apropriados \fBxz\fP tentará usar essa quantidade de +memória mesmo com um baixo número de threads. Ficar sem memória ou trocar +não melhorará o desempenho da descompactação. +.IP "" +Consulte \fB\-\-memlimit\-compress=\fP\fIlimite\fP para possíveis maneiras de +especificar o \fIlimite\fP. Definir \fIlimite\fP como \fB0\fP redefine \fIlimite\fP para +o valor padrão específico do sistema. +.TP +\fB\-M\fP \fIlimite\fP, \fB\-\-memlimit=\fP\fIlimite\fP, \fB\-\-memory=\fP\fIlimite\fP +Isso é equivalente a especificar \fB\-\-memlimit\-compress=\fP\fIlimite\fP +\fB\-\-memlimit\-decompress=\fP\fIlimite\fP \fB\-\-memlimit\-mt\-decompress=\fP\fIlimite\fP. +.TP +\fB\-\-no\-adjust\fP +Exibe um erro e saia se o limite de uso de memória não puder ser atendido +sem ajustar as configurações que afetam a saída compactada. Ou seja, isso +evita que \fBxz\fP alterne o codificador do modo multi\-thread para o modo +encadeado único e reduza o tamanho do dicionário LZMA2. Mesmo quando esta +opção é usada, o número de threads pode ser reduzido para atender ao limite +de uso de memória, pois isso não afetará a saída compactada. +.IP "" +O ajuste automático é sempre desativado ao criar fluxos brutos +(\fB\-\-format=raw\fP). +.TP +\fB\-T\fP \fIthreads\fP, \fB\-\-threads=\fP\fIthreads\fP +Especifica o número de threads de trabalho a serem usados. Definir +\fIthreads\fP para um valor especial \fB0\fP faz com que \fBxz\fP use tantos threads +quanto o(s) processador(es) no suporte do sistema. O número real de +encadeamentos pode ser menor que \fIthreads\fP se o arquivo de entrada não for +grande o suficiente para subdividir em threads com as configurações +fornecidas ou se o uso de mais threads exceder o limite de uso de memória. +.IP "" +Os compactadores usando thread única e várias threads produzem saídas +diferentes. O compactador de thread única fornecerá o menor tamanho de +arquivo, mas apenas a saída do compactador de várias threads pode ser +descompactada usando várias threads. Definir \fIthreads\fP como \fB1\fP usará o +modo de thread única. Definir \fIthreads\fP para qualquer outro valor, +incluindo \fB0\fP, usará o compressor de várias threads, mesmo que o sistema +tenha suporte a apenas uma thread de hardware. (\fBxz\fP 5.2.x usou o modo de +thread única nesta situação.) +.IP "" +Para usar o modo de várias threads com apenas uma thread, defina \fIthreads\fP +como \fB+1\fP. O prefixo \fB+\fP não tem efeito com valores diferentes de \fB1\fP. Um +limite de uso de memória ainda pode fazer \fBxz\fP alternar para o modo de +thread única, a menos que \fB\-\-no\-adjust\fP seja usado. O suporte para o +prefixo \fB+\fP foi adicionado no \fBxz\fP 5.4.0. +.IP "" +Se um número automático de threads foi solicitado e nenhum limite de uso de +memória foi especificado, um limite flexível padrão específico do sistema +será usado para possivelmente limitar o número de threads. É um limite +flexível no sentido de que é ignorado se o número de threads se tornar um, +portanto, um limite flexível nunca impedirá \fBxz\fP de compactar ou +descompactar. Este limite flexível padrão não fará com que \fBxz\fP alterne do +modo de várias threads para o modo de thread única. Os limites ativos podem +ser vistos com \fBxz \-\-info\-memory\fP. +.IP "" +Atualmente, o único método de threading é dividir a entrada em blocos e +comprimi\-los independentemente um do outro. O tamanho padrão do bloco +depende do nível de compactação e pode ser substituído com a opção +\fB\-\-block\-size=\fP\fItamanho\fP. +.IP "" +A descompactação em threads funciona apenas em arquivos que contêm vários +blocos com informações de tamanho nos cabeçalhos dos blocos. Todos os +arquivos grandes o suficiente compactados no modo de várias thread atendem a +essa condição, mas os arquivos compactados no modo de thread única não +atendem, mesmo se \fB\-\-block\-size=\fP\fItamanho\fP tiver sido usado. +.IP "" +The default value for \fIthreads\fP is \fB0\fP. In \fBxz\fP 5.4.x and older the +default is \fB1\fP. +. +.SS "Cadeias de filtro de compressor personalizadas" +Uma cadeia de filtro personalizada permite especificar as configurações de +compactação em detalhes, em vez de confiar nas configurações associadas às +predefinições. Quando uma cadeia de filtro personalizada é especificada, as +opções predefinidas (\fB\-0\fP \&...\& \fB\-9\fP e \fB\-\-extreme\fP) anteriores na linha +de comando são esquecidas. Se uma opção predefinida for especificada após +uma ou mais opções de cadeia de filtros personalizados, a nova predefinição +entrará em vigor e as opções de cadeia de filtros personalizados +especificadas anteriormente serão esquecidas. +.PP +Uma cadeia de filtro é comparável à tubulação na linha de comando. Ao +compactar, a entrada descompactada vai para o primeiro filtro, cuja saída +vai para o próximo filtro (se houver). A saída do último filtro é gravada no +arquivo compactado. O número máximo de filtros na cadeia é quatro, mas +normalmente uma cadeia de filtros tem apenas um ou dois filtros. +.PP +Muitos filtros têm limitações sobre onde podem estar na cadeia de filtros: +alguns filtros podem funcionar apenas como o último filtro na cadeia, alguns +apenas como filtro não\-último e alguns funcionam em qualquer posição na +cadeia. Dependendo do filtro, essa limitação é inerente ao projeto do filtro +ou existe para evitar problemas de segurança. +.PP +A custom filter chain can be specified in two different ways. The options +\fB\-\-filters=\fP\fIfilters\fP and \fB\-\-filters1=\fP\fIfilters\fP \&...\& +\fB\-\-filters9=\fP\fIfilters\fP allow specifying an entire filter chain in one +option using the liblzma filter string syntax. Alternatively, a filter +chain can be specified by using one or more individual filter options in the +order they are wanted in the filter chain. That is, the order of the +individual filter options is significant! When decoding raw streams +(\fB\-\-format=raw\fP), the filter chain must be specified in the same order as +it was specified when compressing. Any individual filter or preset options +specified before the full chain option (\fB\-\-filters=\fP\fIfilters\fP) will be +forgotten. Individual filters specified after the full chain option will +reset the filter chain. +.PP +Both the full and individual filter options take filter\-specific \fIoptions\fP +as a comma\-separated list. Extra commas in \fIoptions\fP are ignored. Every +option has a default value, so specify those you want to change. +.PP +Para ver toda a cadeia de filtros e \fIopções\fP, use \fBxz \-vv\fP (isto é, use +\fB\-\-verbose\fP duas vezes). Isso também funciona para visualizar as opções da +cadeia de filtros usadas pelas predefinições. +.TP +\fB\-\-filters=\fP\fIfilters\fP +Specify the full filter chain or a preset in a single option. Each filter +can be separated by spaces or two dashes (\fB\-\-\fP). \fIfilters\fP may need to be +quoted on the shell command line so it is parsed as a single option. To +denote \fIoptions\fP, use \fB:\fP or \fB=\fP. A preset can be prefixed with a \fB\-\fP +and followed with zero or more flags. The only supported flag is \fBe\fP to +apply the same options as \fB\-\-extreme\fP. +.TP +\fB\-\-filters1\fP=\fIfilters\fP ... \fB\-\-filters9\fP=\fIfilters\fP +Specify up to nine additional filter chains that can be used with +\fB\-\-block\-list\fP. +.IP "" +For example, when compressing an archive with executable files followed by +text files, the executable part could use a filter chain with a BCJ filter +and the text part only the LZMA2 filter. +.TP +\fB\-\-filters\-help\fP +Display a help message describing how to specify presets and custom filter +chains in the \fB\-\-filters\fP and \fB\-\-filters1=\fP\fIfilters\fP \&...\& +\fB\-\-filters9=\fP\fIfilters\fP options, and exit successfully. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fIopções\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fIopções\fP] +.PD +Adiciona o filtro LZMA1 ou LZMA2 à cadeia de filtros. Esses filtros podem +ser usados apenas como o último filtro na cadeia. +.IP "" +LZMA1 é um filtro legado, que é suportado quase exclusivamente devido ao +formato de arquivo legado \fB.lzma\fP, que suporta apenas LZMA1. LZMA2 é uma +versão atualizada do LZMA1 para corrigir alguns problemas práticos do +LZMA1. O formato \fB.xz\fP usa LZMA2 e não suporta LZMA1. A velocidade de +compactação e as proporções de LZMA1 e LZMA2 são praticamente as mesmas. +.IP "" +LZMA1 e LZMA2 compartilham o mesmo conjunto de \fIopções\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fIpredefinição\fP +Redefine todas as \fIopções\fP de LZMA1 ou LZMA2 para +\fIpredefinição\fP. \fIPredefinição\fP consiste em um número inteiro, que pode ser +seguido por modificadores de predefinição de uma única letra. O inteiro pode +ser de \fB0\fP a \fB9\fP, correspondendo às opções de linha de comando \fB\-0\fP +\&...\& \fB\-9\fP. O único modificador suportado atualmente é \fBe\fP, que +corresponde a \fB\-\-extreme\fP. Se nenhum \fBpreset\fP for especificado, os valores +padrão das \fIopções\fP LZMA1 ou LZMA2 serão obtidos da predefinição \fB6\fP. +.TP +\fBdict=\fP\fItamanho\fP +O \fItamanho\fP do dicionário (buffer de histórico) indica quantos bytes dos +dados não compactados processados recentemente são mantidos na memória. O +algoritmo tenta encontrar sequências de bytes repetidos (correspondências) +nos dados não compactados e substituí\-los por referências aos dados +atualmente no dicionário. Quanto maior o dicionário, maior a chance de +encontrar uma correspondência. Portanto, aumentar o dicionário \fItamanho\fP +geralmente melhora a taxa de compactação, mas um dicionário maior que o +arquivo não compactado é um desperdício de memória. +.IP "" +Um \fItamanho\fP de dicionário típico é de 64\ KiB a 64\ MiB. O mínimo é 4\ KiB. O máximo para compactação é atualmente 1,5\ GiB (1536\ MiB). O +descompactador já oferece suporte a dicionários de até um byte a menos de 4\ GiB, que é o máximo para os formatos de fluxo LZMA1 e LZMA2. +.IP "" +O \fItamanho\fP de dicionário e o localizador de correspondência (\fImf\fP) juntos +determinam o uso de memória do codificador LZMA1 ou LZMA2. O mesmo (ou +maior) \fItamanho\fP de dicionário é necessário para descompactar que foi usado +durante a compactação, portanto, o uso de memória do decodificador é +determinado pelo tamanho do dicionário usado durante a compactação. Os +cabeçalhos \fB.xz\fP armazenam o \fItamanho\fP de dicionário como 2^\fIn\fP ou 2^\fIn\fP ++ 2^(\fIn\fP\-1), então esses \fItamanhos\fP são um tanto preferidos para +compactação. Outros \fItamanhos\fP serão arredondados quando armazenados nos +cabeçalhos \fB.xz\fP. +.TP +\fBlc=\fP\fIlc\fP +Especifica o número de bits de contexto literais. O mínimo é 0 e o máximo é +4; o padrão é 3. Além disso, a soma de \fIlc\fP e \fIlp\fP não deve exceder 4. +.IP "" +Todos os bytes que não podem ser codificados como correspondências são +codificados como literais. Ou seja, literais são simplesmente bytes de 8 +bits que são codificados um de cada vez. +.IP "" +A codificação literal assume que os bits \fIlc\fP mais altos do byte não +compactado anterior se correlacionam com o próximo byte. Por exemplo, em um +texto típico em inglês, uma letra maiúscula geralmente é seguida por uma +letra minúscula, e uma letra minúscula geralmente é seguida por outra letra +minúscula. No conjunto de caracteres US\-ASCII, os três bits mais altos são +010 para letras maiúsculas e 011 para letras minúsculas. Quando \fIlc\fP é pelo +menos 3, a codificação literal pode aproveitar essa propriedade nos dados +não compactados. +.IP "" +O valor padrão (3) geralmente é bom. Se você deseja compactação máxima, +experimente \fBlc=4\fP. Às vezes ajuda um pouco, às vezes piora a +compactação. Se piorar, experimente \fBlc=2\fP também. +.TP +\fBlp=\fP\fIlp\fP +Especifica o número de bits de posição literal. O mínimo é 0 e o máximo é 4; +o padrão é 0. +.IP "" +\fILp\fP afeta que tipo de alinhamento nos dados não compactados é assumido ao +codificar literais. Consulte \fIpb\fP abaixo para obter mais informações sobre +alinhamento. +.TP +\fBpb=\fP\fIpb\fP +Especifica o número de bits de posição. O mínimo é 0 e o máximo é 4; o +padrão é 2. +.IP "" +\fIPb\fP afeta que tipo de alinhamento nos dados não compactados é assumido em +geral. O padrão significa alinhamento de quatro bytes (2^\fIpb\fP=2^2=4), que +geralmente é uma boa escolha quando não há melhor estimativa. +.IP "" +Quando o alinhamento é conhecido, definir \fIpb\fP adequadamente pode reduzir +um pouco o tamanho do arquivo. Por exemplo, com arquivos de texto com +alinhamento de um byte (US\-ASCII, ISO\-8859\-*, UTF\-8), a configuração \fBpb=0\fP +pode melhorar um pouco a compactação. Para texto UTF\-16, \fBpb=1\fP é uma boa +escolha. Se o alinhamento for um número ímpar como 3 bytes, \fBpb=0\fP pode ser +a melhor escolha. +.IP "" +Embora o alinhamento assumido possa ser ajustado com \fIpb\fP e \fIlp\fP, LZMA1 e +LZMA2 ainda favorecem ligeiramente o alinhamento de 16 bytes. Pode valer a +pena levar em consideração ao projetar formatos de arquivo que provavelmente +serão compactados com LZMA1 ou LZMA2. +.TP +\fBmf=\fP\fImf\fP +O localizador de correspondência tem um efeito importante na velocidade do +codificador, uso de memória e taxa de compactação. Normalmente, os +localizadores de correspondência de Hash Chain são mais rápidos do que os +localizadores de correspondência de árvore binária. O padrão depende do +\fIpredefinição\fP: 0 usa \fBhc3\fP, 1\(en3 usa \fBhc4\fP e o resto usa \fBbt4\fP. +.IP "" +Os seguintes localizadores de correspondência são suportados. As fórmulas de +uso de memória abaixo são aproximações aproximadas, que estão mais próximas +da realidade quando \fIdict\fP é uma potência de dois. +.RS +.TP +\fBhc3\fP +Cadeia de hashs com hashing de 2 e 3 bytes +.br +Valor mínimo para \fInice\fP: 3 +.br +Uso de memória: +.br +\fIdict\fP * 7.5 (if \fIdict\fP <= 16 MiB); +.br +\fIdict\fP * 5.5 + 64 MiB (if \fIdict\fP > 16 MiB) +.TP +\fBhc4\fP +Cadeia de hashs com hashing de 2, 3 e 4 bytes +.br +Valor mínimo para \fInice\fP: 4 +.br +Uso de memória: +.br +\fIdict\fP * 7.5 (if \fIdict\fP <= 32 MiB); +.br +\fIdict\fP * 6.5 (if \fIdict\fP > 32 MiB) +.TP +\fBbt2\fP +Ãrvore binária com hashing de 2 bytes +.br +Valor mínimo para \fInice\fP: 2 +.br +Uso de memória: \fIdict\fP * 9.5 +.TP +\fBbt3\fP +Ãrvore binária com hashing de 2 e 3 bytes +.br +Valor mínimo para \fInice\fP: 3 +.br +Uso de memória: +.br +\fIdict\fP * 11.5 (if \fIdict\fP <= 16 MiB); +.br +\fIdict\fP * 9.5 + 64 MiB (if \fIdict\fP > 16 MiB) +.TP +\fBbt4\fP +Ãrvore binária com hashing de 2, 3 e 4 bytes +.br +Valor mínimo para \fInice\fP: 4 +.br +Uso de memória: +.br +\fIdict\fP * 11.5 (if \fIdict\fP <= 32 MiB); +.br +\fIdict\fP * 10.5 (if \fIdict\fP > 32 MiB) +.RE +.TP +\fBmode=\fP\fImodo\fP +O \fImodo\fP de compactação especifica o método para analisar os dados +produzidos pelo localizador de correspondência. Os \fImodos\fP suportados são +\fBfast\fP e \fBnormal\fP. O padrão é \fBfast\fP para \fIpredefinições\fP 0\(en3 e +\fBnormal\fP para \fIpredefinições\fP 4\(en9. +.IP "" +Normalmente, \fBfast\fP é usado com localizadores de correspondência cadeia de +hashs e \fBnormal\fP com localizadores de correspondência de árvore +binária. Isso também é o que os \fIpredefinições\fP fazem. +.TP +\fBnice=\fP\fInice\fP +Especifica o que é considerado um bom comprimento para uma +correspondência. Uma vez que uma correspondência de pelo menos \fInice\fP bytes +é encontrada, o algoritmo para de procurar correspondências possivelmente +melhores. +.IP "" +\fINice\fP pode ser 2\(en273 bytes. Valores mais altos tendem a fornecer melhor +taxa de compactação em detrimento da velocidade. O padrão depende do +\fIpredefinição\fP. +.TP +\fBdepth=\fP\fIprofundidade\fP +Especifica a profundidade máxima de pesquisa no localizador de +correspondências. O padrão é o valor especial de 0, que faz com que o +compressor determine um \fIprofundidade\fP razoável de \fImf\fP e \fInice\fP. +.IP "" +Uma \fIprofundidade\fP razoável para cadeias de hash é 4\(en100 e 16\(en1000 +para árvores binárias. Usar valores muito altos para \fIprofundidade\fP pode +tornar o codificador extremamente lento com alguns arquivos. Evite definir +\fIprofundidade\fP acima de 1000 a menos que você esteja preparado para +interromper a compactação caso ela esteja demorando muito. +.RE +.IP "" +Ao decodificar fluxos brutos (\fB\-\-format=raw\fP), o LZMA2 precisa apenas do +dicionário \fItamanho\fP. LZMA1 também precisa de \fIlc\fP, \fIlp\fP e \fIpb\fP. +.TP +\fB\-\-x86\fP[\fB=\fP\fIopções\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fIopções\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fIopções\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fIopções\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fIopções\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fIopções\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fIopções\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIopções\fP] +.PD +Adiciona um filtro de ramificação/chamada/salto (BCJ) à cadeia de +filtros. Esses filtros podem ser usados apenas como um filtro não último na +cadeia de filtros. +.IP "" +Um filtro BCJ converte endereços relativos no código de máquina em suas +contrapartes absolutas. Isso não altera o tamanho dos dados, mas aumenta a +redundância, o que pode ajudar o LZMA2 a produzir um arquivo \fB.xz\fP 0\(en15\ % menor. Os filtros BCJ são sempre reversíveis, portanto, usar um filtro BCJ +para o tipo errado de dados não causa nenhuma perda de dados, embora possa +piorar um pouco a taxa de compactação.Os filtros BCJ são muito rápidos e +usam uma quantidade insignificante de memória. +.IP "" +Esses filtros BCJ têm problemas conhecidos relacionados à taxa de +compactação: +.RS +.IP \(bu 3 +Alguns tipos de arquivos contendo código executável (por exemplo, arquivos +de objeto, bibliotecas estáticas e módulos do kernel do Linux) têm os +endereços nas instruções preenchidos com valores de preenchimento. Esses +filtros BCJ ainda vão fazer a conversão de endereço, o que vai piorar a +compactação desses arquivos. +.IP \(bu 3 +Se um filtro BCJ for aplicado em um arquivo, é possível que isso torne a +taxa de compactação pior do que não usar um filtro BCJ. Por exemplo, se +houver executáveis semelhantes ou mesmo idênticos, a filtragem provavelmente +tornará os arquivos menos semelhantes e, portanto, a compactação será +pior. O conteúdo de arquivos não executáveis no mesmo arquivo também pode +ser importante. Na prática tem que tentar com e sem filtro BCJ para ver qual +é melhor em cada situação. +.RE +.IP "" +Conjuntos de instruções diferentes têm alinhamento diferente: o arquivo +executável deve ser alinhado a um múltiplo desse valor nos dados de entrada +para fazer o filtro funcionar. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +Filtro;Alinhamento;Observações +x86;1;x86 32 bits ou 64 bits +ARM;4; +ARM\-Thumb;2; +ARM64;4;Alinhamento de 4096 bytes +;;é melhor +PowerPC;4;Somente big endian +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +Since the BCJ\-filtered data is usually compressed with LZMA2, the +compression ratio may be improved slightly if the LZMA2 options are set to +match the alignment of the selected BCJ filter. Examples: +.RS +.IP \(bu 3 +IA\-64 filter has 16\-byte alignment so \fBpb=4,lp=4,lc=0\fP is good with LZMA2 +(2^4=16). +.IP \(bu 3 +RISC\-V code has 2\-byte or 4\-byte alignment depending on whether the file +contains 16\-bit compressed instructions (the C extension). When 16\-bit +instructions are used, \fBpb=2,lp=1,lc=3\fP or \fBpb=1,lp=1,lc=3\fP is good. When +16\-bit instructions aren't present, \fBpb=2,lp=2,lc=2\fP is the best. +\fBreadelf \-h\fP can be used to check if "RVC" appears on the "Flags" line. +.IP \(bu 3 +ARM64 is always 4\-byte aligned so \fBpb=2,lp=2,lc=2\fP is the best. +.IP \(bu 3 +The x86 filter is an exception. It's usually good to stick to LZMA2's +defaults (\fBpb=2,lp=0,lc=3\fP) when compressing x86 executables. +.RE +.IP "" +Todos os filtros BCJ suportam as mesmas \fIopções\fP: +.RS +.TP +\fBstart=\fP\fIdeslocamento\fP +Especifica o \fIdeslocamento\fP inicial que é usado na conversão entre +endereços relativos e absolutos. O \fIdeslocamento\fP deve ser um múltiplo do +alinhamento do filtro (ver tabela acima). O padrão é zero. Na prática, o +padrão é bom; especificar um \fIdeslocamento\fP personalizado quase nunca é +útil. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fIopções\fP] +Adiciona o filtro Delta à cadeia de filtros. O filtro Delta só pode ser +usado como filtro não\-último na cadeia de filtros. +.IP "" +Atualmente, apenas o cálculo simples de delta byte a byte é suportado. Pode +ser útil ao compactar, por exemplo, imagens bitmap não compactadas ou áudio +PCM não compactado. No entanto, algoritmos de propósito especial podem +fornecer resultados significativamente melhores do que Delta + LZMA2. Isso é +verdade especialmente com áudio, que compacta mais rápido e melhor, por +exemplo, com \fBflac\fP(1). +.IP "" +\fIOpções\fP suportadas: +.RS +.TP +\fBdist=\fP\fIdistância\fP +Especifica a \fIdistância\fP do cálculo delta em bytes. \fIdistância\fP deve ser +1\(en256. O padrão é 1. +.IP "" +Por exemplo, com \fBdist=2\fP e entrada de oito bytes A1 B1 A2 B3 A3 B5 A4 B7, +a saída será A1 B1 01 02 01 02 01 02. +.RE +. +.SS "Outras opções" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Suprime avisos e avisos. Especifique isso duas vezes para suprimir erros +também. Esta opção não tem efeito no status de saída. Ou seja, mesmo que um +aviso tenha sido suprimido, o status de saída para indicar um aviso ainda é +usado. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +Ser detalhado. Se o erro padrão estiver conectado a um terminal, \fBxz\fP +exibirá um indicador de progresso. Especifique \fB\-\-verbose\fP duas vezes dará +uma saída ainda mais detalhada. +.IP "" +O indicador de progresso mostra as seguintes informações: +.RS +.IP \(bu 3 +A porcentagem de conclusão é mostrada se o tamanho do arquivo de entrada for +conhecido. Ou seja, a porcentagem não pode ser mostrada em encadeamentos +(pipe). +.IP \(bu 3 +Quantidade de dados compactados produzidos (compactando) ou consumidos +(descompactando). +.IP \(bu 3 +Quantidade de dados não compactados consumidos (compactação) ou produzidos +(descompactação). +.IP \(bu 3 +Taxa de compactação, que é calculada dividindo a quantidade de dados +compactados processados até o momento pela quantidade de dados não +compactados processados até o momento. +.IP \(bu 3 +Velocidade de compactação ou descompactação. Isso é medido como a quantidade +de dados não compactados consumidos (compactação) ou produzidos +(descompactação) por segundo. É mostrado após alguns segundos desde que +\fBxz\fP começou a processar o arquivo. +.IP \(bu 3 +Tempo decorrido no formato M:SS ou H:MM:SS. +.IP \(bu 3 +O tempo restante estimado é mostrado apenas quando o tamanho do arquivo de +entrada é conhecido e alguns segundos já se passaram desde que \fBxz\fP começou +a processar o arquivo. A hora é mostrada em um formato menos preciso que +nunca tem dois pontos, por exemplo, 2 min 30 s. +.RE +.IP "" +Quando o erro padrão não é um terminal, \fB\-\-verbose\fP fará com que \fBxz\fP +imprima o nome do arquivo, tamanho compactado, tamanho não compactado, taxa +de compactação e possivelmente também a velocidade e o tempo decorrido em +uma única linha para o erro padrão após a compactação ou descompactando o +arquivo. A velocidade e o tempo decorrido são incluídos apenas quando a +operação leva pelo menos alguns segundos. Se a operação não foi concluída, +por exemplo, devido à interrupção do usuário, também é impressa a +porcentagem de conclusão se o tamanho do arquivo de entrada for conhecido. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Não define o status de saída como 2, mesmo que uma condição digna de um +aviso tenha sido detectada. Esta opção não afeta o nível de detalhamento, +portanto, tanto \fB\-\-quiet\fP quanto \fB\-\-no\-warn\fP devem ser usados para não +exibir avisos e não alterar o status de saída. +.TP +\fB\-\-robot\fP +Imprime mensagens em um formato analisável por máquina. Isso visa facilitar +a criação de frontends que desejam usar \fBxz\fP em vez de liblzma, o que pode +ser o caso de vários scripts. A saída com esta opção habilitada deve ser +estável em versões \fBxz\fP. Consulte a seção \fBMODO ROBÔ\fP para obter detalhes. +.TP +\fB\-\-info\-memory\fP +Exibe, em formato legível por humanos, quanta memória física (RAM) e quantos +threads de processador \fBxz\fP acredita que o sistema possui e os limites de +uso de memória para compactação e descompactação e saia com êxito. +.TP +\fB\-h\fP, \fB\-\-help\fP +Exibe uma mensagem de ajuda descrevendo as opções mais usadas e sai com +sucesso. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +Exibe uma mensagem de ajuda descrevendo todos os recursos de \fBxz\fP e sai com +sucesso +.TP +\fB\-V\fP, \fB\-\-version\fP +Exibe o número da versão de \fBxz\fP e liblzma em formato legível por +humanos. Para obter uma saída analisável por máquina, especifique \fB\-\-robot\fP +antes de \fB\-\-version\fP. +. +.SH "MODO ROBÔ" +The robot mode is activated with the \fB\-\-robot\fP option. It makes the output +of \fBxz\fP easier to parse by other programs. Currently \fB\-\-robot\fP is +supported only together with \fB\-\-list\fP, \fB\-\-filters\-help\fP, \fB\-\-info\-memory\fP, +and \fB\-\-version\fP. It will be supported for compression and decompression in +the future. +. +.SS "Modo lista" +\fBxz \-\-robot \-\-list\fP usa saída separada por tabulações. A primeira coluna de +cada linha possui uma string que indica o tipo de informação encontrada +naquela linha: +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP +Esta é sempre a primeira linha ao começar a listar um arquivo. A segunda +coluna na linha é o nome do arquivo. +.TP +\fBfile\fP +Esta linha contém informações gerais sobre o arquivo \fB.xz\fP. Esta linha é +sempre impressa após a linha \fBname\fP. +.TP +\fBstream\fP +Este tipo de linha é usado somente quando \fB\-\-verbose\fP foi +especificado. Existem tantas linhas de \fBstream\fP quanto fluxos no arquivo +\&\fB.xz\fP. +.TP +\fBblock\fP +Este tipo de linha é usado somente quando \fB\-\-verbose\fP foi +especificado. Existem tantas linhas \fBblock\fP quanto blocos no arquivo +\&\fB.xz\fP. As linhas \fBblock\fP são mostradas após todas as linhas \fBstream\fP; +diferentes tipos de linha não são intercalados. +.TP +\fBsummary\fP +Este tipo de linha é usado apenas quando \fB\-\-verbose\fP foi especificado duas +vezes. Esta linha é impressa após todas as linhas de \fBblock\fP. Assim como a +linha \fBarquivo\fP, a linha \fBsummary\fP contém informações gerais sobre o +arquivo \fB.xz\fP. +.TP +\fBtotals\fP +Esta linha é sempre a última linha da saída da lista. Ele mostra as +contagens totais e tamanhos. +.PP +As colunas das linhas \fBfile\fP: +.PD 0 +.RS +.IP 2. 4 +Número de fluxos no arquivo +.IP 3. 4 +Número total de blocos no(s) fluxo(s) +.IP 4. 4 +Tamanho compactado do arquivo +.IP 5. 4 +Uncompressed size of the file +.IP 6. 4 +Taxa de compactação, por exemplo, \fB0.123\fP. Se a proporção for superior a +9.999, serão exibidos três traços (\fB\-\-\-\fP) em vez da proporção. +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +Lista separada por vírgulas de nomes de verificação de integridade. As +seguintes strings são usadas para os tipos de verificação conhecidos: +\fBNone\fP, \fBCRC32\fP, \fBCRC64\fP e \fBSHA\-256\fP. Para tipos de verificações +desconhecidos, \fBUnknown\-\fP\fIN\fP é usado, onde \fIN\fP é o ID do cheque como um +número decimal (um ou dois dígitos). +.IP 8. 4 +Tamanho total do preenchimento de fluxo no arquivo +.RE +.PD +.PP +As colunas das linhas \fBstream\fP: +.PD 0 +.RS +.IP 2. 4 +Número do fluxo (o primeiro fluxo é 1) +.IP 3. 4 +Número de blocos no fluxo +.IP 4. 4 +Deslocamento inicial compactado +.IP 5. 4 +Deslocamento inicial descompactado +.IP 6. 4 +Tamanho compactado (não inclui preenchimento de fluxo) +.IP 7. 4 +Tamanho descompactado +.IP 8. 4 +Taxa de compactação +.IP 9. 4 +Nome da verificação de integridade +.IP 10. 4 +Tamanho do preenchimento do fluxo +.RE +.PD +.PP +As colunas das linhas \fBblock\fP: +.PD 0 +.RS +.IP 2. 4 +Número do fluxo que contém este bloco +.IP 3. 4 +Número do bloco relativo ao início do fluxo (o primeiro bloco é 1) +.IP 4. 4 +Número do bloco relativo ao início do arquivo +.IP 5. 4 +Deslocamento inicial compactado em relação ao início do arquivo +.IP 6. 4 +Deslocamento inicial descompactado em relação ao início do arquivo +.IP 7. 4 +Tamanho total compactado do bloco (inclui cabeçalhos) +.IP 8. 4 +Tamanho descompactado +.IP 9. 4 +Taxa de compactação +.IP 10. 4 +Nome da verificação de integridade +.RE +.PD +.PP +Se \fB\-\-verbose\fP for especificado duas vezes, colunas adicionais serão +incluídas nas linhas \fBblock\fP. Eles não são exibidos com um único +\fB\-\-verbose\fP, porque obter essas informações requer muitas buscas e, +portanto, pode ser lento: +.PD 0 +.RS +.IP 11. 4 +Valor da verificação de integridade em hexadecimal +.IP 12. 4 +Tamanho do cabeçalho do bloco +.IP 13. 4 +Sinalizadores de bloco: \fBc\fP indica que o tamanho compactado está presente e +\fBu\fP indica que o tamanho não compactado está presente. Se o sinalizador não +estiver definido, um traço (\fB\-\fP) será exibido para manter o comprimento da +string fixo. Novos sinalizadores podem ser adicionados ao final da string no +futuro. +.IP 14. 4 +Tamanho dos dados reais compactados no bloco (isso exclui o cabeçalho do +bloco, o preenchimento do bloco e os campos de verificação) +.IP 15. 4 +Quantidade de memória (em bytes) necessária para descompactar este bloco com +esta versão \fBxz\fP +.IP 16. 4 +Cadeia de filtro. Observe que a maioria das opções usadas no momento da +compactação não pode ser conhecida, pois apenas as opções necessárias para a +descompactação são armazenadas nos cabeçalhos \fB.xz\fP. +.RE +.PD +.PP +As colunas das linhas \fBsummary\fP: +.PD 0 +.RS +.IP 2. 4 +Quantidade de memória (em bytes) necessária para descompactar este arquivo +com esta versão do \fBxz\fP +.IP 3. 4 +\fByes\fP ou \fBno\fP indicando se todos os cabeçalhos de bloco têm tamanho +compactado e tamanho não compactado armazenados neles +.PP +\fIDesde\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +Versão mínima do \fBxz\fP necessária para descompactar o arquivo +.RE +.PD +.PP +As colunas da linha \fBtotals\fP: +.PD 0 +.RS +.IP 2. 4 +Número de fluxos +.IP 3. 4 +Número de blocos +.IP 4. 4 +Tamanho compactado +.IP 5. 4 +Tamanho descompactado +.IP 6. 4 +Taxa de compactação média +.IP 7. 4 +Lista separada por vírgulas de nomes de verificação de integridade que +estavam presentes nos arquivos +.IP 8. 4 +Tamanho do preenchimento do fluxo +.IP 9. 4 +Número de arquivos. Isso está aqui para manter a ordem das colunas +anteriores a mesma das linhas \fBfile\fP. +.PD +.RE +.PP +Se \fB\-\-verbose\fP for especificado duas vezes, colunas adicionais serão +incluídas na linha \fBtotals\fP: +.PD 0 +.RS +.IP 10. 4 +Quantidade máxima de memória (em bytes) necessária para descompactar os +arquivos com esta versão do \fBxz\fP +.IP 11. 4 +\fByes\fP ou \fBno\fP indicando se todos os cabeçalhos de bloco têm tamanho +compactado e tamanho não compactado armazenados neles +.PP +\fIDesde\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +Versão mínima do \fBxz\fP necessária para descompactar o arquivo +.RE +.PD +.PP +Versões futuras podem adicionar novos tipos de linha e novas colunas podem +ser adicionadas aos tipos de linha existentes, mas as colunas existentes não +serão alteradas. +. +.SS "Filters help" +\fBxz \-\-robot \-\-filters\-help\fP prints the supported filters in the following +format: +.PP +\fIfilter\fP\fB:\fP\fIoption\fP\fB=<\fP\fIvalue\fP\fB>,\fP\fIoption\fP\fB=<\fP\fIvalue\fP\fB>\fP... +.TP +\fIfilter\fP +Name of the filter +.TP +\fIoption\fP +Name of a filter specific option +.TP +\fIvalue\fP +Numeric \fIvalue\fP ranges appear as \fB<\fP\fImin\fP\fB\-\fP\fImax\fP\fB>\fP. String +\fIvalue\fP choices are shown within \fB< >\fP and separated by a \fB|\fP +character. +.PP +Each filter is printed on its own line. +. +.SS "Informações de limite de memória" +\fBxz \-\-robot \-\-info\-memory\fP prints a single line with multiple tab\-separated +columns: +.IP 1. 4 +Quantidade total de memória física (RAM) em bytes. +.IP 2. 4 +Limite de uso de memória para compactação em bytes +(\fB\-\-memlimit\-compress\fP). Um valor especial de \fB0\fP indica a configuração +padrão que para o modo de thread única é o mesmo que sem limite. +.IP 3. 4 +Limite de uso de memória para descompactação em bytes +(\fB\-\-memlimit\-decompress\fP). Um valor especial de \fB0\fP indica a configuração +padrão que para o modo de thread única é o mesmo que sem limite. +.IP 4. 4 +Desde \fBxz\fP 5.3.4alpha: Uso de memória para descompactação com várias thread +em bytes (\fB\-\-memlimit\-mt\-decompress\fP). Isso nunca é zero porque um valor +padrão específico do sistema mostrado na coluna 5 é usado se nenhum limite +for especificado explicitamente. Isso também nunca é maior que o valor na +coluna 3, mesmo que um valor maior tenha sido especificado com +\fB\-\-memlimit\-mt\-decompress\fP. +.IP 5. 4 +Desde \fBxz\fP 5.3.4alpha: Um limite de uso de memória padrão específico do +sistema que é usado para limitar o número de threads ao compactar com um +número automático de threads (\fB\-\-threads=0\fP) e nenhum limite de uso de +memória foi especificado (\fB\-\-memlimit\-compress\fP). Isso também é usado como +o valor padrão para \fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +Desde \fBxz\fP 5.3.4alpha: Número de threads de processador disponíveis. +.PP +No futuro, a saída de \fBxz \-\-robot \-\-info\-memory\fP pode ter mais colunas, mas +nunca mais do que uma única linha. +. +.SS Versão +\fBxz \-\-robot \-\-version\fP prints the version number of \fBxz\fP and liblzma in +the following format: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +Versão principal. +.TP +\fIYYY\fP +Versão menor. Números pares são estáveis. Os números ímpares são versões +alfa ou beta. +.TP +\fIZZZ\fP +Nível de patch para versões estáveis ou apenas um contador para versões de +desenvolvimento. +.TP +\fIS\fP +Estabilidade. 0 é alfa, 1 é beta e 2 é estável. \fIS\fP deve ser sempre 2 +quando \fIYYY\fP for par. +.PP +\fIXYYYZZZS\fP são iguais em ambas as linhas se \fBxz\fP e liblzma forem da mesma +versão do XZ Utils. +.PP +Exemplos: 4.999.9beta é \fB49990091\fP e 5.0.0 é \fB50000002\fP. +. +.SH "STATUS DE SAÃDA" +.TP +\fB0\fP +Está tudo bem. +.TP +\fB1\fP +Ocorreu um erro. +.TP +\fB2\fP +Algo digno de um aviso ocorreu, mas ocorreu nenhum erro real. +.PP +Observações (não avisos ou erros) impressas no erro padrão não afetam o +status de saída. +. +.SH AMBIENTE +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP analisa listas de opções separadas por espaços das variáveis de +ambiente \fBXZ_DEFAULTS\fP e \fBXZ_OPT\fP, nesta ordem, antes de analisar as +opções da linha de comando. Observe que apenas as opções são analisadas a +partir das variáveis de ambiente; todas as não opções são silenciosamente +ignoradas. A análise é feita com \fBgetopt_long\fP(3) que também é usado para +os argumentos da linha de comando. +.PP +\fBWarning:\fP By setting these environment variables, one is effectively +modifying programs and scripts that run \fBxz\fP. Most of the time it is safe +to set memory usage limits, number of threads, and compression options via +the environment variables. However, some options can break scripts. An +obvious example is \fB\-\-help\fP which makes \fBxz\fP show the help text instead of +compressing or decompressing a file. More subtle examples are \fB\-\-quiet\fP +and \fB\-\-verbose\fP. In many cases it works well to enable the progress +indicator using \fB\-\-verbose\fP, but in some situations the extra messages +create problems. The verbosity level also affects the behavior of +\fB\-\-list\fP. +.TP +\fBXZ_DEFAULTS\fP +User\-specific or system\-wide default options. Typically this is set in a +shell initialization script to enable \fBxz\fP's memory usage limiter by +default or set the default number of threads. Excluding shell +initialization scripts and similar special cases, scripts should never set +or unset \fBXZ_DEFAULTS\fP. +.TP +\fBXZ_OPT\fP +Isso é para passar opções para \fBxz\fP quando não é possível definir as opções +diretamente na linha de comando \fBxz\fP. Este é o caso quando \fBxz\fP é +executado por um script ou ferramenta, por exemplo, GNU \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +Os scripts podem usar \fBXZ_OPT\fP, por exemplo, para definir opções de +compactação padrão específicas do script. Ainda é recomendável permitir que +os usuários substituam \fBXZ_OPT\fP se isso for razoável. Por exemplo, em +scripts \fBsh\fP(1) pode\-se usar algo assim: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "COMPATIBILIDADE COM LZMA UTILS" +A sintaxe da linha de comando do \fBxz\fP é praticamente um superconjunto de +\fBlzma\fP, \fBunlzma\fP e \fBlzcat\fP conforme encontrado no LZMA Utils 4.32.x. Na +maioria dos casos, é possível substituir LZMA Utils por XZ Utils sem +interromper os scripts existentes. Existem algumas incompatibilidades, +porém, que às vezes podem causar problemas. +. +.SS "Níveis de predefinição de compactação" +A numeração das predefinições de nível de compactação não é idêntica em +\fBxz\fP e LZMA Utils. A diferença mais importante é como os tamanhos dos +dicionários são mapeados para diferentes predefinições. O tamanho do +dicionário é aproximadamente igual ao uso de memória do descompactador. +.RS +.PP +.TS +tab(;); +c c c +c n n. +Nível;xz;LZMA Utils +\-0;256 KiB;N/D +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +As diferenças de tamanho do dicionário também afetam o uso da memória do +compressor, mas existem algumas outras diferenças entre LZMA Utils e XZ +Utils, que tornam a diferença ainda maior: +.RS +.PP +.TS +tab(;); +c c c +c n n. +Nível;xz;LZMA Utils 4.32.x +\-0;3 MiB;N/D +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +O nível de predefinição padrão no LZMA Utils é \fB\-7\fP enquanto no XZ Utils é +\fB\-6\fP, então ambos usam um dicionário de 8 MiB por padrão. +. +.SS "Arquivos .lzma em um fluxo versus sem ser em um fluxo" +O tamanho descompactado do arquivo pode ser armazenado no cabeçalho de +\&\fB.lzma\fP. O LZMA Utils faz isso ao compactar arquivos comuns. A alternativa +é marcar que o tamanho não compactado é desconhecido e usar o marcador de +fim de carga útil para indicar onde o descompactador deve parar. O LZMA +Utils usa este método quando o tamanho não compactado não é conhecido, como +é o caso, por exemplo, de encadeamentos (pipes). +.PP +\fBxz\fP oferece suporte à descompactação de arquivos \fB.lzma\fP com ou sem +marcador de fim de carga útil, mas todos os arquivos \fB.lzma\fP criados por +\fBxz\fP usarão marcador de fim de carga útil e terão o tamanho descompactado +marcado como desconhecido no cabeçalho de \fB.lzma\fP. Isso pode ser um +problema em algumas situações incomuns. Por exemplo, um descompactador de +\&\fB.lzma\fP em um dispositivo embarcado pode funcionar apenas com arquivos que +tenham tamanho descompactado conhecido. Se você encontrar esse problema, +precisará usar o LZMA Utils ou o LZMA SDK para criar arquivos \fB.lzma\fP com +tamanho descompactado conhecido. +. +.SS "Arquivos .lzma não suportados" +O formato \fB.lzma\fP permite valores \fIlc\fP até 8 e valores \fIlp\fP até 4. LZMA +Utils pode descompactar arquivos com qualquer \fIlc\fP e \fIlp\fP, mas sempre cria +arquivos com \fBlc=3\fP e \fBlp=0\fP. Criar arquivos com outros \fIlc\fP e \fIlp\fP é +possível com \fBxz\fP e com LZMA SDK. +.PP +A implementação do filtro LZMA1 em liblzma requer que a soma de \fIlc\fP e +\fIlp\fP não exceda 4. Assim, arquivos \fB.lzma\fP, que excedam esta limitação, +não podem ser descompactados com \fBxz\fP. +.PP +LZMA Utils cria apenas arquivos \fB.lzma\fP que possuem um tamanho de +dicionário de 2^\fIn\fP (uma potência de 2), mas aceita arquivos com qualquer +tamanho de dicionário. liblzma aceita apenas arquivos \fB.lzma\fP que tenham um +tamanho de dicionário de 2^\fIn\fP ou 2^\fIn\fP + 2^(\fIn\fP\-1). Isso é para diminuir +os falsos positivos ao detectar arquivos \fB.lzma\fP. +.PP +Essas limitações não devem ser um problema na prática, já que praticamente +todos os arquivos \fB.lzma\fP foram compactados com configurações que o liblzma +aceitará. +. +.SS "Lixo à direita" +Ao descompactar, o LZMA Utils silenciosamente ignora tudo após o primeiro +fluxo \fB.lzma\fP. Na maioria das situações, isso é um bug. Isso também +significa que o LZMA Utils não oferece suporte a descompactação de arquivos +\&\fB.lzma\fP concatenados. +.PP +Se houver dados restantes após o primeiro fluxo de \fB.lzma\fP, \fBxz\fP considera +o arquivo corrompido, a menos que \fB\-\-single\-stream\fP tenha sido usado. Isso +pode quebrar scripts obscuros que presumiram que o lixo à direita é +ignorado. +. +.SH NOTAS +. +.SS "A saída compactada pode variar" +A saída compactada exata produzida a partir do mesmo arquivo de entrada não +compactado pode variar entre as versões do XZ Utils, mesmo se as opções de +compactação forem idênticas. Isso ocorre porque o codificador pode ser +aprimorado (compactação mais rápida ou melhor) sem afetar o formato do +arquivo. A saída pode variar mesmo entre diferentes compilações da mesma +versão do XZ Utils, se diferentes opções de compilação forem usadas. +.PP +A informação acima significa que, uma vez que \fB\-\-rsyncable\fP tenha sido +implementado, os arquivos resultantes não serão necessariamente +"rsyncáveis", a menos que os arquivos antigos e novos tenham sido +compactados com a mesma versão xz. Esse problema pode ser corrigido se uma +parte da implementação do codificador for congelada para manter a saída de +rsyncable estável nas versões do xz. +. +.SS "Descompactadores .xz embarcados" +As implementações do descompactador \fB.xz\fP embarcados, como o XZ Embedded, +não oferecem necessariamente suporte a arquivos criados com tipos de +\fIverificações\fP de integridade diferentes de \fBnone\fP e \fBcrc32\fP. Como o +padrão é \fB\-\-check=crc64\fP, você deve usar \fB\-\-check=none\fP ou +\fB\-\-check=crc32\fP ao criar arquivos para sistemas embarcados. +.PP +Fora dos sistemas embarcados, todos os descompactadores de formato \fB.xz\fP +oferecem suporte a todos os tipos de \fIverificação\fP ou, pelo menos, são +capazes de descompactar o arquivo sem verificar a verificação de integridade +se a \fIverificação\fP específica não for suportada. +.PP +XZ Embedded oferece suporte a filtros BCJ, mas apenas com o deslocamento +inicial padrão. +. +.SH EXEMPLOS +. +.SS Básico +Compactar o arquivo \fIfoo\fP em \fIfoo.xz\fP usando o nível de compactação padrão +(\fB\-6\fP) e remover \fIfoo\fP se a compactação for bem\-sucedida: +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +Descompactar \fIbar.xz\fP em \fIbar\fP e não remover \fIbar.xz\fP mesmo se a +descompactação for bem\-sucedida: +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +Criar \fIbaz.tar.xz\fP com a predefinição \fB\-4e\fP (\fB\-4 \-\-extreme\fP), que é mais +lenta que o padrão \fB\-6\fP, mas precisa de menos memória para compactação e +descompactação (48 \ MiB e 5\ MiB, respectivamente): +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +Uma mistura de arquivos compactados e descompactados pode ser descompactada +para a saída padrão com um único comando: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "Compactação paralela de muitos arquivos" +No GNU e *BSD, \fBfind\fP(1) e \fBxargs\fP(1) podem ser usados para paralelizar a +compactação de muitos arquivos: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +A opção \fB\-P\fP para \fBxargs\fP(1) define o número de processos paralelos do +\fBxz\fP. O melhor valor para a opção \fB\-n\fP depende de quantos arquivos devem +ser compactados. Se houver apenas alguns arquivos, o valor provavelmente +deve ser 1; com dezenas de milhares de arquivos, 100 ou até mais podem ser +apropriados para reduzir o número de processos de \fBxz\fP que \fBxargs\fP(1) +eventualmente criará. +.PP +A opção \fB\-T1\fP para \fBxz\fP existe para forçá\-lo ao modo de thread única, +porque \fBxargs\fP(1) é usado para controlar a quantidade de paralelização. +. +.SS "Modo robô" +Calcular quantos bytes foram salvos no total depois de compactar vários +arquivos: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +Um script pode querer saber que está usando \fBxz\fP novo o suficiente. O +seguinte script \fBsh\fP(1) verifica se o número da versão da ferramenta \fBxz\fP +é pelo menos 5.0.0. Este método é compatível com versões beta antigas, que +não suportavam a opção \fB\-\-robot\fP: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Your xz is too old." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +Definir um limite de uso de memória para descompactação usando \fBXZ_OPT\fP, +mas se um limite já tiver sido definido, não o aumentar: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "Cadeias de filtro de compressor personalizadas" +O uso mais simples para cadeias de filtro personalizadas é personalizar uma +predefinição LZMA2. Isso pode ser útil, porque as predefinições abrangem +apenas um subconjunto das combinações potencialmente úteis de configurações +de compactação. +.PP +As colunas CompCPU das tabelas das descrições das opções \fB\-0\fP ... \fB\-9\fP e +\fB\-\-extreme\fP são úteis ao personalizar as predefinições LZMA2. Aqui estão as +partes relevantes coletadas dessas duas tabelas: +.RS +.PP +.TS +tab(;); +c c +n n. +Predefinição;CompCPU +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +Se você sabe que um arquivo requer um dicionário um tanto grande (por +exemplo, 32\ MiB) para compactar bem, mas deseja comprimi\-lo mais +rapidamente do que \fBxz \-8\fP faria, uma predefinição com um valor CompCPU +baixo (por exemplo, 1) pode ser modificado para usar um dicionário maior: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +Com certos arquivos, o comando acima pode ser mais rápido que \fBxz \-6\fP +enquanto compacta significativamente melhor. No entanto, deve\-se enfatizar +que apenas alguns arquivos se beneficiam de um grande dicionário, mantendo o +valor CompCPU baixo. A situação mais óbvia, onde um grande dicionário pode +ajudar muito, é um arquivo contendo arquivos muito semelhantes de pelo menos +alguns megabytes cada. O tamanho do dicionário deve ser significativamente +maior do que qualquer arquivo individual para permitir que o LZMA2 aproveite +ao máximo as semelhanças entre arquivos consecutivos. +.PP +Se o uso muito alto de memória do compactador e do descompactador for bom e +o arquivo que está sendo compactado tiver pelo menos várias centenas de +megabytes, pode ser útil usar um dicionário ainda maior do que os 64 MiB que +o \fBxz \-9\fP usaria: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +Usar \fB\-vv\fP (\fB\-\-verbose \-\-verbose\fP) como no exemplo acima pode ser útil +para ver os requisitos de memória do compactador e do +descompactador. Lembre\-se que usar um dicionário maior que o tamanho do +arquivo descompactado é desperdício de memória, então o comando acima não é +útil para arquivos pequenos. +.PP +Às vezes, o tempo de compactação não importa, mas o uso de memória do +descompactador deve ser mantido baixo, por exemplo, para possibilitar a +descompactação do arquivo em um sistema embarcado. O comando a seguir usa +\fB\-6e\fP (\fB\-6 \-\-extreme\fP) como base e define o dicionário como apenas 64\ KiB. O arquivo resultante pode ser descompactado com XZ Embedded (é por isso +que existe \fB\-\-check=crc32\fP) usando cerca de 100\ KiB de memória. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +Se você deseja espremer o máximo de bytes possível, ajustar o número de bits +de contexto literal (\fIlc\fP) e o número de bits de posição (\fIpb\fP) às vezes +pode ajudar. Ajustar o número de bits de posição literal (\fIlp\fP) também pode +ajudar, mas geralmente \fIlc\fP e \fIpb\fP são mais importantes. Por exemplo, um +arquivo de código\-fonte contém principalmente texto US\-ASCII, então algo +como o seguinte pode fornecer um arquivo ligeiramente (como 0,1\ %) menor +que \fBxz \-6e\fP (tente também sem \fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar\fR +.fi +.RE +.PP +O uso de outro filtro junto com o LZMA2 pode melhorar a compactação com +determinados tipos de arquivo. Por exemplo, para compactar uma biblioteca +compartilhada x86\-32 ou x86\-64 usando o filtro x86 BCJ: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +Observe que a ordem das opções de filtro é significativa. Se \fB\-\-x86\fP for +especificado após \fB\-\-lzma2\fP, \fBxz\fP dará um erro, porque não pode haver +nenhum filtro após LZMA2 e também porque o filtro x86 BCJ não pode ser usado +como o último filtro em a corrente. +.PP +O filtro Delta junto com LZMA2 pode dar bons resultados com imagens +bitmap. Ele geralmente deve superar o PNG, que possui alguns filtros mais +avançados do que o delta simples, mas usa Deflate para a compactação real. +.PP +A imagem deve ser salva em formato não compactado, por exemplo, como TIFF +não compactado. O parâmetro de distância do filtro Delta é definido para +corresponder ao número de bytes por pixel na imagem. Por exemplo, bitmap RGB +de 24 bits precisa de \fBdist=3\fP, e também é bom passar \fBpb=0\fP para LZMA2 +para acomodar o alinhamento de três bytes: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +Se várias imagens foram colocadas em um único arquivo (por exemplo, +\&\fB.tar\fP), o filtro Delta também funcionará, desde que todas as imagens +tenham o mesmo número de bytes por pixel. +. +.SH "VEJA TAMBÉM" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ Utils: +.br +XZ Embedded: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xzdec.1 new file mode 100644 index 000000000..996139d90 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xzdec.1 @@ -0,0 +1,87 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Brazilian Portuguese translations for xz package +.\" Traduções em português brasileiro para o pacote xz. +.\" Rafael Fontenelle , 2022-2023. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 2024\-04\-08 Tukaani "XZ Utils" +.SH NOME +xzdec, lzmadec \- Pequenos descompactadores .xz e .lzma +.SH SINOPSE +\fBxzdec\fP [\fIopção...\fP] [\fIarquivo...\fP] +.br +\fBlzmadec\fP [\fIopção...\fP] [\fIarquivo...\fP] +.SH DESCRIÇÃO +\fBxzdec\fP é uma ferramenta de descompactação baseada em liblzma somente para +arquivos \fB.xz\fP (e somente \fB.xz\fP). \fBxzdec\fP destina\-se a funcionar como um +substituto para \fBxz\fP(1) nas situações mais comuns em que um script foi +escrito para usar \fBxz \-\-decompress \-\-stdout\fP (e possivelmente alguns outras +opções comumente usadas) para descompactar arquivos \fB.xz\fP. \fBlzmadec\fP é +idêntico a \fBxzdec\fP exceto que \fBlzmadec\fP tem suporte a arquivos \fB.lzma\fP em +vez de arquivos \fB.xz\fP. +.PP +Para reduzir o tamanho do executável, \fBxzdec\fP não tem suporte ao uso de +várias threads ou a localização, e não lê opções de variáveis de ambiente +\fBXZ_DEFAULTS\fP e \fBXZ_OPT\fP. \fBxzdec\fP não tem suporte à exibição de +informações de progresso intermediárias: enviar \fBSIGINFO\fP para \fBxzdec\fP não +faz nada, mas enviar \fBSIGUSR1\fP encerra o processo em vez de exibir +informações de progresso. +.SH OPÇÕES +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +Ignorada para compatibilidade \fBxz\fP(1). \fBxzdec\fP tem suporte a apenas +descompactação. +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ignorada para compatibilidade \fBxz\fP(1). \fBxzdec\fP nunca cria ou remove +quaisquer arquivos. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Ignorada para compatibilidade \fBxz\fP(1). \fBxzdec\fP sempre grava os dados +descompactados para a saída padrão. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Especificar isso uma vez não faz nada, pois \fBxzdec\fP nunca exibe nenhum +aviso ou notificação. Especifique isso duas vezes para suprimir erros. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Ignorada para compatibilidade \fBxz\fP(1). \fBxzdec\fP nunca usa o status de saída +2. +.TP +\fB\-h\fP, \fB\-\-help\fP +Exibe uma mensagem de ajuda e sai com sucesso. +.TP +\fB\-V\fP, \fB\-\-version\fP +Mostra o número da versão do \fBxzdec\fP e liblzma. +.SH "STATUS DE SAÃDA" +.TP +\fB0\fP +Correu tudo bem. +.TP +\fB1\fP +Ocorreu um erro. +.PP +\fBxzdec\fP não possui nenhuma mensagem de aviso como o \fBxz\fP(1), portanto, o +status de saída 2 não é usado por \fBxzdec\fP. +.SH NOTAS +Use \fBxz\fP(1) em vez de \fBxzdec\fP ou \fBlzmadec\fP para uso diário +normal. \fBxzdec\fP ou \fBlzmadec\fP destinam\-se apenas a situações em que é +importante ter um descompactador menor do que o \fBxz\fP(1) completo. +.PP +\fBxzdec\fP e \fBlzmadec\fP não são realmente tão pequenos. O tamanho pode ser +reduzido ainda mais eliminando recursos do liblzma no tempo de compilação, +mas isso geralmente não deve ser feito para executáveis distribuídos em +distribuições típicas de sistemas operacionais não embarcados. Se você +precisa de um descompactador \fB.xz\fP realmente pequeno, considere usar o XZ +Embedded. +.SH "VEJA TAMBÉM" +\fBxz\fP(1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xzless.1 new file mode 100644 index 000000000..a39dabb94 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/pt_BR/xzless.1 @@ -0,0 +1,48 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Brazilian Portuguese translations for xz package +.\" Traduções em português brasileiro para o pacote xz. +.\" Rafael Fontenelle , 2022-2023. +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 2025\-03\-06 Tukaani "XZ Utils" +.SH NOME +xzless, lzless \- visualiza arquivos (texto) compactados em xz ou lzma +.SH SINOPSE +\fBxzless\fP [\fIarquivo\fP...] +.br +\fBlzless\fP [\fIfile\fP...] (DEPRECATED) +.SH DESCRIÇÃO +\fBxzless\fP is a filter that displays text from compressed files to a +terminal. Files supported by \fBxz\fP(1) are decompressed; other files are +assumed to be in uncompressed form already. If no \fIfiles\fP are given, +\fBxzless\fP reads from standard input. +.PP +\fBxzless\fP usa \fBless\fP(1) para apresentar sua saída. Ao contrário de +\fBxzmore\fP, sua escolha de pager não pode ser alterada pela configuração de +uma variável de ambiente. Os comandos são baseados em \fBmore\fP(1) e \fBvi\fP(1) +e permitem movimento e busca para frente e para trás. Consulte o manual +\fBless\fP(1) para obter mais informações. +.PP +The command named \fBlzless\fP is provided for backward compatibility with LZMA +Utils. It is deprecated and will be removed in a future version. +.SH AMBIENTE +.TP +\fBLESSMETACHARS\fP +Uma lista de caracteres especiais para o shell. Definido por \fBxzless\fP a +menos que já esteja definido no ambiente. +.TP +\fBLESSOPEN\fP +Defina como uma linha de comando para invocar o descompactador \fBxz\fP(1) para +pré\-processar os arquivos de entrada para \fBless\fP(1). +.SH "VEJA TAMBÉM" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ro/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/ro/lzmainfo.1 new file mode 100644 index 000000000..7a533bd6e --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ro/lzmainfo.1 @@ -0,0 +1,57 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Romanian translation for xz-man. +.\" Mesajele în limba română pentru manualul pachetului XZ Utils. +.\" Remus-Gabriel Chelu , 2022 - 2025. +.\" Cronologia traducerii fiÈ™ierului „xz-manâ€: +.\" Traducerea iniÈ›ială, făcută de R-GC, pentru versiunea xz-man 5.4.0-pre1. +.\" Actualizare a traducerii pentru versiunea 5.4.0-pre2, făcută de R-GC, dec-2022. +.\" Actualizare a traducerii pentru versiunea 5.4.3, făcută de R-GC, mai-2023. +.\" Actualizare a traducerii pentru versiunea 5.4.4-pre1, făcută de R-GC, iul-2023. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre1, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre2, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.7.1-dev1, făcută de R-GC, ian-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.0-pre1, făcută de R-GC, mar-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.2-pre1, făcută de R-GC, oct-2025. +.\" Actualizare a traducerii pentru versiunea Y, făcută de X, Z(luna-anul). +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 30.06.2013 Tukaani "Utilități XZ" +.SH NUME +lzmainfo \- afiÈ™ează informaÈ›iile stocate în antetul fiÈ™ierului .lzma +.SH REZUMAT +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fIfiÈ™ier...\fP] +.SH DESCRIERE +\fBlzmainfo\fP afiÈ™ează informaÈ›iile stocate în antetul fiÈ™ierului +\&\fB.lzma\fP. CiteÈ™te primii 13 octeÈ›i din \fIfiÈ™ierul\fP specificat, decodifică +antetul È™i îl afiÈ™ează la ieÈ™irea standard în format care poate fi citit de +om. Dacă nu sunt date \fIfiÈ™iere\fP sau dacă \fIfiÈ™ier\fP este \fB\-\fP, se citeÈ™te +intrarea standard. +.PP +De obicei, cele mai interesante informaÈ›ii sunt dimensiunea necomprimată È™i +dimensiunea dicÈ›ionarului. Dimensiunea necomprimată poate fi afiÈ™ată numai +dacă fiÈ™ierul este în varianta formatului \fB.lzma\fP netransmis în +flux. Cantitatea de memorie necesară pentru a decomprima fiÈ™ierul este de +câteva zeci de kiloocteÈ›i plus dimensiunea dicÈ›ionarului. +.PP +\fBlzmainfo\fP este inclus în XZ Utils în primul rând pentru compatibilitatea +cu LZMA Utils. +.SH "STARE DE IEȘIRE" +.TP +\fB0\fP +Totul este bine. +.TP +\fB1\fP +A apărut o eroare. +.SH ERORI +\fBlzmainfo\fP foloseÈ™te sufixul \fBMB\fP în timp ce sufixul corect ar fi \fBMiB\fP +(2^20 octeÈ›i). Acest lucru este pentru a menÈ›ine ieÈ™irea compatibilă cu LZMA +Utils. +.SH "CONSULTAÈšI ȘI" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ro/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/ro/xz.1 new file mode 100644 index 000000000..155544559 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ro/xz.1 @@ -0,0 +1,2111 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Romanian translation for xz-man. +.\" Mesajele în limba română pentru manualul pachetului XZ Utils. +.\" Remus-Gabriel Chelu , 2022 - 2025. +.\" Cronologia traducerii fiÈ™ierului „xz-manâ€: +.\" Traducerea iniÈ›ială, făcută de R-GC, pentru versiunea xz-man 5.4.0-pre1. +.\" Actualizare a traducerii pentru versiunea 5.4.0-pre2, făcută de R-GC, dec-2022. +.\" Actualizare a traducerii pentru versiunea 5.4.3, făcută de R-GC, mai-2023. +.\" Actualizare a traducerii pentru versiunea 5.4.4-pre1, făcută de R-GC, iul-2023. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre1, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre2, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.7.1-dev1, făcută de R-GC, ian-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.0-pre1, făcută de R-GC, mar-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.2-pre1, făcută de R-GC, oct-2025. +.\" Actualizare a traducerii pentru versiunea Y, făcută de X, Z(luna-anul). +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 "8 martie 2025" Tukaani "Utilități XZ" +. +.SH NUME +xz, unxz, xzcat, lzma, unlzma, lzcat \- Comprimă sau decomprimă fiÈ™iere .xz +È™i .lzma +. +.SH REZUMAT +\fBxz\fP [\fIopÈ›iune...\fP] [\fIfiÈ™ier...\fP] +. +.SH "ALIAS COMENZI" +\fBunxz\fP este echivalent cu \fBxz \-\-decompress\fP. +.br +\fBxzcat\fP este echivalent cu \fBxz \-\-decompress \-\-stdout\fP. +.br +\fBlzma\fP este echivalent cu \fBxz \-\-format=lzma\fP. +.br +\fBunlzma\fP este echivalent cu \fBxz \-\-format=lzma \-\-decompress\fP. +.br +\fBlzcat\fP este echivalent cu \fBxz \-\-format=lzma \-\-decompress \-\-stdout\fP. +.PP +Când scrieÈ›i scripturi care trebuie să decomprime fiÈ™iere, este recomandat +să folosiÈ›i întotdeauna comanda \fBxz\fP cu argumentele adecvate (\fBxz \-d\fP sau +\fBxz \-dc\fP) în loc de comenzile \fBunxz\fP È™i \fBxzcat\fP. +. +.SH DESCRIERE +\fBxz\fP este un instrument de comprimare a datelor de uz general cu sintaxă de +linie de comandă similară cu \fBgzip\fP(1) È™i \fBbzip2\fP(1). Formatul de fiÈ™ier +nativ este formatul \fB.xz\fP, dar formatul vechi \fB.lzma\fP folosit de LZMA +Utils È™i fluxurile comprimate brute fără anteturi de format container sunt +de asemenea acceptate. ÃŽn plus, este acceptată decomprimarea formatului +\&\fB.lz\fP folosit de \fBlzip\fP. +.PP +\fBxz\fP comprimă sau decomprimă fiecare \fIfiÈ™ier\fP în funcÈ›ie de modul de +operare selectat. Dacă nu sunt date \fIfiÈ™iere\fP sau \fIfiÈ™ier\fP este \fB\-\fP, +\fBxz\fP citeÈ™te de la intrarea standard È™i scrie datele procesate la ieÈ™irea +standard. \fBxz\fP va refuza (afiÈ™ează o eroare È™i omite \fIfiÈ™ier\fP) să scrie +date comprimate la ieÈ™irea standard dacă este un terminal. ÃŽn mod similar, +\fBxz\fP va refuza să citească datele comprimate de la intrarea standard dacă +este un terminal. +.PP +Cu excepÈ›ia cazului în care este specificată opÈ›iunea \fB\-\-stdout\fP, +\fIfiÈ™ierele\fP altele decât \fB\-\fP sunt scrise într\-un fiÈ™ier nou al cărui nume +este derivat din numele \fIfiÈ™ierului\fP sursă: +.IP \(bu 3 +La comprimare, sufixul formatului de fiÈ™ier È›intă (\fB.xz\fP sau \fB.lzma\fP) este +ataÈ™at la numele fiÈ™ierului sursă pentru a se obÈ›ine numele fiÈ™ierului +È›intă. +.IP \(bu 3 +La decomprimare, sufixul \fB.xz\fP, \fB.lzma\fP sau \fB.lz\fP este eliminat din +numele fiÈ™ierului pentru a se obÈ›ine numele fiÈ™ierului È›intă. \fBxz\fP +recunoaÈ™te È™i sufixele \fB.txz\fP È™i \fB.tlz\fP È™i le înlocuieÈ™te cu sufixul +\&\fB.tar\fP. +.PP +Dacă fiÈ™ierul È›intă există deja, este afiÈ™ată o eroare È™i \fIfiÈ™ier\fP este +omis. +.PP +Cu excepÈ›ia cazului în care scrie la ieÈ™irea standard, \fBxz\fP va afiÈ™a un +avertisment È™i va omite \fIfiÈ™ier\fPul dacă se aplică oricare dintre +următoarele: +.IP \(bu 3 +\fIFiÈ™ierul\fP nu este un fiÈ™ier obiÈ™nuit. Legăturile simbolice nu sunt urmate +È™i, prin urmare, nu sunt considerate fiÈ™iere obiÈ™nuite. +.IP \(bu 3 +\fIFiÈ™ierul\fP are mai mult de o legătură dură. +.IP \(bu 3 +\fIFiÈ™ierul\fP are activat bitul «setuid», «setgid» sau cel lipicios(sticky). +.IP \(bu 3 +Modul de operare este stabilit la comprimare È™i \fIfiÈ™ier\fP are deja un sufix +al formatului de fiÈ™ier È›intă (\fB.xz\fP sau \fB.txz\fP când se comprimă în +formatul \fB.xz\fP È™i \fB.lzma\fP sau \fB.tlz\fP când se comprimă în formatul +\&\fB.lzma\fP). +.IP \(bu 3 +Modul de operare este stabilit la decomprimare È™i \fIfiÈ™ierul\fP nu are un +sufix al niciunui format de fiÈ™ier acceptat (\fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, +\&\fB.tlz\fP, sau \fB.lz\fP). +.PP +După comprimarea sau decomprimarea cu succes a \fIfiÈ™ierului\fP, \fBxz\fP copiază +proprietarul, grupul, permisiunile, timpul de acces È™i timpul de modificare +din \fIfiÈ™ierul\fP sursă în fiÈ™ierul È›intă. Dacă copierea grupului eÈ™uează, +permisiunile sunt modificate astfel încât fiÈ™ierul È›intă să nu devină +accesibil utilizatorilor care nu aveau permisiunea de a accesa \fIfiÈ™ierul\fP +sursă. \fBxz\fP nu acceptă încă copierea altor metadate, cum ar fi listele de +control al accesului sau atributele extinse. +.PP +Odată ce fiÈ™ierul È›intă a fost închis cu succes, \fIfiÈ™ierul\fP sursă este +eliminat dacă nu a fost specificată opÈ›iunea \fB\-\-keep\fP. \fIFiÈ™ierul\fP sursă nu +este niciodată eliminat dacă rezultatul este scris la ieÈ™irea standard sau +dacă apare o eroare. +.PP +Trimiterea unui semnal \fBSIGINFO\fP sau \fBSIGUSR1\fP către procesul \fBxz\fP face +ca acesta să imprime informaÈ›ii despre progres la ieÈ™irea de eroare +standard. Acest lucru are o utilizare limitată, deoarece atunci când ieÈ™irea +de eroare standard este un terminal, folosind opÈ›iunea \fB\-\-verbose\fP va afiÈ™a +un indicator de progres de actualizare automată. +. +.SS "Utilizarea memoriei" +Cantitatea de memorie utilizată de \fBxz\fP variază de la câteva sute de +kiloocteÈ›i la câțiva gigaocteÈ›i, în funcÈ›ie de opÈ›iunile de +comprimare. OpÈ›iunile utilizate la comprimarea unui fiÈ™ier determină +cerinÈ›ele de memorie ale instrumentului de decomprimare. De obicei, +instrumentul de decomprimare are nevoie de 5% până la 20% din cantitatea de +memorie de care a avut nevoie instrumentul de comprimare la crearea +fiÈ™ierului. De exemplu, decomprimarea unui fiÈ™ier creat cu \fBxz \-9\fP necesită +în prezent 65Mio de memorie. TotuÈ™i, este posibil să aveÈ›i fiÈ™iere \fB.xz\fP +care necesită câțiva gigaocteÈ›i de memorie pentru decomprimare. +.PP +ÃŽn special utilizatorii de sisteme mai vechi pot considera deranjantă +posibilitatea unei utilizări foarte mari a memoriei. Pentru a preveni +surprizele neplăcute, \fBxz\fP are încorporat un limitator de utilizare a +memoriei, care este dezactivat implicit. ÃŽn timp ce unele sisteme de operare +oferă modalități de a limita utilizarea memoriei proceselor, bazarea pe +aceasta nu a fost considerată a fi suficient de flexibilă (de exemplu, +utilizarea \fBulimit\fP(1) pentru a limita memoria virtuală tinde să paralizeze +\fBmmap\fP(2)). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +Limitatorul de utilizare a memoriei poate fi activat cu opÈ›iunea din linia +de comandă \fB\-\-memlimit=\fP\fIlimita\fP. Adesea este mai convenabil să activaÈ›i +limitatorul în mod implicit prin definirea variabilei de mediu +\fBXZ_DEFAULTS\fP, de exemplu, \fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP. Este posibil +să stabiliÈ›i limitele separat pentru comprimare È™i decomprimare folosind +\fB\-\-memlimit\-compress=\fP\fIlimita\fP È™i +\fB\-\-memlimit\-decompress=\fP\fIlimita\fP. Utilizarea acestor două opÈ›iuni în afara +\fBXZ_DEFAULTS\fP este foarte rar utilă, deoarece o singură rulare a \fBxz\fP nu +poate face atât comprimarea, cât È™i decomprimarea È™i \fB\-\-memlimit=\fP\fIlimita\fP +(sau \fB\-M\fP \fIlimita\fP ) este mai scurt de tastat pe linia de comandă. +.PP +Dacă limita de utilizare a memoriei specificată este depășită la +decomprimare, \fBxz\fP va afiÈ™a o eroare È™i decomprimarea fiÈ™ierului va +eÈ™ua. Dacă limita este depășită la comprimare, \fBxz\fP va încerca să reducă +valorile stabilite astfel încât limita să nu mai fie depășită (cu excepÈ›ia +cazului în care se utilizează opÈ›iunea \fB\-\-format=raw\fP sau +\fB\-\-no\-adjust\fP). ÃŽn acest fel, operaÈ›iunea nu va eÈ™ua decât dacă limita +stabilită este foarte mică. Scalarea valorilor stabilite se face în paÈ™i +care nu se potrivesc cu valorile prestabilite ale nivelului de comprimare, +de exemplu, dacă limita este doar puÈ›in mai mică decât cantitatea necesară +pentru \fBxz \-9\fP, valorile stabilite vor fi reduse doar puÈ›in , nu până la +valoarea prestabilită a lui \fBxz \-8\fP. +. +.SS "Concatenare È™i completare (prin umplere cu octeÈ›i nuli) cu fiÈ™iere .xz" +Este posibil să concatenaÈ›i fiÈ™ierele \fB.xz\fP aÈ™a cum sunt. \fBxz\fP va +decomprima astfel de fiÈ™iere ca È™i cum ar fi un singur fiÈ™ier \fB.xz\fP. +.PP +Este posibil să se introducă umplutură între părÈ›ile concatenate sau după +ultima parte. Umplutura trebuie să fie compusă din octeÈ›i nuli, iar +dimensiunea umpluturii trebuie să fie un multiplu de patru octeÈ›i. Acest +lucru poate fi util, de exemplu, dacă fiÈ™ierul \fB.xz\fP este stocat pe un +mediu care măsoară dimensiunile fiÈ™ierelor în blocuri de 512 de octeÈ›i. +.PP +Concatenarea È™i completarea nu sunt permise cu fiÈ™ierele \fB.lzma\fP sau +fluxurile brute. +. +.SH OPÈšIUNI +. +.SS "Sufixe de numere întregi È™i valori speciale" +ÃŽn majoritatea locurilor în care este de aÈ™teptat un număr întreg ca +argument, un sufix opÈ›ional este acceptat pentru a indica cu uÈ™urință +numerele întregi mari. Nu trebuie să existe spaÈ›iu între numărul întreg È™i +sufix. +.TP +\fBKiB\fP +ÃŽnmulÈ›eÈ™te numărul întreg cu 1.024 (2^10). \fBKi\fP, \fBk\fP, \fBkB\fP, \fBK\fP È™i +\fBKB\fP sunt acceptate ca sinonime pentru \fBKiB\fP. +.TP +\fBMiB\fP +ÃŽnmulÈ›eÈ™te numărul întreg cu 1,048,576 (2^20). \fBMi\fP, \fBm\fP, \fBM\fP, È™i \fBMB\fP +sunt acceptate ca sinonime pentru \fBMiB\fP. +.TP +\fBGiB\fP +ÃŽnmulÈ›eÈ™te numărul întreg cu 1,073,741,824 (2^30). \fBGi\fP, \fBg\fP, \fBG\fP, È™i +\fBGB\fP sunt acceptate ca sinonime pentru \fBGiB\fP. +.PP +Valoarea specială \fBmax\fP poate fi utilizată pentru a indica valoarea maximă +întreagă suportată de opÈ›iune. +. +.SS "Mod de operare" +Dacă sunt date mai multe opÈ›iuni de mod de funcÈ›ionare, ultima dintre ele, +este cea care va avea efect. +.TP +\fB\-z\fP, \fB\-\-compress\fP +Comprimare. Acesta este modul de operare implicit atunci când nu este +specificată nicio opÈ›iune de mod de funcÈ›ionare È™i nici un alt mod de +operare nu este implicat din numele comenzii (de exemplu, \fBunxz\fP implică +\fB\-\-decompress\fP). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +După o comprimare reuÈ™ită, fiÈ™ierul sursă este eliminat, cu excepÈ›ia cazului +în care a fost specificată scrierea la ieÈ™irea standard sau opÈ›iunea +\fB\-\-keep\fP. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Decomprimare. După o decomprimare reuÈ™ită, fiÈ™ierul sursă este eliminat, cu +excepÈ›ia cazului în care a fost specificată scrierea la ieÈ™irea standard sau +opÈ›iunea \fB\-\-keep\fP. +.TP +\fB\-t\fP, \fB\-\-test\fP +Testează integritatea \fIfiÈ™ierelor\fP comprimate. Această opÈ›iune este +echivalentă cu \fB\-\-decompress \-\-stdout\fP cu excepÈ›ia faptului că datele +decomprimate sunt înlăturate în loc să fie scrise la ieÈ™irea standard. Nu +sunt create sau eliminate fiÈ™iere. +.TP +\fB\-l\fP, \fB\-\-list\fP +AfiÈ™ează informaÈ›ii despre \fIfiÈ™iere\fP comprimate. Nu are loc nicio +decomprimare la ieÈ™ire È™i nu sunt create sau eliminate fiÈ™iere. ÃŽn modul +listă, programul nu poate citi datele comprimate din intrarea standard sau +din alte surse care nu pot fi explorate. +.IP "" +Listarea implicită arată informaÈ›ii de bază despre \fIfiÈ™iere\fP, câte un +fiÈ™ier pe linie. Pentru a obÈ›ine informaÈ›ii mai detaliate, utilizaÈ›i È™i +opÈ›iunea \fB\-\-verbose\fP. Pentru È™i mai multe informaÈ›ii, utilizaÈ›i opÈ›iunea +\fB\-\-verbose\fP de două ori, dar reÈ›ineÈ›i că acest lucru poate fi lent, +deoarece obÈ›inerea tuturor informaÈ›iilor suplimentare necesită multe +căutări. Lățimea ieÈ™irii detaliate depășeÈ™te 80 de caractere, deci +canalizarea ieÈ™irii către, de exemplu, \fBless\ \-S\fP poate fi convenabilă dacă +terminalul nu este suficient de lat. +.IP "" +IeÈ™irea exactă poate varia între versiunile \fBxz\fP È™i diferitele +localizări(configurările regionale). Pentru ieÈ™iri care pot fi citite de +maÈ™ină, ar trebui utilizată opÈ›iunea \fB\-\-robot \-\-list\fP. +. +.SS "Modificatori de operare" +.TP +\fB\-k\fP, \fB\-\-keep\fP +Nu È™terge fiÈ™ierele de intrare. +.IP "" +ÃŽncepând cu \fBxz\fP 5.2.6, această opÈ›iune face ca \fBxz\fP să comprime sau să +decomprime, chiar dacă intrarea este o legătură simbolică către un fiÈ™ier +obiÈ™nuit, are mai mult de\-o legătură dură sau are marcaÈ›i biÈ›ii setuid, +setgid sau bitul lipicios. BiÈ›ii setuid, setgid È™i bitul lipicios nu sunt +copiaÈ›i în fiÈ™ierul È›intă. ÃŽn versiunile anterioare acest lucru se făcea +numai cu ajutorul opÈ›iunii \fB\-\-force\fP. +.TP +\fB\-f\fP, \fB\-\-force\fP +Această opÈ›iune are mai multe efecte: +.RS +.IP \(bu 3 +Dacă fiÈ™ierul È›intă există deja, îl È™terge înainte de comprimare sau +decomprimare. +.IP \(bu 3 +Comprimă sau decomprimă chiar dacă intrarea este o legătură simbolică către +un fiÈ™ier obiÈ™nuit, are mai mult de\-o legătură dură sau are marcaÈ›i biÈ›ii +setuid, setgid sau bitul lipicios. BiÈ›ii setuid, setgid È™i bitul lipicios nu +sunt copiaÈ›i în fiÈ™ierul È›intă. +.IP \(bu 3 +Când este utilizată cu opÈ›iunile \fB\-\-decompress\fP È™i \fB\-\-stdout\fP, comanda +\fBxz\fP nu poate recunoaÈ™te tipul fiÈ™ierului sursă, È™i copiază fiÈ™ierul sursă +aÈ™a cum este la ieÈ™irea standard. Acest lucru permite comenzii \fBxzcat\fP +\fB\-\-force\fP să fie folosită drept comanda \fBcat\fP(1) pentru fiÈ™ierele care nu +au fost comprimate cu \fBxz\fP. ReÈ›ineÈ›i că, în viitor, \fBxz\fP ar putea să +accepte noi formate de fiÈ™iere comprimate, ceea ce poate face ca \fBxz\fP să +decomprime mai multe tipuri de fiÈ™iere în loc să le copieze aÈ™a cum sunt la +ieÈ™irea standard. OpÈ›iunea \fB\-\-format=\fP\fIformat\fP poate fi folosită pentru a +restricÈ›iona \fBxz\fP să decomprime doar un singur format de fiÈ™ier. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Scrie datele comprimate sau decomprimate la ieÈ™irea standard în loc de +într\-un fiÈ™ier. Aceasta implică \fB\-\-keep\fP. +.TP +\fB\-\-single\-stream\fP +Decomprimă numai primul flux \fB.xz\fP È™i ignoră în tăcere posibilele date de +intrare rămase în urma fluxului. ÃŽn mod normal, astfel de resturi rămase +face ca \fBxz\fP să afiÈ™eze o eroare. +.IP "" +\fBxz\fP nu decomprimă niciodată mai mult de un flux din fiÈ™ierele \fB.lzma\fP sau +din fluxurile brute, dar această opÈ›iune face ca \fBxz\fP să ignore posibilele +resturi de date rămase după fiÈ™ierul \fB.lzma\fP sau fluxul brut. +.IP "" +Această opÈ›iune nu are efect dacă modul de funcÈ›ionare nu este +\fB\-\-decompress\fP sau \fB\-\-test\fP. +.IP "" +ÃŽncepând cu \fBxz\fP 5.7.1alpha, \fB\-\-single\-stream\fP implică \fB\-\-keep\fP. +.TP +\fB\-\-no\-sparse\fP +Dezactivează crearea de fiÈ™iere dispersate. ÃŽn mod implicit, dacă decomprimă +într\-un fiÈ™ier obiÈ™nuit, \fBxz\fP încearcă să facă fiÈ™ierul dispersat dacă +datele decomprimate conÈ›in secvenÈ›e lungi de zerouri binare. De asemenea, +funcÈ›ionează atunci când scrie la ieÈ™irea standard, atâta timp cât ieÈ™irea +standard este conectată la un fiÈ™ier obiÈ™nuit È™i sunt îndeplinite anumite +condiÈ›ii suplimentare pentru a o face în siguranță. Crearea de fiÈ™iere +dispersate poate economisi spaÈ›iu pe disc È™i poate accelera decomprimarea +prin reducerea cantității de date de In/IeÈ™ pe disc. +.TP +\fB\-S\fP \fI.suf\fP, \fB\-\-suffix=\fP\fI.suf\fP +Când comprimă, utilizează \fI.suf\fP ca sufix pentru fiÈ™ierul È›intă în loc de +\&\fB.xz\fP sau \fB.lzma\fP. Dacă nu scrie la ieÈ™irea standard È™i fiÈ™ierul sursă are +deja sufixul \fI.suf\fP, este afiÈ™at un avertisment È™i fiÈ™ierul este omis. +.IP "" +Când decomprimă, recunoaÈ™te fiÈ™ierele cu sufixul \fI.suf\fP în plus față de +fiÈ™ierele cu sufixul \fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP sau \fB.lz\fP. Dacă +fiÈ™ierul sursă are sufixul \fI.suf\fP, sufixul este eliminat pentru a obÈ›ine +numele fiÈ™ierului È›intă. +.IP "" +La comprimarea sau decomprimarea fluxurilor brute (\fB\-\-format=raw\fP), sufixul +trebuie să fie întotdeauna specificat, cu excepÈ›ia cazului în care se scrie +la ieÈ™irea standard, deoarece nu există un sufix implicit pentru fluxurile +brute. +.TP +\fB\-\-files\fP[\fB=\fP\fIfiÈ™ier\fP] +CiteÈ™te numele fiÈ™ierelor de procesat din \fIfiÈ™ier\fP; dacă \fIfiÈ™ierul\fP este +omis, numele fiÈ™ierelor sunt citite de la intrarea standard. Numele de +fiÈ™iere trebuie să fie terminate cu caracterul de linie nouă. O liniuță +(\fB\-\fP) este luată ca nume de fiÈ™ier obiÈ™nuit; nu înseamnă intrarea +standard. Dacă numele de fiÈ™iere sunt date È™i ca argumente în linia de +comandă, ele sunt procesate înainte ca numele fiÈ™ierelor să fie citite din +\fIfiÈ™ier\fP. +.TP +\fB\-\-files0\fP[\fB=\fP\fIfiÈ™ier\fP] +Această opÈ›iune este identică cu \fB\-\-files\fP[\fB=\fP\fIfiÈ™ier\fP], cu excepÈ›ia +faptului că fiecare nume de fiÈ™ier trebuie să fie terminat cu caracterul +nul. +. +.SS "Formatul de bază al fiÈ™ierului È™i opÈ›iunile de comprimare" +.TP +\fB\-F\fP \fIformat\fP, \fB\-\-format=\fP\fIformat\fP +Specifică \fIformatul\fP fiÈ™ierului pentru comprimare sau decomprimare: +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +Aceasta este valoarea implicită. La comprimare, \fBauto\fP este echivalent cu +\fBxz\fP. La decomprimare, formatul fiÈ™ierului de intrare este detectat +automat. ReÈ›ineÈ›i că fluxurile brute (create cu \fB\-\-format=raw\fP) nu pot fi +detectate automat. +.TP +\fBxz\fP +Comprimă în formatul de fiÈ™ier \fB.xz\fP sau acceptă numai fiÈ™ierele \fB.xz\fP +când decomprimă. +.TP +\fBlzma\fP, \fBalone\fP +Comprimă în formatul de fiÈ™ier \fB.lzma\fP vechi sau acceptă numai fiÈ™ierele +\&\fB.lzma\fP când decomprimă. Numele alternativ \fBalone\fP este furnizat pentru +compatibilitatea cu versiunile mai vechi de LZMA Utils. +.TP +\fBlzip\fP +Acceptă numai fiÈ™ierele \fB.lz\fP când decomprimă. Comprimarea nu este +acceptată. +.IP "" +Sunt acceptate versiunile 0 È™i 1 ale formatului \fB.lz\fP. FiÈ™ierele versiunii +0 au fost create cu \fBlzip\fP 1.3 È™i versiuni mai vechi. Astfel de fiÈ™iere nu +sunt comune, dar pot fi găsite în arhivele de fiÈ™iere, deoarece câteva +pachete sursă au fost lansate în acest format. Este posibil ca oamenii să +aibă È™i fiÈ™iere personale vechi în acest format. Suportul pentru +decomprimare pentru versiunea 0 a formatului a fost eliminat în \fBlzip\fP +1.18. \fBlzip\fP 1.4 È™i versiunile ulterioare creează fiÈ™iere în versiunea 1 a +formatului. +.TP +\fBraw\fP +Comprimă sau decomprimă un flux brut (fără anteturi). Acest lucru este +destinat doar utilizatorilor avansaÈ›i. Pentru a decodifica fluxurile brute, +trebuie să utilizaÈ›i opÈ›iunea \fB\-\-format=raw\fP È™i să specificaÈ›i în mod +explicit lanÈ›ul de filtre, care în mod normal ar fi fost stocat în +anteturile containerului. +.RE +.TP +\fB\-C\fP \fIverificarea\fP, \fB\-\-check=\fP\fIverificarea\fP +Specifică tipul verificării integrității. Verificarea este calculată din +datele necomprimate È™i stocată în fiÈ™ierul \fB.xz\fP. Această opÈ›iune are efect +numai la comprimarea în format \fB.xz\fP; formatul \fB.lzma\fP nu acceptă +verificări de integritate. Verificarea integrității (dacă există) este +efectuată atunci când fiÈ™ierul \fB.xz\fP este decomprimat. +.IP "" +Tipuri de \fIverificare\fP acceptate: +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +Nu calculează deloc o verificare a integrității. Aceasta este de obicei o +idee proastă. Acest lucru poate fi util atunci când integritatea datelor +este oricum verificată prin alte mijloace. +.TP +\fBcrc32\fP +Calculează CRC32 folosind polinomul din IEEE\-802.3 (Ethernet). +.TP +\fBcrc64\fP +Calculează CRC64 folosind polinomul din ECMA\-182. Aceasta este valoarea +implicită, deoarece este ceva mai bună decât CRC32 la detectarea fiÈ™ierelor +deteriorate, iar diferenÈ›a de viteză este neglijabilă. +.TP +\fBsha256\fP +Calculează SHA\-256. Acest lucru este oarecum mai lent decât CRC32 È™i CRC64. +.RE +.IP "" +Integritatea antetelor \fB.xz\fP este întotdeauna verificată cu CRC32. Nu este +posibilă modificarea sau dezactivarea acesteia. +.TP +\fB\-\-ignore\-check\fP +Nu efectuează verificarea integrității datelor comprimate la +decomprimare. Valorile CRC32 din antetele \fB.xz\fP vor fi însă verificate +normal. +.IP "" +\fBNu utilizaÈ›i această opÈ›iune decât dacă È™tiÈ›i ce faceÈ›i\fP. Motive posibile +pentru a utiliza această opÈ›iune: +.RS +.IP \(bu 3 +ÃŽncercarea de a recupera datele dintr\-un fiÈ™ier .xz corupt. +.IP \(bu 3 +Accelerarea decomprimării. Acest lucru contează mai ales cu SHA\-256 sau cu +fiÈ™ierele care s\-au comprimat extrem de bine. Este recomandat să nu +utilizaÈ›i această opÈ›iune în acest scop decât dacă integritatea fiÈ™ierului +este verificată extern într\-un alt mod. +.RE +.TP +\fB\-0\fP ... \fB\-9\fP +Selectează un nivel prestabilit de comprimare. Valoarea implicită este +\fB\-6\fP. Dacă sunt specificate mai multe niveluri prestabilite, ultimul are +efect. Dacă a fost deja specificat un lanÈ› de filtre personalizat, +specificarea unui nivel prestabilit de comprimare È™terge lanÈ›ul de filtre +personalizat. +.IP "" +DiferenÈ›ele dintre valorile prestabilite sunt mai semnificative decât cu +\fBgzip\fP(1) È™i \fBbzip2\fP(1). Valorile de comprimare selectate determină +cerinÈ›ele de memorie ale instrumentului de decomprimare, astfel încât +utilizarea unui nivel prea mare prestabilit ar putea face „dureroasă†+decomprimarea fiÈ™ierului pe un sistem vechi cu puÈ›ină memorie RAM. Mai +exact, \fBnu este o idee bună să folosiÈ›i orbeÈ™te \-9 pentru tot\fP aÈ™a cum se +întâmplă adesea cu \fBgzip\fP(1) È™i \fBbzip2\fP(1). +.RS +.TP +\fB\-0\fP ... \fB\-3\fP +Acestea sunt valorile prestabilite oarecum rapide. \fB\-0\fP este uneori mai +rapid decât \fBgzip \-9\fP în timp ce comprimă mult mai bine. Cele mai ridicate +au adesea viteza comparabilă cu \fBbzip2\fP(1) cu un raport de comprimare +comparabil sau mai bun, deÈ™i rezultatele depind foarte mult de tipul de date +care sunt comprimate. +.TP +\fB\-4\fP ... \fB\-6\fP +Comprimare bună spre foarte bună, păstrând în acelaÈ™i timp utilizarea +memoriei de către instrumentul de decomprimare la un nivel rezonabil chiar +È™i pentru sistemele vechi. \fB\-6\fP este valoarea implicită, care este de +obicei o alegere bună pentru distribuirea fiÈ™ierelor care trebuie să poată +fi decomprimate chiar È™i pe sisteme cu doar 16Mio de memorie RAM. OpÈ›iunile +(\fB\-5e\fP sau \fB\-6e\fP ar putea fi demne de luat în considerare. A se vedea +opÈ›iunea \fB\-\-extreme\fP.) +.TP +\fB\-7 ... \-9\fP +Acestea sunt precum \fB\-6\fP, dar cu cerinÈ›e mai mari de memorie pentru +comprimare È™i decomprimare. Acestea sunt utile numai atunci când comprimaÈ›i +fiÈ™iere mai mari de 8Mio, 16Mio È™i, respectiv, 32Mio. +.RE +.IP "" +Pe acelaÈ™i hardware, viteza de decomprimare este aproximativ un număr +constant de octeÈ›i de date comprimate pe secundă. Cu alte cuvinte, cu cât +comprimarea este mai bună, cu atât decomprimarea va fi de obicei mai +rapidă. Aceasta înseamnă, de asemenea, că valoarea de la ieÈ™ire a cantității +de date necomprimate produsă pe secundă poate varia foarte mult. +.IP "" +Următorul tabel rezumă caracteristicile valorilor prestabilite: +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +ValPrestab;DimDict;CPUComp;MemComp;MemDec +\-0;256 KiB;0;3 MiB;1 MiB +\-1;1 MiB;1;9 MiB;2 MiB +\-2;2 MiB;2;17 MiB;3 MiB +\-3;4 MiB;3;32 MiB;5 MiB +\-4;4 MiB;4;48 MiB;5 MiB +\-5;8 MiB;5;94 MiB;9 MiB +\-6;8 MiB;6;94 MiB;9 MiB +\-7;16 MiB;6;186 MiB;17 MiB +\-8;32 MiB;6;370 MiB;33 MiB +\-9;64 MiB;6;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Descrieri coloane: +.RS +.IP \(bu 3 +DimDict este dimensiunea dicÈ›ionarului LZMA2. Este o risipă de memorie să +foloseÈ™ti un dicÈ›ionar mai mare decât dimensiunea fiÈ™ierului necomprimat. De +aceea este bine să evitaÈ›i utilizarea valorilor prestabilite \fB\-7\fP ... \fB\-9\fP +atunci când nu este nevoie cu adevărat de ele. Pentru valoarea prestabilită +\fB\-6\fP sau alta mai mică, cantitatea de memorie irosită este de obicei +suficient de mică pentru a nu conta. +.IP \(bu 3 +CPUComp este o reprezentare simplificată a configurărilor LZMA2 care +afectează viteza de comprimare. Dimensiunea dicÈ›ionarului afectează È™i +viteza, aÈ™a că, în timp ce CPUComp este aceeaÈ™i pentru nivelurile \fB\-6\fP +\&... \fB\-9\fP, nivelurile mai mari tind să fie puÈ›in mai lente. Pentru a obÈ›ine +o comprimare È™i mai lentă È™i, astfel, posibil mai bună, consultaÈ›i opÈ›iunea +\fB\-\-extreme\fP. +.IP \(bu 3 +MemComp conÈ›ine cerinÈ›ele de memorie ale comprimării în modul cu un singur +fir de execuÈ›ie. Poate varia uÈ™or între versiunile \fBxz\fP. +.IP \(bu 3 +MemDec conÈ›ine cerinÈ›ele de memorie pentru decomprimare. Adică, +configurările de comprimare determină cerinÈ›ele de memorie ale +decomprimării. Cantitatea exactă a memoriei utilizate la decomprimare este +puÈ›in mai mare decât dimensiunea dicÈ›ionarului LZMA2, dar valorile din tabel +au fost rotunjite la următorul Mio. +.RE +.IP "" +CerinÈ›ele de memorie ale modului cu mai multe fire de execuÈ›ie sunt +semnificativ mai mari decât cele ale modului cu un singur fir de +execuÈ›ie. Cu valoarea implicită a lui \fB\-\-block\-size\fP, fiecare fir are +nevoie de 3*3*DictSize plus MemComp sau MemDec. De exemplu, patru fire de +execuÈ›ie cu valoarea prestabilită \fB\-6\fP au nevoie de 660\(en670\ Mio de +memorie. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +Utilizează o variantă mai lentă a nivelului prestabilit de comprimare +selectat (\fB\-0\fP ... \fB\-9\fP) pentru a obÈ›ine un raport de comprimare puÈ›in mai +bun, dar din nefericire, acest lucru îl poate înrăutăți. Utilizarea memoriei +pentru decomprimare nu este afectată, dar utilizarea memoriei la comprimare +creÈ™te puÈ›in la nivelurile prestabilite \fB\-0\fP ... \fB\-3\fP. +.IP "" +Deoarece există două valori prestabilite cu dimensiuni ale dicÈ›ionarului de +4Mio È™i 8Mio, valorile prestabilite \fB\-3e\fP È™i \fB\-5e\fP folosesc configurări +puÈ›in mai rapide (CPUComp mai mic) decât \fB\-4e\fP È™i \fB\-6e\fP, respectiv. ÃŽn +acest fel, nu există două nivele prestabilite identice. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +ValPrestab;DimDict;CPUComp;MemComp;MemDec +\-0e;256 KiB;8;4 MiB;1 MiB +\-1e;1 MiB;8;13 MiB;2 MiB +\-2e;2 MiB;8;25 MiB;3 MiB +\-3e;4 MiB;7;48 MiB;5 MiB +\-4e;4 MiB;8;48 MiB;5 MiB +\-5e;8 MiB;7;94 MiB;9 MiB +\-6e;8 MiB;8;94 MiB;9 MiB +\-7e;16 MiB;8;186 MiB;17 MiB +\-8e;32 MiB;8;370 MiB;33 MiB +\-9e;64 MiB;8;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +De exemplu, există un total de patru nivele prestabilite care folosesc +dicÈ›ionarul 8Mio, a căror ordine de la cel mai rapid la cel mai lent este +\fB\-5\fP, \fB\-6\fP, \fB\-5e\fP È™i \fB\-6e\fP . +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +Acestea sunt alias de opÈ›iuni, oarecum înÈ™elătoare pentru \fB\-0\fP È™i, +respectiv, \fB\-9\fP. Acestea sunt furnizate numai pentru compatibilitatea cu +LZMA Utils. EvitaÈ›i utilizarea acestor opÈ›iuni. +.TP +\fB\-\-block\-size=\fP\fIdimensiunea\fP +Când comprimă în formatul \fB.xz\fP, împarte datele de intrare în blocuri de +\fIdimensiunea\fP octeÈ›i. Blocurile sunt comprimate independent unul de +celălalt, ceea ce ajută în modul cu mai multe fire de execuÈ›ie È™i face +posibilă decomprimarea cu acces aleatoriu limitat. Această opÈ›iune este de +obicei folosită pentru a suprascrie dimensiunea implicită a blocului în +modul cu mai multe fire de execuÈ›ie, dar această opÈ›iune poate fi folosită +È™i în modul cu un singur fir de execuÈ›ie. +.IP "" +ÃŽn modul cu mai multe fire de execuÈ›ie, aproximativ de trei ori +\fIdimensiunea\fP de octeÈ›i vor fi alocaÈ›i în fiecare fir pentru stocarea +intrării È™i ieÈ™irii. \fIDimensiunea\fP implicită este de trei ori dimensiunea +dicÈ›ionarului LZMA2 sau 1Mio, oricare dintre acestea este mai mare. ÃŽn mod +obiÈ™nuit, o valoare bună este de două la patru ori dimensiunea dicÈ›ionarului +LZMA2 sau de cel puÈ›in 1Mio. Utilizarea unei \fIdimensiuni\fP mai mici decât +dimensiunea dicÈ›ionarului LZMA2 este o risipă de memorie RAM, deoarece +atunci memoria tampon a dicÈ›ionarului LZMA2 nu va fi niciodată utilizată pe +deplin. ÃŽn modul cu mai multe fire de execuÈ›ie, dimensiunile blocurilor sunt +stocate în anteturile blocurilor. Aceste informaÈ›ii privind dimensiunea sunt +necesare pentru decomprimarea cu mai multe fire. +.IP "" +ÃŽn modul cu un singur fir de execuÈ›ie, nicio divizare a blocurilor nu se +face în mod implicit. Folosirea acestei opÈ›iuni nu afectează utilizarea +memoriei. Nu sunt stocate informaÈ›ii despre dimensiune în antetele +blocurilor, astfel încât fiÈ™ierele create în modul cu un singur fir de +execuÈ›ie nu vor fi identice cu fiÈ™ierele create în modul cu mai multe fire +de execuÈ›ie. Lipsa informaÈ›iilor privind dimensiunea înseamnă, de asemenea, +că \fBxz\fP nu va putea decomprima fiÈ™ierele în modul cu mai multe fire. de +execuÈ›ie. +.TP +\fB\-\-block\-list=\fP\fIelemente\fP +Când comprimă în formatul \fB.xz\fP, începe un nou bloc cu un lanÈ› de filtre +personalizat opÈ›ional după intervalele specificate de date necomprimate. +.IP "" +\fIelementele\fP sunt o listă separată prin virgule. Fiecare element este +format dintr\-un număr opÈ›ional de lanÈ› de filtrare între 0 È™i 9, urmat de +două puncte (\fB:\fP) È™i de o dimensiune cerută a datelor +necomprimate. Omiterea unui element (două sau mai multe virgule consecutive) +este o prescurtare pentru a utiliza dimensiunea È™i filtrele din elementul +anterior. +.IP "" +ÃŽn cazul în care fiÈ™ierul de intrare este mai mare decât suma dimensiunilor +din \fIelemente\fP, ultimul element se repetă până la sfârÈ™itul fiÈ™ierului. O +valoare specială de \fB0\fP poate fi utilizată ca ultimă dimensiune pentru a +indica faptul că restul fiÈ™ierului trebuie să fie codificat ca un singur +bloc. +.IP "" +Un lanÈ› de filtre alternativ pentru fiecare bloc poate fi specificat în +combinaÈ›ie cu opÈ›iunile \fB\-\-filters1=\fP\fIfiltre\fP \&...\& +\fB\-\-filters9=\fP\fIfiltre\fP. Aceste opÈ›iuni definesc lanÈ›uri de filtre cu un +identificator cuprins între 1\(en9. LanÈ›ul de filtre 0 poate fi utilizat +pentru a se referi la lanÈ›ul de filtre implicit, ceea ce este acelaÈ™i lucru +cu a nu specifica un lanÈ› de filtre. Identificatorul lanÈ›ului de filtre +poate fi utilizat înaintea dimensiunii necomprimate, urmat de două puncte +(\fB:\fP). De exemplu, dacă se specifică +\fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP, atunci blocurile vor fi +create folosind: +.RS +.IP \(bu 3 +LanÈ›ul de filtre specificat de \fB\-\-filters1\fP È™i 2 Mio de intrare +.IP \(bu 3 +LanÈ›ul de filtre specificat de \fB\-\-filters3\fP È™i 2 Mio de intrare +.IP \(bu 3 +LanÈ›ul de filtre specificat de \fB\-\-filters2\fP È™i 4 Mio de intrare +.IP \(bu 3 +LanÈ›ul de filtre specificat de \fB\-\-filters2\fP È™i 4 Mio de intrare +.IP \(bu 3 +LanÈ›ul de filtre implicit È™i 2 MiB de intrare +.IP \(bu 3 +LanÈ›ul de filtre implicit È™i 4 MiB de intrare pentru fiecare bloc până la +sfârÈ™itul intrării. +.RE +.IP "" +Dacă se specifică o dimensiune care depășeÈ™te dimensiunea blocului +codificatorului (fie valoarea implicită în modul cu fire de execuÈ›ie, fie +valoarea specificată cu \fB\-\-block\-size=\fP\fIdimensiune\fP), codificatorul va +crea blocuri suplimentare, păstrând limitele specificate în \fIelemente\fP. De +exemplu, dacă se specifică \fB\-\-block\-size=10MiB\fP +\fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP È™i fiÈ™ierul de intrare este de +80 MiB, se vor obÈ›ine 11 blocuri: 5, 10, 8, 10, 10, 2, 10, 10, 10, 4, 10, +10, 10 È™i 1 Mio. +.IP "" +ÃŽn modul cu mai multe fire de execuÈ›ie, dimensiunile blocurilor sunt stocate +în antetele blocurilor. Acest lucru nu se face în modul cu un singur fir de +execuÈ›ie, astfel încât ieÈ™irea codificată nu va fi identică cu cea a modului +cu mai multe fire de execuÈ›ie. +.TP +\fB\-\-flush\-timeout=\fP\fItimp_limită\fP +La comprimare, dacă au trecut mai mult de \fItimp_limită\fP milisecunde (un +întreg pozitiv) de la curățarea anterioară È™i citirea mai multor intrări +s\-ar bloca, toate datele de intrare în aÈ™teptare sunt eliminate din +codificator È™i puse la dispoziÈ›ie în fluxul de ieÈ™ire. Acest lucru poate să +fie util dacă \fBxz\fP este utilizat pentru a comprima datele care sunt +transmise în flux printr\-o reÈ›ea. Valorile mici de \fItimp_limită\fP fac datele +disponibile la capătul de recepÈ›ie cu o mică întârziere, dar valorile mari +de \fItimp_limită\fP oferă un raport de comprimare mai bun. +.IP "" +Această caracteristică este dezactivată în mod implicit. Dacă această +opÈ›iune este specificată de mai multe ori, ultima este cea care se ia în +considerare. Valoarea specială a lui \fItimp_limită\fP de \fB0\fP, poate fi +utilizată pentru a dezactiva în mod explicit această caracteristică. +.IP "" +Această caracteristică nu este disponibilă în sistemele non\-POSIX. +.IP "" +.\" FIXME +\fBAceastă caracteristică este încă experimentală\fP. ÃŽn prezent, \fBxz\fP este +nepotrivit pentru decomprimarea fluxului în timp real datorită modului în +care \fBxz\fP utilizează memoria tampon. +.TP +\fB\-\-no\-sync\fP +Nu sincronizează fiÈ™ierul È›intă È™i directorul acestuia cu dispozitivul de +stocare înainte de a elimina fiÈ™ierul sursă. Acest lucru poate îmbunătăți +performanÈ›a în cazul comprimării sau decomprimării multor fiÈ™iere mici. Cu +toate acestea, dacă sistemul se blochează imediat după È™tergere, este +posibil ca fiÈ™ierul È›intă să nu fi fost scris pe dispozitivul de stocare, +dar operaÈ›ia de È™tergere să fi fost. ÃŽn acest caz, nici fiÈ™ierul sursă +original, nici fiÈ™ierul È›intă nu sunt disponibile. +.IP "" +Această opÈ›iune are efect numai atunci când \fBxz\fP urmează să elimine +fiÈ™ierul sursă. ÃŽn alte cazuri, sincronizarea nu se face niciodată. +.IP "" +Sincronizarea È™i \fB\-\-no\-sync\fP au fost adăugate în \fBxz\fP 5.7.1alpha. +.TP +\fB\-\-memlimit\-compress=\fP\fIlimita\fP +StabileÈ™te o limită de utilizare a memoriei pentru comprimare. Dacă această +opÈ›iune este specificată de mai multe ori, ultima va avea efect. +.IP "" +Dacă parametrii de comprimare depășesc \fIlimita\fP, \fBxz\fP va încerca să +ajusteze parametrii scăzând valorile acestora, astfel încât limita să nu mai +fie depășită È™i va afiÈ™a o notificare că ajustarea automată a fost +efectuată. Ajustările se fac în această ordine: reducerea numărului de fire, +trecerea la modul un singur fir de execuÈ›ie dacă chiar È™i un singur fir în +modul cu mai multe fire de execuÈ›ie depășeÈ™te \fIlimita\fP È™i, în final, +reducerea dimensiunii dicÈ›ionarului LZMA2. +.IP "" +Când comprimă cu opÈ›iunea \fB\-\-format=raw\fP sau dacă a fost specificată +opÈ›iunea \fB\-\-no\-adjust\fP, numai numărul de fire poate fi redus, deoarece se +poate face fără a afecta rezultatul comprimării. +.IP "" +Dacă \fIlimita\fP nu poate fi îndeplinită chiar È™i cu ajustările descrise mai +sus, este afiÈ™ată o eroare È™i \fBxz\fP va ieÈ™i cu starea de ieÈ™ire 1. +.IP "" +\fILimita\fP poate fi specificata în mai multe moduri: +.RS +.IP \(bu 3 +\fILimita\fP poate fi o valoare absolută în octeÈ›i. Utilizarea unui sufix +întreg precum \fBMiB\fP poate fi utilă. De exemplu: +\fB\-\-memlimit\-compress=80MiB\fP +.IP \(bu 3 +\fILimita\fP poate fi specificată ca procent din memoria fizică totală +(RAM). Acest lucru poate fi util mai ales atunci când definiÈ›i variabila de +mediu \fBXZ_DEFAULTS\fP într\-un script de iniÈ›ializare shell care este partajat +între diferite calculatoare. ÃŽn acest fel, limita este automat mai mare pe +sistemele cu mai multă memorie. De exemplu: \fB\-\-memlimit\-compress=70%\fP +.IP \(bu 3 +\fILimita\fP poate fi restabilită la valoarea implicită dându\-i valoarea +\fB0\fP. ÃŽn prezent, aceasta este echivalentă cu stabilirea \fIlimitei\fP la +\fBmax\fP (fără limită de utilizare a memoriei). +.RE +.IP "" +Pentru \fBxz\fP pe 32 de biÈ›i există un caz special: dacă \fIlimita\fP ar fi peste +\fB4020MiB\fP, \fIlimita\fP este stabilită la \fB4020MiB\fP. Pe MIPS32 este +stabilită în schimb la \fB2000MiB\fP; (valorile \fB0\fP È™i \fBmax\fP nu sunt afectate +de acest lucru \-\- o caracteristică similară nu există pentru +decomprimare). Acest lucru poate fi util atunci când un executabil pe 32 de +biÈ›i are acces la un spaÈ›iu de adrese de 4Gio (2Gio pe MIPS32), se speră că +nu produce daune în alte situaÈ›ii. +.IP "" +ConsultaÈ›i È™i secÈ›iunea \fBUtilizarea memoriei\fP. +.TP +\fB\-\-memlimit\-decompress=\fP\fIlimita\fP +StabileÈ™te o limită de utilizare a memoriei pentru decomprimare. Acest lucru +afectează È™i modul \fB\-\-list\fP. Dacă operaÈ›iunea nu este posibilă fără a +depăși \fIlimita\fP, \fBxz\fP va afiÈ™a o eroare È™i decomprimarea fiÈ™ierului va +eÈ™ua. ConsultaÈ›i \fB\-\-memlimit\-compress=\fP\fIlimita\fP pentru modalitățile +posibile de a specifica \fIlimita\fP. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fIlimita\fP +StabileÈ™te o limită de utilizare a memoriei pentru decomprimarea cu mai +multe fire de execuÈ›ie. Acest lucru poate afecta doar numărul de fire de +execuÈ›ie; acest lucru nu îl va face niciodată pe \fBxz\fP să refuze +decomprimarea unui fiÈ™ier. Dacă \fIlimita\fP este prea scăzută pentru a permite +orice mod cu mai multe fire de execuÈ›ie, \fIlimita\fP este ignorată È™i \fBxz\fP va +continua în modul cu un singur fir de execuÈ›ie. ReÈ›ineÈ›i că, dacă se +foloseÈ™te È™i opÈ›iunea \fB\-\-memlimit\-decompress\fP, se va aplica întotdeauna +atât modurilor cu un singur fir de execuÈ›ie, cât È™i modurilor cu mai multe +fire de execuÈ›ie È™i astfel \fIlimita\fP efectivă pentru modul cu mai multe fire +de execuÈ›ie nu va fi niciodată mai mare decât limita stabilită cu opÈ›iunea +\fB\-\-memlimit\-decompress\fP. +.IP "" +Spre deosebire de celelalte opÈ›iuni de limită de utilizare a memoriei, +opÈ›iunea \fB\-\-memlimit\-mt\-decompress=\fP\fIlimita\fP are o \fIlimită\fP implicită +specifică sistemului. Comanda \fBxz \-\-info\-memory\fP poate fi folosită pentru a +vedea valoarea curentă. +.IP "" +Această opÈ›iune È™i valoarea ei implicită există deoarece, fără nicio limită, +decomprimarea cu (mai multe) fire de execuÈ›ie ar putea ajunge să aloce o +cantitate „nebună†de memorie cu unele fiÈ™iere de intrare. Dacă \fIlimita\fP +implicită este prea scăzută pe sistemul dumneavoastră, nu ezitaÈ›i să +creÈ™teÈ›i \fIlimita\fP, dar niciodată să nu o stabiliÈ›i la o valoare mai mare +decât cantitatea de memorie RAM utilizabilă È™i cu niÈ™te fiÈ™iere de intrare +adecvate, \fBxz\fP va încerca să utilizeze acea cantitate de memorie chiar È™i +cu un număr redus de fire de execuÈ›ie. Rularea lui \fBxz\fP cu depășirea +cantității de memorie fizice(RAM) sau a celei de interschimb(swap) nu va +îmbunătăți performanÈ›a de decomprimare. +.IP "" +ConsultaÈ›i opÈ›iunea \fB\-\-memlimit\-compress=\fP\fIlimita\fP pentru modalități +posibile de a specifica \fIlimita\fP. Stabilirea \fIlimitei\fP la \fB0\fP +restabileÈ™te \fIlimita\fP la valoarea implicită specifică sistemului. +.TP +\fB\-M\fP \fIlimita\fP, \fB\-\-memlimit=\fP\fIlimita\fP, \fB\-\-memory=\fP\fIlimita\fP +Aceasta este echivalentă cu specificarea opÈ›iunilor: +\fB\-\-memlimit\-compress=\fP\fIlimita\fP \fB\-\-memlimit\-decompress=\fP\fIlimita\fP +\fB\-\-memlimit\-mt\-decompress=\fP\fIlimita\fP. +.TP +\fB\-\-no\-adjust\fP +AfiÈ™ează o eroare È™i iese dacă limita de utilizare a memoriei nu poate fi +îndeplinită fără ajustarea parametrilor care afectează ieÈ™irea +comprimată. Adică, acest lucru împiedică \fBxz\fP să comute codificatorul din +modul cu mai multe fire de execuÈ›ie în modul cu un singur fir de execuÈ›ie È™i +să reducă dimensiunea dicÈ›ionarului LZMA2. Chiar È™i atunci când această +opÈ›iune este utilizată, numărul de fire de execuÈ›ie poate fi redus pentru a +îndeplini limita de utilizare a memoriei, deoarece aceasta nu va afecta +comprimarea. +.IP "" +Ajustarea automată este întotdeauna dezactivată la crearea fluxurilor brute +(\fB\-\-format=raw\fP). +.TP +\fB\-T\fP \fInumăr\fP, \fB\-\-threads=\fP\fInumăr\fP +Specifică numărul de fire de execuÈ›ie de utilizat. Stabilirea \fInumărului\fP +la valoarea specială \fB0\fP, face ca \fBxz\fP să utilizeze până la atâtea fire de +execuÈ›ie câte procesoare sunt în sistem. Numărul real de fire de execuÈ›ie +poate fi mai mic decât \fInumăr\fP dacă fiÈ™ierul de intrare nu este suficient +de mare pentru a trece la modul cu mai multe fire de execuÈ›ie cu parametrii +daÈ›i, sau dacă folosirea mai multor fire de execuÈ›ie ar depăși limita de +utilizare a memoriei. +.IP "" +OperaÈ›iile de comprimare cu un singur fir de execuÈ›ie È™i cele cu mai multe +fire de execuÈ›ie produc ieÈ™iri diferite. Comprimarea cu un singur fir de +execuÈ›ie va oferi cea mai mică dimensiune a fiÈ™ierului, dar numai ieÈ™irea de +la comprimarea cu mai multe fire de execuÈ›ie poate fi decomprimată folosind +mai multe fire. Stabilirea \fInumărului\fP la \fB1\fP va determina ca \fBxz\fP să +folosească modul cu un singur fir de execuÈ›ie. Stabilirea \fInumărului\fP la +orice altă valoare, inclusiv \fB0\fP, va determina ca \fBxz\fP să folosească +comprimarea cu mai multe fire de execuÈ›ie chiar dacă sistemul acceptă doar +un fir hardware; (\fBxz\fP 5.2.x foloseÈ™te modul cu un singur fir de execuÈ›ie +în această situaÈ›ie). +.IP "" +Pentru a utiliza modul cu mai multe fire de execuÈ›ie cu un singur fir, +stabiliÈ›i \fInumărul\fP la \fB+1\fP. Prefixul \fB+\fP nu are efect cu alte valori +decât \fB1\fP. O limită de utilizare a memoriei poate face în continuare \fBxz\fP +să treacă în modul cu un singur fir, cu excepÈ›ia cazului în care este +utilizată opÈ›iunea \fB\-\-no\-adjust\fP. Suportul pentru prefixul \fB+\fP a fost +adăugat în \fBxz\fP 5.4.0. +.IP "" +Dacă a fost solicitat un număr automat de fire È™i nu a fost specificată +nicio limită de utilizare a memoriei, atunci o limită „maleabilă†implicită +specifică sistemului va fi utilizată pentru a limita eventual numărul de +fire de execuÈ›ie. Este o limită „maleabilă†în sensul că este ignorată dacă +numărul de fire devine unul, astfel o limită „maleabilă†nu va opri +niciodată \fBxz\fP să comprime sau să decomprime. Această limită „maleabilă†+implicită nu va face \fBxz\fP să treacă de la modul cu mai multe fire de +execuÈ›ie la modul cu un singur fir de execuÈ›ie. Limitele active pot fi +văzute rulând comanda \fBxz \-\-info\-memory\fP. +.IP "" +ÃŽn prezent, singura metodă de procesare cu fire de execuÈ›ie este împărÈ›irea +intrării în blocuri È™i comprimarea lor independent unul de +celălalt. Dimensiunea implicită a blocului depinde de nivelul de comprimare +È™i poate fi înlocuită cu opÈ›iunea \fB\-\-block\-size=\fP\fIdimensiune\fP. +.IP "" +Decomprimarea cu fire de execuÈ›ie funcÈ›ionează numai pe fiÈ™ierele care +conÈ›in mai multe blocuri cu informaÈ›ii despre dimensiune în antetele +blocurilor. Toate fiÈ™ierele suficient de mari comprimate în modul cu mai +multe fire de execuÈ›ie îndeplinesc această condiÈ›ie, dar fiÈ™ierele +comprimate în modul cu un singur fir de execuÈ›ie nu o îndeplinesc chiar dacă +a fost folosită opÈ›iunea \fB\-\-block\-size=\fP\fIdimensiune\fP. +.IP "" +Valoarea implicită pentru \fIfire de execuÈ›ie\fP este \fB0\fP. ÃŽn \fBxz\fP 5.4.x È™i +mai vechi, valoarea implicită este \fB1\fP. +. +.SS "LanÈ›uri de filtrare personalizate pentru instrumentul de comprimare" +Un lanÈ› de filtrare personalizat permite specificarea parametrilor de +comprimare în detaliu, în loc să se bazeze pe cei asociaÈ›i opÈ›iunilor +prestabilite. Când este specificat un lanÈ› de filtrare personalizat, +opÈ›iunile prestabilite (\fB\-0\fP \&...\& \fB\-9\fP È™i \fB\-\-extreme\fP) de mai devreme +din linia de comandă sunt uitate. Dacă o opÈ›iune prestabilită este +specificată după una sau mai multe opÈ›iuni de lanÈ› de filtrare personalizat, +noua prestabilire intră în vigoare È™i opÈ›iunile lanÈ›ului de filtrare +personalizat, specificate mai devreme sunt uitate. +.PP +Un lanÈ› de filtrare este comparabil cu conductele din linia de comandă. La +comprimare, intrarea necomprimată merge la primul filtru, a cărui ieÈ™ire +merge la următorul filtru (dacă există). IeÈ™irea ultimului filtru este +scrisă în fiÈ™ierul comprimat. Numărul maxim de filtre din lanÈ› este de +patru, dar de obicei un lanÈ› de filtrare are doar unul sau două filtre. +.PP +Multe filtre au limitări în ceea ce priveÈ™te locul în care se pot afla în +lanÈ›ul de filtrare: unele filtre pot funcÈ›iona doar ca ultimul filtru din +lanÈ›, altele doar ca non\-ultim filtru È™i unele funcÈ›ionează în orice poziÈ›ie +din lanÈ›. ÃŽn funcÈ›ie de filtru, această limitare este fie inerentă +proiectării filtrului, fie există pentru a preveni problemele de securitate. +.PP +Un lanÈ› de filtre personalizat poate fi specificat în două moduri +diferite. OpÈ›iunile \fB\-\-filters=\fP\fIfiltre\fP È™i \fB\-\-filters1=\fP\fIfiltre\fP +\&...\& \fB\-\-filters9=\fP\fIfiltre\fP permit specificarea unui întreg lanÈ› de +filtre într\-o singură opÈ›iune, folosind sintaxa È™irului de filtre +liblzma. Alternativ, un lanÈ› de filtre poate fi specificat prin utilizarea +uneia sau mai multor opÈ›iuni de filtrare individuale în ordinea în care sunt +dorite în lanÈ›ul de filtre. Adică, ordinea opÈ›iunilor de filtrare +individuale este semnificativă! La decodificarea fluxurilor brute +(\fB\-\-format=raw\fP), lanÈ›ul de filtre trebuie să fie specificat în aceeaÈ™i +ordine în care a fost specificat la comprimare. Orice filtru individual sau +opÈ›iuni presetate specificate înainte de opÈ›iunea de lanÈ› complet +(\fB\-\-filters=\fP\fIfiltre\fP) vor fi uitate. Filtrele individuale specificate +după opÈ›iunea „lanÈ› complet†vor reiniÈ›ializa lanÈ›ul de filtre. +.PP +Atât opÈ›iunile de filtrare completă, cât È™i cele de filtrare individuală +acceptă \fIopÈ›iuni\fP specifice filtrului sub forma unei liste separate prin +virgule. Se ignoră virgulele suplimentare din \fIopÈ›iuni\fP. Fiecare opÈ›iune +are o valoare implicită, deci specificaÈ›i\-le pe cele pe care doriÈ›i să le +modificaÈ›i. +.PP +Pentru a vedea întregul lanÈ› de filtre È™i \fIopÈ›iuni\fP, utilizaÈ›i \fBxz \-vv\fP +(adică folosiÈ›i \fB\-\-verbose\fP de două ori). Acest lucru funcÈ›ionează È™i +pentru vizualizarea opÈ›iunilor lanÈ›ului de filtre utilizate de valorile +prestabilite. +.TP +\fB\-\-filters=\fP\fIfiltre\fP +SpecificaÈ›i întregul lanÈ› de filtre sau o presetare într\-o singură +opÈ›iune. Fiecare filtru poate fi separat prin spaÈ›ii sau două liniuÈ›e +(\fB\-\-\fP). Este posibil să fie necesar ca \fIfiltrele\fP să fie puse între +ghilimele în linia de comandă a shell\-ului pentru a fi analizate ca o +singură opÈ›iune. Pentru a indica \fIopÈ›iuni\fP, utilizaÈ›i \fB:\fP sau \fB=\fP. O +presetare poate fi prefixată cu un \fB\-\fP È™i urmată de zero sau mai multe +indicatoare. Singurul indicator suportat este \fBe\fP pentru a aplica aceleaÈ™i +opÈ›iuni ca È™i \fB\-\-extreme\fP. +.TP +\fB\-\-filters1\fP=\fIfiltre\fP ... \fB\-\-filters9\fP=\fIfiltre\fP +Specifică până la nouă lanÈ›uri de filtre suplimentare care pot fi utilizate +cu \fB\-\-block\-list\fP. +.IP "" +De exemplu, atunci când se comprimă o arhivă cu fiÈ™iere executabile urmate +de fiÈ™iere text, partea executabilă ar putea utiliza un lanÈ› de filtre cu un +filtru BCJ, iar partea de text doar filtrul LZMA2. +.TP +\fB\-\-filters\-help\fP +AfiÈ™ează un mesaj de ajutor care descrie modul de specificare a presetărilor +È™i a lanÈ›urilor de filtre personalizate în opÈ›iunile \fB\-\-filters\fP È™i +\fB\-\-filters1=\fP\fIfiltre\fP \&...\& \fB\-\-filters9=\fP\fIfiltre\fP È™i iese. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fIopÈ›iuni\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fIopÈ›iuni\fP] +.PD +Adaugă filtrul LZMA1 sau LZMA2 la lanÈ›ul de filtre. Aceste filtre pot fi +folosite doar ca ultimul filtru din lanÈ›. +.IP "" +LZMA1 este un filtru vechi, care este acceptat aproape exclusiv datorită +formatului de fiÈ™ier vechi \fB.lzma\fP, care acceptă numai LZMA1. LZMA2 este o +versiune actualizată a LZMA1 pentru a rezolva unele probleme practice ale +LZMA1. Formatul \fB.xz\fP foloseÈ™te LZMA2 È™i nu acceptă deloc LZMA1. Viteza de +comprimare È™i rapoartele LZMA1 È™i LZMA2 sunt practic aceleaÈ™i. +.IP "" +LZMA1 È™i LZMA2 au acelaÈ™i set de \fIopÈ›iuni\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fIprestabilit\fP +Reconfigurează toate \fIopÈ›iunile\fP LZMA1 sau LZMA2 la +\fIprestabilit\fP. \fIprestabilit\fP constă dintr\-un număr întreg, care poate fi +urmat de modificatori prestabiliÈ›i cu o singură literă. Numărul întreg +poate fi de la \fB0\fP la \fB9\fP, potrivindu\-se cu opÈ›iunile liniei de comandă +\fB\-0\fP \&...\& \fB\-9\fP. Singurul modificator acceptat în prezent este \fBe\fP, +care se potriveÈ™te cu \fB\-\-extreme\fP. Dacă nu este specificat \fBprestabilit\fP, +valorile implicite ale \fIopÈ›iunilor\fP LZMA1 sau LZMA2 sunt preluate din +prestabilirea \fB6\fP. +.TP +\fBdict=\fP\fIdimensiunea\fP +\fIDimensiunea\fP dicÈ›ionarului (istoricul memoriei tampon) indică câți octeÈ›i +din datele necomprimate recent procesate sunt păstraÈ›i în +memorie. Algoritmul încearcă să găsească secvenÈ›e de octeÈ›i care se repetă +(potriviri) în datele necomprimate È™i să le înlocuiască cu referinÈ›e la +datele aflate în prezent în dicÈ›ionar. Cu cât dicÈ›ionarul este mai mare, cu +atât este mai mare È™ansa de a găsi o potrivire. Astfel, creÈ™terea +\fIdimensiunii\fP dicÈ›ionarului îmbunătățeÈ™te de obicei raportul de comprimare, +dar un dicÈ›ionar mai mare decât fiÈ™ierul necomprimat este risipă de memorie. +.IP "" +\fIDimensiunea\fPtipică a dicÈ›ionarului este de la 64Kio până la 64Mio. Minimul +este de 4Kio. Maximul pentru compresie este în prezent de 1,5Gio +(1536Mio). Decomprimarea acceptă deja dicÈ›ionare cu până la un octet mai +puÈ›in de 4Gio, care este maximul pentru formatele de flux LZMA1 È™i LZMA2. +.IP "" +\fIDimensiunea\fP dicÈ›ionarului È™i găsitorul de potriviri (match finder) → +(\fImf\fP) determină împreună utilizarea memoriei de către codificatorul LZMA1 +sau LZMA2. AceeaÈ™i \fIdimensiune\fP a dicÈ›ionarului (sau mai mare) care a fost +utilizată la comprimare, este necesară pentru decomprimare, astfel încât +utilizarea memoriei de către decodificator este determinată de dimensiunea +dicÈ›ionarului utilizată la comprimare. Antetele \fB.xz\fP stochează +\fIdimensiunea\fP dicÈ›ionarului fie ca 2^\fIn\fP, fie ca 2^\fIn\fP + 2^(\fIn\fP\-1), deci +aceste \fIdimensiuni\fP sunt oarecum preferate pentru comprimare. Alte +\fIdimensiuni\fP vor fi rotunjite atunci când sunt stocate în anteturile +\&\fB.xz\fP. +.TP +\fBlc=\fP\fIlc\fP +Specifică numărul de biÈ›i de context literal. Minimul este 0 È™i maximul este +4; implicit este 3. ÃŽn plus, suma \fIlc\fP È™i \fIlp\fP nu trebuie să depășească +4. +.IP "" +ToÈ›i octeÈ›ii care nu pot fi codificaÈ›i ca potriviri sunt codificaÈ›i ca +literali. Adică, literalii sunt pur È™i simplu octeÈ›i de 8 biÈ›i care sunt +codificaÈ›i unul câte unul. +.IP "" +Codificarea literală presupune că cei mai mari biÈ›i \fIlc\fP ai octetului +anterior necomprimat se corelează cu octetul următor. De exemplu, în textul +tipic englezesc, o literă mare este adesea urmată de o literă mică, iar o +literă mică este urmată de obicei de o altă literă mică. ÃŽn setul de +caractere US\-ASCII, cei mai mari trei biÈ›i sunt 010 pentru literele mari È™i +011 pentru literele mici. Când \fIlc\fP este cel puÈ›in 3, codificarea literală +poate profita de această proprietate în datele necomprimate. +.IP "" +Valoarea implicită (3) este de obicei bună. Dacă doriÈ›i o comprimare maximă, +testaÈ›i \fBlc=4\fP. Uneori ajută puÈ›in, iar uneori înrăutățeÈ™te comprimarea +\&. Dacă o agravează, încercaÈ›i de\-asemeni cu \fBlc=2\fP. +.TP +\fBlp=\fP\fIlp\fP +Specifică numărul de biÈ›i de poziÈ›ie literală. Minimul este 0 È™i maximul +este 4; implicit este 0. +.IP "" +\fILp\fP afectează ce fel de aliniere în datele necomprimate este presupusă la +codificarea literalelor. ConsultaÈ›i argumentul \fIpb\fP de mai jos pentru mai +multe informaÈ›ii despre aliniere. +.TP +\fBpb=\fP\fIpb\fP +Specifică numărul de biÈ›i de poziÈ›ie. Minimul este 0 È™i maximul este 4; +implicit este 2. +.IP "" +\fIPb\fP afectează ce fel de aliniere în datele necomprimate este presupusă în +general. Valoarea implicită înseamnă alinierea pe patru octeÈ›i +(2^\fIpb\fP=2^2=4), care este adesea o alegere bună atunci când nu există o +ipoteză mai bună. +.IP "" +Când alinierea este cunoscută, definirea lui \fIpb\fP în mod corespunzător +poate reduce puÈ›in dimensiunea fiÈ™ierului. De exemplu, cu fiÈ™ierele text cu +aliniere pe un octet (US\-ASCII, ISO\-8859\-*, UTF\-8), definirea \fBpb=0\fP poate +îmbunătăți uÈ™or comprimarea. Pentru textul UTF\-16, \fBpb=1\fP este o alegere +bună. Dacă alinierea este un număr impar, cum ar fi 3 octeÈ›i, \fBpb=0\fP ar +putea fi cea mai bună alegere. +.IP "" +Chiar dacă alinierea presupusă poate fi ajustată cu \fIpb\fP È™i \fIlp\fP, LZMA1 È™i +LZMA2 încă favorizează uÈ™or alinierea pe 16 octeÈ›i. Ar putea fi demn de luat +în considerare atunci când proiectaÈ›i formate de fiÈ™iere care pot fi adesea +comprimate cu LZMA1 sau LZMA2. +.TP +\fBmf=\fP\fImf\fP +Căutarea potrivirilor are un efect major asupra vitezei codificatorului, +utilizării memoriei È™i raportului de comprimare. De obicei, găsitorii de +potriviri din lanÈ›ul sumelor de control sunt mai rapizi decât găsitorii de +potriviri din arborele binar. Valoarea implicită depinde de \fIprestabilit\fP: +0 foloseÈ™te \fBhc3\fP, 1\(en3 foloseÈ™te \fBhc4\fP, iar restul foloseÈ™te \fBbt4\fP. +.IP "" +Sunt acceptate următoarele opÈ›iuni de căutare de potriviri. Formulele de +utilizare a memoriei de mai jos sunt aproximări estimative, care se apropie +cel mai mult de realitate atunci când \fIdict\fP este o putere a lui doi. +.RS +.TP +\fBhc3\fP +LanÈ› de sumă de control, cu suma de control de 2 È™i 3 octeÈ›i +.br +Valoarea minimă pentru \fInice\fP: 3 +.br +Utilizarea memoriei: +.br +\fIdict\fP * 7.5 (dacă \fIdict\fP <= 16 Mio); +.br +\fIdict\fP * 5.5 + 64 MiB (dacă \fIdict\fP > 16 Mio) +.TP +\fBhc4\fP +LanÈ› de sumă de control, cu suma de control de 2, 3 È™i 4 octeÈ›i +.br +Valoarea minimă pentru \fInice\fP: 4 +.br +Utilizarea memoriei: +.br +\fIdict\fP * 7.5 (dacă \fIdict\fP <= 32 Mio); +.br +\fIdict\fP * 6.5 (dacă \fIdict\fP > 32 Mio) +.TP +\fBbt2\fP +Arbore binar cu suma de control de 2 octeÈ›i +.br +Valoarea minimă pentru \fInice\fP: 2 +.br +Utilizarea memoriei: \fIdict\fP * 9.5 +.TP +\fBbt3\fP +Arbore binar cu suma de control de 2 È™i 3 octeÈ›i +.br +Valoarea minimă pentru \fInice\fP: 3 +.br +Utilizarea memoriei: +.br +\fIdict\fP * 11.5 (dacă \fIdict\fP <= 16 Mio); +.br +\fIdict\fP * 9.5 + 64 MiB (dacă \fIdict\fP > 16 Mio) +.TP +\fBbt4\fP +Arbore binar cu suma de control de 2, 3 È™i 4 octeÈ›i +.br +Valoarea minimă pentru \fInice\fP: 4 +.br +Utilizarea memoriei: +.br +\fIdict\fP * 11.5 (dacă \fIdict\fP <= 32 Mio); +.br +\fIdict\fP * 10.5 (dacă \fIdict\fP > 32 Mio) +.RE +.TP +\fBmode=\fP\fImod\fP +Comprimarea \fImod\fP specifică metoda de analiză a datelor produse de +găsitorul de potriviri. \fIModurile\fP acceptate sunt \fBfast\fP(rapid) È™i +\fBnormal\fP. Valoarea implicită este \fBfast\fP pentru \fIprestabiliri\fP 0\(en3 È™i +\fBnormal\fP pentru \fIprestabiliri\fP 4\(en9. +.IP "" +De obicei, \fBfast\fP este folosit cu instrumentele de căutare de potriviri ale +lanÈ›ului de sume de control, È™i \fBnormal\fP cu instrumentele de căutare de +potriviri din arborele binar. Aceasta este È™i ceea ce fac \fIprestabiririle\fP. +.TP +\fBnice=\fP\fInice\fP +Specifică ceea ce este considerat a fi o lungime bună(nice) pentru o +potrivire. Odată ce este găsită o potrivire de cel puÈ›in \fInice\fP octeÈ›i, +algoritmul nu mai caută după potriviri posibile mai bune. +.IP "" +\fINice\fP poate fi de 2\(en273 octeÈ›i. Valorile mai mari tind să ofere un +raport de comprimare mai bun în detrimentul vitezei. Valoarea implicită +depinde de \fIprestabilit\fP. +.TP +\fBdepth=\fP\fIadâncimea\fP +Specifică adâncimea maximă de căutare în găsitorul de potriviri. Valoarea +implicită este valoarea specială de 0, ceea ce face ca instrumentul de +comprimare să determine o \fIadâncime\fP rezonabilă pornind de la valorile +\fImf\fP È™i \fInice\fP. +.IP "" +\fIAdâncimea\fP rezonabilă pentru lanÈ›uri de sumă de control este 4\(en100 È™i +16\(en1000 pentru arbori binari. Folosirea unor valori foarte mari pentru +\fIadâncime\fP poate face codificatorul extrem de lent cu unele +fiÈ™iere. EvitaÈ›i să stabiliÈ›i \fIadâncimea\fP la valori peste 1000, cu excepÈ›ia +cazului în care sunteÈ›i pregătit să întrerupeÈ›i comprimarea în cazul în care +durează prea mult. +.RE +.IP "" +La decodificarea fluxurilor brute (\fB\-\-format=raw\fP), LZMA2 are nevoie doar +de \fIdimensiunea\fP dicÈ›ionarului. LZMA1 are nevoie de asemenea de \fIlc\fP, +\fIlp\fP È™i \fIpb\fP. +.TP +\fB\-\-x86\fP[\fB=\fP\fIopÈ›iuni\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fIopÈ›iuni\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fIopÈ›iuni\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fIopÈ›iuni\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fIopÈ›iuni\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fIopÈ›iuni\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fIopÈ›iuni\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIopÈ›iuni\fP] +.PD +Adaugă un filtru de ramură/apel/salt (branch/call/jump ⟶ „BCJâ€) la lanÈ›ul de +filtre. Aceste filtre pot fi utilizate numai ca un filtru care nu este +ultimul din lanÈ›ul de filtrare. +.IP "" +Un filtru BCJ converteÈ™te adresele relative din codul maÈ™inii în omoloagele +lor absolute. Acest lucru nu modifică dimensiunea datelor, dar creÈ™te +redundanÈ›a, ceea ce poate ajuta LZMA2 să producă fiÈ™ier \fB.xz\fP cu 0\(en15\ % +mai mic. Filtrele BCJ sunt întotdeauna reversibile, deci folosind un filtru +BCJ pentru tipul greÈ™it de date nu provoacă nicio pierdere de date, deÈ™i +poate înrăutăți puÈ›in raportul de comprimare. Filtrele BCJ sunt foarte +rapide È™i folosesc o cantitate nesemnificativă de memorie. +.IP "" +Aceste filtre BCJ au probleme cunoscute legate de raportul de comprimare: +.RS +.IP \(bu 3 +Unele tipuri de fiÈ™iere care conÈ›in cod executabil (de exemplu, fiÈ™iere +obiect, biblioteci statice È™i module de kernel Linux) au adresele din +instrucÈ›iuni completate cu valori de umplere. Aceste filtre BCJ vor face în +continuare conversia adresei, ceea ce va înrăutăți comprimarea cu aceste +fiÈ™iere. +.IP \(bu 3 +Dacă pe o arhivă este aplicat un filtru BCJ, este posibil ca raportul de +comprimare să fie mai rău decât la neutilizarea unui filtru BCJ. De exemplu, +dacă există executabile similare sau chiar identice, filtrarea va face +probabil fiÈ™ierele mai puÈ›in asemănătoare È™i astfel comprimarea este mai +proastă. ConÈ›inutul fiÈ™ierelor neexecutabile din aceeaÈ™i arhivă poate conta +È™i el. ÃŽn practică, trebuie să încercaÈ›i cu È™i fără filtru BCJ pentru a +vedea care rezultat este mai bun în fiecare situaÈ›ie. +.RE +.IP "" +Seturi de instrucÈ›iuni diferite au o aliniere diferită: fiÈ™ierul executabil +trebuie aliniat la un multiplu al acestei valori în datele de intrare pentru +ca filtrul să funcÈ›ioneze. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +Filtru;Aliniere;Note +x86;1;x86 pe 32 de biÈ›i +;;sau 64 de biÈ›i +ARM;4; +ARM\-Thumb;2; +ARM64;4;alinierea pe 4096\-octeÈ›i +;;este cea mai bună +PowerPC;4;Doar big endian +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +Deoarece datele filtrate prin BCJ sunt de obicei comprimate cu LZMA2, +raportul de comprimare poate fi uÈ™or îmbunătățit dacă opÈ›iunile LZMA2 sunt +definite pentru a se potrivi cu alinierea filtrului BCJ selectat. Exemple: +.RS +.IP \(bu 3 +Filtrul IA\-64 are o aliniere de 16 octeÈ›i, astfel încât \fBpb=4,lp=4,lc=0\fP +este alegere adecvată cu LZMA2 (2^4=16). +.IP \(bu 3 +Codul RISC\-V are o aliniere pe 2 sau 4 octeÈ›i, depinzând de faptul că +fiÈ™ierul conÈ›ine instrucÈ›iuni comprimate pe 16 biÈ›i (extensia C) sau +nu. Atunci când se utilizează instrucÈ›iuni pe 16 biÈ›i, \fBpb=2,lp=1,lc=3\fP sau +\fBpb=1,lp=1,lc=3\fP este o alegere bună. Atunci când nu sunt prezente +instrucÈ›iuni pe 16 biÈ›i, \fBpb=2,lp=2,lc=2\fP este cea mai bună +alegere. \fBreadelf \-h\fP poate fi utilizată pentru a verifica dacă „RVC†apare +în linia „Indicatori". +.IP \(bu 3 +ARM64 este întotdeauna aliniat pe 4 octeÈ›i, astfel încât \fBpb=2,lp=2,lc=2\fP +este cea mai bună alegere. +.IP \(bu 3 +Filtrul x86 este o excepÈ›ie. De obicei, este bine să rămâneÈ›i la valorile +implicite ale LZMA2 (\fBpb=2,lp=0,lc=3\fP) atunci când comprimaÈ›i executabile +x86. +.RE +.IP "" +Toate filtrele BCJ acceptă acelaÈ™i \fIopÈ›iuni\fP: +.RS +.TP +\fBstart=\fP\fIpoziÈ›ie\fP +Specifică \fIpoziÈ›ia\fP de pornire care este utilizată la conversia între +adresele relative È™i absolute. \fIPoziÈ›ia\fP trebuie să fie un multiplu al +alinierii filtrului (consultaÈ›i tabelul de mai sus). Valoarea implicită +este zero. ÃŽn practică, valoarea implicită este bună; specificarea unei +\fIpoziÈ›ii\fP personalizate nu este aproape niciodată utilă. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fIopÈ›iuni\fP] +Adaugă filtrul Delta în lanÈ›ul de filtrare. Filtrul Delta poate fi folosit +doar ca un filtru care nu este ultimul în lanÈ›ul de filtrare. +.IP "" +ÃŽn prezent, este acceptat doar calculul delta simplu de octeÈ›i. Poate fi +util la comprimarea, de exemplu, a imaginilor bitmap necomprimate sau a +sunetului PCM necomprimat. Cu toate acestea, algoritmii cu scop special pot +da rezultate semnificativ mai bune decât Delta + LZMA2. Acest lucru este +valabil mai ales în cazul audio, care se comprimă mai repede È™i mai bine, de +exemplu, cu \fBflac\fP(1). +.IP "" +\fIOpÈ›iuni\fP acceptate: +.RS +.TP +\fBdist=\fP\fIdistanÈ›a\fP +Specifică \fIdistanÈ›a\fP calculului delta în octeÈ›i. \fIDistanÈ›a\fP trebuie să fie +1\(en256. Valoarea implicită este 1. +.IP "" +De exemplu, cu \fBdist=2\fP È™i intrare de opt octeÈ›i: A1 B1 A2 B3 A3 B5 A4 B7, +ieÈ™irea va fi: A1 B1 01 02 01 02 01 02. +.RE +. +.SS "Alte opÈ›iuni" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Suprimă avertismentele È™i notificările. SpecificaÈ›i acest lucru de două ori +pentru a suprima È™i erorile. Această opÈ›iune nu are niciun efect asupra +stării de ieÈ™ire. Adică, chiar dacă o avertizare a fost suprimată, starea de +ieÈ™ire pentru a indica o avertizare este încă utilizată. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +Oferă informaÈ›ii detaliate. Dacă ieÈ™irea de eroare standard este conectată +la un terminal, \fBxz\fP va afiÈ™a un indicator de progres. Specificarea +opÈ›iunii \fB\-\-verbose\fP de două ori, va avea ca rezultat oferirea de +informaÈ›ii È™i mai detaliate. +.IP "" +Indicatorul de progres afiÈ™ează următoarele informaÈ›ii: +.RS +.IP \(bu 3 +Procentul de completare este afiÈ™at dacă se cunoaÈ™te dimensiunea fiÈ™ierului +de intrare. Adică, procentul nu poate fi afiÈ™at la procesarea fiÈ™ierului +prin conducte(pipe). +.IP \(bu 3 +Cantitatea de date comprimate produse (comprimare) sau consumate +(decomprimare). +.IP \(bu 3 +Cantitatea de date necomprimate consumate (comprimare) sau produse +(decomprimare). +.IP \(bu 3 +Raportul de comprimare, care se calculează împărÈ›ind cantitatea de date +comprimate procesate până acum la cantitatea de date necomprimate procesate +până acum. +.IP \(bu 3 +Viteza de comprimare sau decomprimare. Aceasta este măsurată drept +cantitatea de date necomprimate consumate (comprimare) sau produse +(decomprimare) pe secundă. Este afiÈ™ată după ce au trecut câteva secunde de +când \fBxz\fP a început procesarea fiÈ™ierului. +.IP \(bu 3 +Timpul scurs în format M:SS sau H:MM:SS. +.IP \(bu 3 +Timpul rămas estimat este afiÈ™at numai atunci când dimensiunea fiÈ™ierului de +intrare este cunoscută È™i au trecut deja câteva secunde de când \fBxz\fP a +început procesarea fiÈ™ierului. Ora este afiÈ™ată într\-un format mai puÈ›in +precis, care nu are niciodată două puncte, de exemplu, 2 min 30 s. +.RE +.IP "" +Când ieÈ™irea de eroare standard nu este un terminal, \fB\-\-verbose\fP va face +\fBxz\fP să imprime numele fiÈ™ierului, dimensiunea comprimată, dimensiunea +necomprimată, raportul de comprimare È™i, eventual, de asemenea, viteza È™i +timpul scurs pe o singură linie la ieÈ™irea de eroare standard după +comprimarea sau decomprimarea fiÈ™ierului. Viteza È™i timpul scurs sunt +incluse numai atunci când operaÈ›iunea a durat cel puÈ›in câteva secunde. Dacă +operaÈ›iunea nu s\-a încheiat, de exemplu, din cauza întreruperii din partea +utilizatorului, se imprimă È™i procentul de completare dacă se cunoaÈ™te +dimensiunea fiÈ™ierului de intrare. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Nu comută starea de ieÈ™ire la 2 chiar dacă a fost detectată o condiÈ›ie care +merită avertizată. Această opÈ›iune nu afectează nivelul de detaliere al +informaÈ›iilor, astfel încât atât \fB\-\-quiet\fP cât È™i \fB\-\-no\-warn\fP trebuie +folosite pentru a nu afiÈ™a avertismente È™i pentru a nu modifica starea de +ieÈ™ire. +.TP +\fB\-\-robot\fP +AfiÈ™ează mesajele într\-un format care poate fi analizat de maÈ™ină. Acest +lucru are scopul de a uÈ™ura scrierea interfeÈ›elor în care se doreÈ™te să se +folosească \fBxz\fP în loc de liblzma, ceea ce poate fi cazul cu diferite +scripturi. IeÈ™irea cu această opÈ›iune activată este menită să fie stabilă în +toate versiunile \fBxz\fP. ConsultaÈ›i secÈ›iunea \fBMOD ROBOT\fP pentru detalii. +.TP +\fB\-\-info\-memory\fP +AfiÈ™ează, într\-un format care poate fi citit de om, câtă memorie fizică +(RAM) È™i câte fire de execuÈ›ie de procesor \fBxz\fP crede că are sistemul È™i +limitele de utilizare a memoriei pentru comprimare È™i decomprimare È™i iese +cu succes. +.TP +\fB\-h\fP, \fB\-\-help\fP +AfiÈ™ează un mesaj de ajutor care descrie opÈ›iunile cele mai frecvent +utilizate È™i iese cu succes. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +AfiÈ™ează un mesaj de ajutor care descrie toate caracteristicile \fBxz\fP È™i +iese cu succes +.TP +\fB\-V\fP, \fB\-\-version\fP +AfiÈ™ează numărul versiunii \fBxz\fP È™i liblzma într\-un format care poate fi +citit de om. Pentru a obÈ›ine rezultate analizabile de maÈ™ină, specificaÈ›i +\fB\-\-robot\fP înainte de \fB\-\-version\fP. +. +.SH "MOD ROBOT" +Modul robot este activat cu opÈ›iunea \fB\-\-robot\fP. Face ieÈ™irea lui \fBxz\fP mai +uÈ™or de analizat de către alte programe. ÃŽn prezent, opÈ›iunea \fB\-\-robot\fP +este acceptată numai împreună cu opÈ›iunile \fB\-\-list\fP, \fB\-\-filters\-help\fP, +\fB\-\-info\-memory\fP, È™i \fB\-\-version\fP. Va fi acceptată pentru comprimare È™i +decomprimare în viitor. +. +.SS "Modul listă" +\fBxz \-\-robot \-\-list\fP utilizează o ieÈ™ire separată de tabulatori. Prima +coloană a fiecărei linii are un È™ir care indică tipul de informaÈ›ii găsite +pe acea linie: +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP +Aceasta este întotdeauna prima linie când începe să se listeze un fiÈ™ier. A +doua coloană de pe linie este numele fiÈ™ierului. +.TP +\fBfile\fP +Această linie conÈ›ine informaÈ›ii generale despre fiÈ™ierul \fB.xz\fP. Această +linie este întotdeauna tipărită după linia \fBname\fP. +.TP +\fBstream\fP +Acest tip de linie este utilizat numai atunci când a fost specificată +opÈ›iunea \fB\-\-verbose\fP. Există tot atâtea linii \fBstream\fP câte fluxuri există +în fiÈ™ierul \fB.xz\fP. +.TP +\fBblock\fP +Acest tip de linie este utilizat numai atunci când a fost specificată +opÈ›iunea \fB\-\-verbose\fP. Există tot atâtea linii \fBblock\fP câte blocuri există +în fiÈ™ierul \fB.xz\fP. Liniile \fBblock\fP sunt afiÈ™ate după toate liniile +\fBstream\fP; tipurile diferite de linii nu sunt intercalate. +.TP +\fBsummary\fP +Acest tip de linie este folosit numai atunci când opÈ›iunea \fB\-\-verbose\fP a +fost specificată de două ori. Această linie este afiÈ™ată după toate liniile +\fBblock\fP. Ca È™i linia \fBfile\fP, linia \fBsummary\fP conÈ›ine informaÈ›ii generale +despre fiÈ™ierul \fB.xz\fP. +.TP +\fBtotals\fP +Această linie este întotdeauna ultima linie din lista afiÈ™ată la +ieÈ™ire. Aceasta arată numărul total È™i dimensiunile. +.PP +Coloanele din liniile \fBfile\fP: +.PD 0 +.RS +.IP 2. 4 +Numărul de fluxuri din fiÈ™ier +.IP 3. 4 +Numărul total de blocuri din fluxuri +.IP 4. 4 +Dimensiunea comprimată a fiÈ™ierului +.IP 5. 4 +Dimensiunea necomprimată a fiÈ™ierului +.IP 6. 4 +Raportul de comprimare, de exemplu, \fB0,123\fP. Dacă raportul este peste +9,999, în locul raportului sunt afiÈ™ate trei liniuÈ›e (\fB\-\-\-\fP). +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +Lista de nume de verificare a integrității, separate prin +virgule. Următoarele È™iruri sunt utilizate pentru tipurile de verificare +cunoscute: \fBNone\fP, \fBCRC32\fP, \fBCRC64\fP È™i \fBSHA\-256\fP. Pentru tipurile de +verificări necunoscute, se utilizează \fBUnknown\-\fP\fIN\fP, unde \fIN\fP este ID\-ul +de verificare ca număr zecimal (una sau două cifre). +.IP 8. 4 +Dimensiunea totală a umpluturii fluxului din fiÈ™ier +.RE +.PD +.PP +Coloanele din liniile \fBstream\fP: +.PD 0 +.RS +.IP 2. 4 +Numărul fluxului (primul flux este 1) +.IP 3. 4 +Numărul de blocuri din flux +.IP 4. 4 +PoziÈ›ia de pornire a comprimării +.IP 5. 4 +PoziÈ›ia de pornire a decomprimării +.IP 6. 4 +Dimensiune comprimată (nu include umplutura fluxului) +.IP 7. 4 +Dimensiune necomprimată +.IP 8. 4 +Raport de comprimare +.IP 9. 4 +Numele verificării de integritate +.IP 10. 4 +Dimensiunea umpluturii fluxului +.RE +.PD +.PP +Coloanele din liniile \fBblock\fP: +.PD 0 +.RS +.IP 2. 4 +Numărul fluxului care conÈ›ine acest bloc +.IP 3. 4 +Numărul blocului în raport cu începutul fluxului (primul bloc este 1) +.IP 4. 4 +Numărul blocului în raport cu începutul fiÈ™ierului +.IP 5. 4 +PoziÈ›ia de pornire a comprimării în raport cu începutul fiÈ™ierului +.IP 6. 4 +PoziÈ›ia de pornire necomprimată în raport cu începutul fiÈ™ierului +.IP 7. 4 +Dimensiunea totală comprimată a blocului (include antetele) +.IP 8. 4 +Dimensiune necomprimată +.IP 9. 4 +Raport de comprimare +.IP 10. 4 +Numele verificării de integritate +.RE +.PD +.PP +Dacă opÈ›iunea \fB\-\-verbose\fP a fost specificată de două ori, coloane +suplimentare sunt incluse pe liniile \fBblock\fP. Acestea nu sunt afiÈ™ate cu o +singură specificare a opÈ›iunii \fB\-\-verbose\fP, deoarece obÈ›inerea acestor +informaÈ›ii necesită multe căutări È™i, prin urmare, poate fi lentă: +.PD 0 +.RS +.IP 11. 4 +Valoarea verificării integrității în hexazecimal +.IP 12. 4 +Dimensiunea antetului blocului +.IP 13. 4 +Indicatori de bloc: \fBc\fP indică faptul că este prezentă dimensiunea +comprimată, iar \fBu\fP indică faptul că este prezentă dimensiunea +necomprimată. Dacă indicatorul nu este determinat, este afiÈ™ată o liniuță +(\fB\-\fP) pentru a menÈ›ine lungimea È™irului fixă. Pot fi adăugate noi +indicatoare la sfârÈ™itul È™irului, în viitor. +.IP 14. 4 +Dimensiunea datelor comprimate reale din bloc (acest lucru exclude antetul +blocului, umplutura blocului È™i câmpurile de verificare) +.IP 15. 4 +Cantitatea de memorie (în octeÈ›i) necesară pentru a decomprima acest bloc cu +această versiune \fBxz\fP +.IP 16. 4 +LanÈ› de filtrare. ReÈ›ineÈ›i că majoritatea opÈ›iunilor utilizate în timpul +comprimării nu pot fi cunoscute, deoarece doar opÈ›iunile necesare pentru +decomprimare sunt stocate în anteturile \fB.xz\fP. +.RE +.PD +.PP +Coloanele din liniile \fBsummary\fP: +.PD 0 +.RS +.IP 2. 4 +Cantitatea de memorie (în octeÈ›i) necesară pentru a decomprima acest fiÈ™ier +cu această versiune \fBxz\fP +.IP 3. 4 +\fByes\fP sau \fBno\fP indicând dacă toate antetele blocurilor au atât dimensiunea +comprimată, cât È™i dimensiunea necomprimată stocate în ele +.PP +\fIÃŽncepând cu\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +Versiunea \fBxz\fP minimă necesară pentru a decomprima fiÈ™ierul +.RE +.PD +.PP +Coloanele din linia \fBtotals\fP: +.PD 0 +.RS +.IP 2. 4 +Numărul de fluxuri +.IP 3. 4 +Numărul de blocuri +.IP 4. 4 +Dimensiunea comprimată +.IP 5. 4 +Dimensiune necomprimată +.IP 6. 4 +Raportul mediu de comprimare +.IP 7. 4 +Lista de nume de verificare a integrității, separate prin virgule, care au +fost prezente în fiÈ™iere +.IP 8. 4 +Dimensiunea umpluturii fluxului +.IP 9. 4 +Numărul de fiÈ™iere. Aceasta este aici pentru a păstra ordinea coloanelor +anterioare la fel ca pe liniile \fBfile\fP. +.PD +.RE +.PP +Dacă opÈ›iunea \fB\-\-verbose\fP a fost specificată de două ori, pe linia +\fBtotals\fP sunt incluse coloane suplimentare: +.PD 0 +.RS +.IP 10. 4 +Cantitatea maximă de memorie (în octeÈ›i) necesară pentru a decomprima +fiÈ™ierele cu această versiune \fBxz\fP +.IP 11. 4 +\fByes\fP sau \fBno\fP indicând dacă toate antetele blocurilor au atât dimensiunea +comprimată, cât È™i dimensiunea necomprimată stocate în ele +.PP +\fIÃŽncepând cu\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +Versiunea \fBxz\fP minimă necesară pentru a decomprima fiÈ™ierul +.RE +.PD +.PP +Versiunile viitoare pot adăuga noi tipuri de linii È™i pot fi adăugate +coloane noi la tipurile de linii existente, dar coloanele existente nu vor +fi modificate. +. +.SS "Ajutor pentru filtrare" +\fBxz \-\-robot \-\-filters\-help\fP afiÈ™ează filtrele acceptate în următorul +format: +.PP +\fIfiltru\fP\fB:\fP\fIopÈ›iune\fP\fB=<\fP\fIvaloare\fP\fB>,\fP\fIopÈ›iune\fP\fB=<\fP\fIvaloare\fP\fB>\fP... +.TP +\fBfiltru\fP +Numele filtrului +.TP +\fIopÈ›iune\fP +Numele unei opÈ›iuni specifice unui filtru +.TP +\fIvaloare\fP +Intervalele numerice \fIvaloare\fP apar ca +\fB<\fP\fImin\fP\fB\-\fP\fImax\fP\fB>\fP. Alegerile \fIvaloare\fP de tip È™ir de +caractere sunt afiÈ™ate în cadrul \fB< >\fP È™i separate de un caracter +\fB|\fP. +.PP +Fiecare filtru este afiÈ™at pe propria linie. +. +.SS "InformaÈ›ii privind limita memoriei" +\fBxz \-\-robot \-\-info\-memory\fP afiÈ™ează o singură linie cu multiple coloane +separate prin tabulatoare: +.IP 1. 4 +Cantitatea totală de memorie fizică (RAM) în octeÈ›i. +.IP 2. 4 +Limita de utilizare a memoriei pentru comprimare în octeÈ›i +(\fB\-\-memlimit\-compress\fP). O valoare specială de \fB0\fP indică configurarea +implicită, care pentru modul cu un singur fir este la fel ca fără limită. +.IP 3. 4 +Limita de utilizare a memoriei pentru decomprimare în octeÈ›i +(\fB\-\-memlimit\-decompress\fP). O valoare specială de \fB0\fP indică configurarea +implicită, care pentru modul cu un singur fir este la fel ca fără limită. +.IP 4. 4 +ÃŽncepând cu \fBxz\fP 5.3.4alpha: Utilizarea memoriei pentru decomprimarea cu +mai multe fire în octeÈ›i (\fB\-\-memlimit\-mt\-decompress\fP). Acesta nu este +niciodată zero, deoarece o valoare implicită specifică sistemului afiÈ™ată în +coloana 5 este utilizată dacă nu a fost specificată în mod explicit nicio +limită. De asemenea, aceasta nu este niciodată mai mare decât valoarea din +coloana 3, chiar dacă a fost specificată o valoare mai mare cu +\fB\-\-memlimit\-mt\-decompress\fP. +.IP 5. 4 +ÃŽncepând cu \fBxz\fP 5.3.4alpha: o limită implicită de utilizare a memoriei +specifică sistemului, care este utilizată pentru a limita numărul de fire de +execuÈ›ie atunci când se comprimă cu un număr automat de fire de execuÈ›ie +(\fB\-\-threads=0\fP) È™i nicio limită de utilizare a memoriei nu fost specificată +cu (\fB\-\-memlimit\-compress\fP). Aceasta este, de asemenea, utilizată ca valoare +implicită pentru \fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +ÃŽncepând cu \fBxz\fP 5.3.4alpha: numărul de fire de execuÈ›ie de procesor +disponibile. +.PP +ÃŽn viitor, rezultatul \fBxz \-\-robot \-\-info\-memory\fP poate avea mai multe +coloane, dar niciodată mai mult de o singură linie. +. +.SS Versiunea +\fBxz \-\-robot \-\-version\fP va afiÈ™a numărul versiunii \fBxz\fP È™i liblzma în +următorul format: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +Versiunea majoră. +.TP +\fIYYY\fP +Versiunea minoră. Numerele pare sunt prezente în versiunile +stabile. Numerele impare sunt prezente în versiunile alfa sau beta. +.TP +\fIZZZ\fP +Nivelul de plasture(patch) pentru versiunile stabile sau doar un contor +pentru versiunile de dezvoltare. +.TP +\fIS\fP +Stabilitate. 0 este alfa, 1 este beta È™i 2 este stabil. \fIS\fP trebuie să fie +întotdeauna 2 atunci când \fIAAA\fP este par. +.PP +\fIXYYYZZZS\fP sunt aceleaÈ™i pe ambele linii dacă \fBxz\fP È™i liblzma sunt din +aceeaÈ™i versiune XZ Utils. +.PP +Exemple: 4.999.9beta este \fB49990091\fP È™i 5.0.0 este \fB50000002\fP. +. +.SH "STARE DE IEȘIRE" +.TP +\fB0\fP +Totul este bine. +.TP +\fB1\fP +A apărut o eroare. +.TP +\fB2\fP +A apărut ceva care merită să fie avertizat, dar nu au apărut erori reale. +.PP +Notificările (nu avertismentele sau erorile) afiÈ™ate la ieÈ™irea de eroare +standard nu afectează starea de ieÈ™ire. +. +.SH "VARIABILE DE MEDIU" +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP analizează liste de opÈ›iuni separate prin spaÈ›ii din variabilele de +mediu \fBXZ_DEFAULTS\fP È™i \fBXZ_OPT\fP, în această ordine, înainte de a analiza +opÈ›iunile din linia de comandă. ReÈ›ineÈ›i că numai opÈ›iunile sunt analizate +din variabilele de mediu; toate non\-opÈ›iunile sunt ignorate în +tăcere. Analiza se face cu funcÈ›ia \fBgetopt_long\fP(3) care este folosită È™i +pentru argumentele liniei de comandă. +.PP +\fBAvertisment:\fP Prin definirea acestor variabile de mediu, se modifică +efectiv programele È™i scripturile care rulează \fBxz\fP. De cele mai multe ori +este sigur să se definească limitele de utilizare a memoriei, numărul de +fire È™i opÈ›iunile de comprimare prin intermediul variabilelor de mediu. Cu +toate acestea, unele opÈ›iuni pot întrerupe scripturile. Un exemplu evident +este \fB\-\-help\fP care face ca \fBxz\fP să afiÈ™eze textul de ajutor în loc să +comprime sau să decomprime un fiÈ™ier. Exemple mai subtile sunt \fB\-\-quiet\fP È™i +\fB\-\-verbose\fP. ÃŽn multe cazuri funcÈ›ionează bine activarea indicatorului de +progres folosind \fB\-\-verbose\fP, dar în unele situaÈ›ii mesajele suplimentare +creează probleme. Nivelul de detaliere al mesajelor afectează, de asemenea, +comportamentul lui \fB\-\-list\fP. +.TP +\fBXZ_DEFAULTS\fP +OpÈ›iuni implicite specifice utilizatorului sau la nivelul întregului +sistem. De obicei, acest lucru este specificat într\-un script de +iniÈ›ializare shell pentru a activa limitatorul de utilizare a memoriei lui +\fBxz\fP implicit sau pentru a stabili numărul implicit de fire. Excluzând +scripturile de iniÈ›ializare shell È™i cazurile speciale similare, scripturile +nu trebuie niciodată să modifice sau să dezactiveze \fBXZ_DEFAULTS\fP. +.TP +\fBXZ_OPT\fP +Acest lucru este pentru transmiterea opÈ›iunilor către \fBxz\fP atunci când nu +este posibil să definiÈ›i opÈ›iunile direct în linia de comandă a +\fBxz\fP. Acesta este cazul când \fBxz\fP este rulat de un script sau de un +instrument, de exemplu, GNU \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +Scripturile pot folosi \fBXZ_OPT\fP, de exemplu, pentru a configura opÈ›iunile +implicite de comprimare specifice scriptului. Se recomandă totuÈ™i să se +permită utilizatorilor să înlocuiască \fBXZ_OPT\fP dacă acest lucru este +rezonabil. De exemplu, în scripturile \fBsh\fP(1) se poate folosi ceva de genul +acesta: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "COMPATIBILITATE CU LZMA\-UTILS" +Sintaxa liniei de comandă a lui \fBxz\fP este practic o super\-colecÈ›ie de +\fBlzma\fP, \fBunlzma\fP È™i \fBlzcat\fP aÈ™a cum se găseÈ™te în LZMA Utils 4.32.x. ÃŽn +cele mai multe cazuri, este posibil să înlocuiÈ›i LZMA Utils cu XZ Utils fără +a întrerupe scripturile existente. Există totuÈ™i unele incompatibilități, +care uneori pot cauza probleme. +. +.SS "Niveluri de comprimare prestabilite" +Numerotarea nivelurilor de comprimare prestabilite nu este identică în \fBxz\fP +È™i LZMA Utils. Cea mai importantă diferență este modul în care dimensiunile +dicÈ›ionarului sunt atribuite diferitelor niveluri prestabilite. Dimensiunea +dicÈ›ionarului este aproximativ egală cu memoria utilizată la decomprimare. +.RS +.PP +.TS +tab(;); +c c c +c n n. +Nivel;xz;LZMA Utils +\-0;256 KiB;N/A +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +DiferenÈ›ele de dimensiune a dicÈ›ionarului afectează deasemenea cantitatea de +memorie utilizată la comprimare dar există È™i alte diferenÈ›e între LZMA +Utils È™i XZ Utils, care fac diferenÈ›a È™i mai mare: +.RS +.PP +.TS +tab(;); +c c c +c n n. +Nivel;xz;LZMA Utils 4.32.x +\-0;3 MiB;N/A +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +Nivelul prestabilit implicit în LZMA Utils este \fB\-7\fP, în timp ce în XZ +Utils este \fB\-6\fP, deci ambele folosesc un dicÈ›ionar de 8Mio în mod implicit. +. +.SS "FiÈ™iere .lzma transmise în flux vs. netransmise în flux" +Dimensiunea necomprimată a fiÈ™ierului poate fi stocată în antetul +\&\fB.lzma\fP. LZMA Utils face asta atunci când comprimă fiÈ™iere +obiÈ™nuite. Alternativa este să marcaÈ›i că dimensiunea necomprimată este +necunoscută È™i să folosiÈ›i marcajul de sfârÈ™it de încărcare pentru a indica +unde ar trebui să se oprească decomprimarea. LZMA Utils foloseÈ™te această +metodă atunci când dimensiunea necomprimată nu este cunoscută, ceea ce este +cazul, de exemplu, când se folosesc conducte. +.PP +\fBxz\fP acceptă decomprimarea fiÈ™ierelor \fB.lzma\fP cu sau fără marcaj de +sfârÈ™it de încărcare, dar toate fiÈ™ierele \fB.lzma\fP create de \fBxz\fP vor +folosi marcajul de sfârÈ™it de încărcare È™i vor avea dimensiunea necomprimată +marcată ca necunoscută în antetul \fB.lzma\fP. Aceasta poate fi o problemă în +unele situaÈ›ii mai puÈ›in frecvente. De exemplu, un instrument de +decomprimare \fB.lzma\fP încorporat într\-un dispozitiv poate funcÈ›iona numai cu +fiÈ™iere care au dimensiunea necomprimată cunoscută. Dacă întâmpinaÈ›i această +problemă, trebuie să utilizaÈ›i LZMA Utils sau LZMA SDK pentru a crea fiÈ™iere +\&\fB.lzma\fP cu dimensiunea necomprimată cunoscută. +. +.SS "FiÈ™iere .lzma neacceptate" +Formatul \fB.lzma\fP permite valori \fIlc\fP de până la 8 È™i valori \fIlp\fP de până +la 4. LZMA Utils poate decomprima fiÈ™iere cu orice \fIlc\fP È™i \fIlp\fP, dar +creează întotdeauna fiÈ™iere cu \fBlc=3\fP È™i \fBlp=0\fP. Crearea de fiÈ™iere cu +alte \fIlc\fP È™i \fIlp\fP este posibilă cu \fBxz\fP È™i cu LZMA SDK. +.PP +Implementarea filtrului LZMA1 în liblzma necesită ca suma \fIlc\fP È™i \fIlp\fP să +nu depășească 4. Altfel, fiÈ™ierele \fB.lzma\fP, care depășesc această limitare, +nu pot fi decomprimate cu \fBxz\fP. +.PP +LZMA Utils creează numai fiÈ™iere \fB.lzma\fP care au o dimensiune de dicÈ›ionar +de 2^\fIn\fP (o putere de 2), dar acceptă fiÈ™iere cu orice dimensiune de +dicÈ›ionar. liblzma acceptă numai fiÈ™ierele \fB.lzma\fP care au dimensiunea de +dicÈ›ionar de 2^\fIn\fP sau 2^\fIn\fP + 2^(\fIn\fP\-1). Acest lucru este pentru a +reduce numărul de „fals pozitiv†atunci când se detectează fiÈ™iere \fB.lzma\fP. +.PP +Aceste limitări nu ar trebui să fie o problemă în practică, deoarece practic +toate fiÈ™ierele \fB.lzma\fP au fost comprimate cu opÈ›iuni pe care liblzma le va +accepta. +. +.SS "Resturi rămase" +Când decomprimă, LZMA Utils ignoră în tăcere totul după primul flux +\&\fB.lzma\fP. ÃŽn majoritatea situaÈ›iilor, aceasta este o eroare. Aceasta +înseamnă, de asemenea, că LZMA Utils nu acceptă decomprimarea fiÈ™ierelor +\&\fB.lzma\fP concatenate. +.PP +Dacă au rămas date după primul flux \fB.lzma\fP, \fBxz\fP consideră că fiÈ™ierul +este corupt, cu excepÈ›ia cazului în care a fost utilizată opÈ›iunea +\fB\-\-single\-stream\fP. Acest lucru poate rupe scripturile obscure(scrise +deficitar) care presupun că resturile rămase sunt ignorate. +. +.SH NOTE +. +.SS "Rezultatul comprimării poate varia" +IeÈ™irea exactă comprimată produsă din acelaÈ™i fiÈ™ier de intrare necomprimat +poate varia între versiunile XZ Utils, chiar dacă opÈ›iunile de comprimare +sunt identice. Acest lucru se datorează faptului că instrumentul codificator +poate fi îmbunătățit (comprimare mai rapidă sau mai bună) fără a afecta +formatul fiÈ™ierului. IeÈ™irea poate varia chiar È™i între compilările diferite +ale aceleiaÈ™i versiuni XZ Utils, dacă sunt utilizate opÈ›iuni diferite de +compilare. +.PP +Cele de mai sus înseamnă că odată ce opÈ›iunea \fB\-\-rsyncable\fP a fost +utilizată, fiÈ™ierele rezultate nu vor fi neapărat sincronizate cu rsync +decât dacă atât fiÈ™ierele vechi, cât È™i cele noi au fost comprimate cu +aceeaÈ™i versiune xz. Această problemă poate fi remediată dacă o parte a +implementării codificatorului este îngheÈ›ată pentru a menÈ›ine stabilă +ieÈ™irea „rsyncabilă†între versiunile xz. +. +.SS "Instrumente de decomprimare .xz încorporate" +Implementările instrumentului de decomprimare \fB.xz\fP încorporat, cum ar fi +XZ Embedded, nu acceptă neapărat fiÈ™iere create cu tipuri de \fIverificare\fP a +integrității, altele decât \fBnone\fP È™i \fBcrc32\fP. Deoarece valoarea implicită +este \fB\-\-check=crc64\fP, trebuie să utilizaÈ›i \fB\-\-check=none\fP sau +\fB\-\-check=crc32\fP atunci când creaÈ›i fiÈ™iere pentru sistemele încorporate. +.PP +ÃŽn afara sistemelor încorporate, toate instrumentele de decomprimare în +format \fB.xz\fP acceptă toate tipurile de \fIverificare\fP sau cel puÈ›in pot +decomprima fiÈ™ierul fără a efectua verificarea integrității dacă acel tip de +\fIverificare\fP nu este acceptat. +.PP +XZ Embedded acceptă filtre BCJ, dar numai cu poziÈ›ie de pornire implicită. +. +.SH EXEMPLE +. +.SS Bazice +Comprimă fiÈ™ierul \fIfoo\fP în \fIfoo.xz\fP folosind nivelul de comprimare +implicit (\fB\-6\fP) È™i elimină fiÈ™ierul \fIfoo\fP dacă comprimarea are succes: +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +Decomprimă \fIbar.xz\fP în \fIbar\fP È™i nu elimină \fIbar.xz\fP chiar dacă +decomprimarea este efectuată cu succes: +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +Creează \fIbaz.tar.xz\fP cu nivelul prestabilit \fB\-4e\fP (\fB\-4 \-\-extreme\fP), care +este mai lent decât nivelul prestabilit implicit \fB\-6\fP, dar necesită mai +puÈ›ină memorie pentru comprimare È™i decomprimare (48Mio È™i, respectiv, +5Mio): +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +Un amestec de fiÈ™iere comprimate È™i necomprimate poate fi decomprimat la +ieÈ™irea standard cu o singură comandă: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "Comprimarea în paralel a mai multor fiÈ™iere" +ÃŽn sisteme GNU È™i *BSD, \fBfind\fP(1) È™i \fBxargs\fP(1) pot fi utilizate pentru a +paraleliza comprimarea mai multor fiÈ™iere: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +OpÈ›iunea \fB\-P\fP pentru comanda \fBxargs\fP(1) stabileÈ™te numărul de procese +paralele \fBxz\fP. Cea mai bună valoare pentru opÈ›iunea \fB\-n\fP depinde de câte +fiÈ™iere trebuie să fie comprimate. Dacă există doar câteva fiÈ™iere, valoarea +ar trebui probabil să fie 1; cu zeci de mii de fiÈ™iere, 100 sau chiar mai +mult poate să fie valoarea potrivită pentru a reduce numărul de procese +\fBxz\fP pe care \fBxargs\fP(1) le va crea în final. +.PP +OpÈ›iunea \fB\-T1\fP pentru \fBxz\fP este acolo pentru a\-l forÈ›a să ruleze în modul +cu un singur fir de execuÈ›ie, deoarece \fBxargs\fP(1) este folosit pentru a +controla cantitatea de paralelizare. +. +.SS "Modul robot" +Calculează câți octeÈ›i au fost salvaÈ›i în total după comprimarea mai multor +fiÈ™iere: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +Un script poate dori să afle dacă foloseÈ™te o versiune \fBxz\fP suficient de +nouă. Următorul script \fBsh\fP(1) verifică dacă numărul versiunii +instrumentului \fBxz\fP este cel puÈ›in 5.0.0. Această metodă este compatibilă +cu versiunile beta vechi, care nu acceptau opÈ›iunea \fB\-\-robot\fP: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Versiunea dumneavoastră de „xz†este prea veche!" +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +StabileÈ™te o limită de utilizare a memoriei pentru decomprimare folosind +variabila de mediu \fBXZ_OPT\fP, dar dacă o limită a fost deja stabilită, nu o +măreÈ™te: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "LanÈ›uri de filtrare personalizate pentru instrumentul de comprimare" +Cea mai simplă utilizare a lanÈ›urilor de filtrare personalizate este +personalizarea unei opÈ›iuni prestabilite LZMA2. Acest lucru poate fi util, +deoarece opÈ›iunile prestabilite acoperă doar un subset al combinaÈ›iilor +potenÈ›ial utile de opÈ›iuni de comprimare. +.PP +Coloanele CPUComp din tabelele de descriere a opÈ›iunilor \fB\-0\fP ... \fB\-9\fP È™i +\fB\-\-extreme\fP sunt utile atunci când personalizaÈ›i opÈ›iunilor prestabilite +LZMA2. Iată părÈ›ile relevante colectate din aceste două tabele: +.RS +.PP +.TS +tab(;); +c c +n n. +ValPrestab;CPUComp +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +Dacă È™tiÈ›i că un fiÈ™ier necesită un dicÈ›ionar oarecum mare (de exemplu, +32Mio) pentru a se comprima bine, dar doriÈ›i să\-l comprimaÈ›i mai repede +decât ar face \fBxz \-8\fP, o opÈ›iune prestabilită cu o valoare CPUComp scăzută +(de exemplu, 1) poate fi modificată pentru a utiliza un dicÈ›ionar mai mare: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +Cu anumite fiÈ™iere, comanda de mai sus poate fi mai rapidă decât \fBxz \-6\fP în +timp ce comprimă semnificativ mai bine. Cu toate acestea, trebuie subliniat +că doar unele fiÈ™iere se beneficiază de un dicÈ›ionar mare, păstrând în +acelaÈ™i timp valoarea CPUComp scăzută. Cea mai evidentă situaÈ›ie, în care un +dicÈ›ionar mare poate ajuta foarte mult, este o arhivă care conÈ›ine fiÈ™iere +foarte asemănătoare de cel puÈ›in câțiva megaocteÈ›i fiecare. Dimensiunea +dicÈ›ionarului trebuie să fie semnificativ mai mare decât orice fiÈ™ier +individual pentru a permite LZMA2 să profite din plin de asemănările dintre +fiÈ™ierele consecutive. +.PP +Dacă utilizarea unei mari cantități de memorie pentru comprimare È™i +decomprimare este în regulă, iar fiÈ™ierul comprimat are cel puÈ›in câteva +sute de megaocteÈ›i, poate fi util să folosiÈ›i un dicÈ›ionar È™i mai mare decât +cei 64Mio pe care i\-ar folosi \fBxz \-9\fP: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +Utilizarea opÈ›iunii \fB\-vv\fP (\fB\-\-verbose \-\-verbose\fP) ca în exemplul de mai +sus, poate fi utilă pentru a vedea cerinÈ›ele de memorie la comprimare È™i +decomprimare. AmintiÈ›i\-vă că utilizarea unui dicÈ›ionar mai mare decât +dimensiunea fiÈ™ierului necomprimat este risipă de memorie, de aceea, comanda +de mai sus nu este utilă pentru fiÈ™iere mici. +.PP +Uneori, timpul de comprimare nu contează, dar utilizarea memoriei la +decomprimare trebuie menÈ›inută la un nivel scăzut, de exemplu, pentru a face +posibilă decomprimarea fiÈ™ierului pe un sistem încorporat. Următoarea +comandă foloseÈ™te \fB\-6e\fP (\fB\-6 \-\-extreme\fP) ca bază È™i fixează dimensiunea +dicÈ›ionarului la doar 64Kio. FiÈ™ierul rezultat poate fi decomprimat cu XZ +Embedded (de aceea există \fB\-\-check=crc32\fP) folosind aproximativ 100Kio de +memorie. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +Dacă doriÈ›i să stoarceÈ›i cât mai mulÈ›i octeÈ›i posibil, ajustarea numărului +de biÈ›i de context literal (\fIlc\fP) È™i a numărului de biÈ›i de poziÈ›ie (\fIpb\fP) +poate ajuta uneori. Ajustarea numărului de biÈ›i de poziÈ›ie literală (\fIlp\fP) +ar putea ajuta, de asemenea, dar de obicei \fIlc\fP È™i \fIpb\fP sunt mai +importante. De exemplu, o arhivă de cod sursă conÈ›ine în mare parte text +US\-ASCII, aÈ™a că ceva precum comanda următoare, ar putea oferi un fiÈ™ier +„mai slăbuț†(aproximativ cu 0,1%) mai mic decât cu \fBxz \-6e\fP (încercaÈ›i È™i +fără \fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 fiÈ™ierul_sursă.tar\fR +.fi +.RE +.PP +Utilizarea unui alt filtru împreună cu LZMA2 poate îmbunătăți comprimarea cu +anumite tipuri de fiÈ™iere. De exemplu, pentru a comprima o bibliotecă +partajată x86 pe 32 de biÈ›i sau x86 pe 64 de biÈ›i folosind filtrul BCJ x86: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +ReÈ›ineÈ›i că ordinea opÈ›iunilor de filtrare este semnificativă. Dacă \fB\-\-x86\fP +este specificată după \fB\-\-lzma2\fP, \fBxz\fP va da o eroare, deoarece nu poate +exista niciun filtru după LZMA2 È™i, de asemenea, pentru că filtrul x86 BCJ +nu poate fi utilizat ca ultimul filtru din lanÈ›ul de filtrare. +.PP +Filtrul Delta împreună cu LZMA2 pot da rezultate bune cu imagini bitmap. De +obicei, ar trebui să întreacă comprimarea PNG, care are câteva filtre mai +avansate decât delta simplă, dar utilizează Deflate pentru comprimarea +reală. +.PP +Imaginea trebuie să fie salvată în format necomprimat, de exemplu, ca TIFF +necomprimat. Parametrul de distanță al filtrului Delta este fixat să se +potrivească cu numărul de octeÈ›i per pixel din imagine. De exemplu, +bitmap\-ul RGB pe 24 de biÈ›i necesită \fBdist=3\fP È™i este, de asemenea, bine să +pasaÈ›i \fBpb=0\fP la LZMA2 pentru a se adapta alinierii pe trei octeÈ›i: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +Dacă mai multe imagini au fost introduse într\-o singură arhivă (de exemplu, +\&\fB.tar\fP), filtrul Delta va funcÈ›iona È™i pe aceasta atâta timp cât toate +imaginile au acelaÈ™i număr de octeÈ›i per pixel. +. +.SH "CONSULTAÈšI ȘI" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ Utils: +.br +XZ Embedded: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ro/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzdec.1 new file mode 100644 index 000000000..2ba0113bc --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzdec.1 @@ -0,0 +1,101 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Romanian translation for xz-man. +.\" Mesajele în limba română pentru manualul pachetului XZ Utils. +.\" Remus-Gabriel Chelu , 2022 - 2025. +.\" Cronologia traducerii fiÈ™ierului „xz-manâ€: +.\" Traducerea iniÈ›ială, făcută de R-GC, pentru versiunea xz-man 5.4.0-pre1. +.\" Actualizare a traducerii pentru versiunea 5.4.0-pre2, făcută de R-GC, dec-2022. +.\" Actualizare a traducerii pentru versiunea 5.4.3, făcută de R-GC, mai-2023. +.\" Actualizare a traducerii pentru versiunea 5.4.4-pre1, făcută de R-GC, iul-2023. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre1, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre2, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.7.1-dev1, făcută de R-GC, ian-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.0-pre1, făcută de R-GC, mar-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.2-pre1, făcută de R-GC, oct-2025. +.\" Actualizare a traducerii pentru versiunea Y, făcută de X, Z(luna-anul). +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 "8 aprilie 2024" Tukaani "Utilități XZ" +.SH NUME +xzdec, lzmadec \- Programe de decomprimare mici de fiÈ™iere .xz È™i .lzma +.SH REZUMAT +\fBxzdec\fP [\fIopÈ›iune...\fP] [\fIfiÈ™ier...\fP] +.br +\fBlzmadec\fP [\fIopÈ›iune...\fP] [\fIfiÈ™ier...\fP] +.SH DESCRIERE +\fBxzdec\fP este un instrument de decomprimare bazat pe liblzma pentru +fiÈ™ierele \fB.xz\fP (È™i numai \fB.xz\fP). \fBxzdec\fP este destinat să funcÈ›ioneze ca +un înlocuitor pentru \fBxz\fP(1) în cele mai frecvente situaÈ›ii în care un +script a fost scris pentru a utiliza \fBxz \-\-decompress \-\-stdout\fP (È™i posibil +câteva alte opÈ›iuni frecvent utilizate) pentru a decomprima fiÈ™ierele +\&\fB.xz\fP. \fBlzmadec\fP este identic cu \fBxzdec\fP cu excepÈ›ia faptului că +\fBlzmadec\fP acceptă fiÈ™ierele \fB.lzma\fP în loc de fiÈ™ierele \fB.xz\fP. +.PP +Pentru a reduce dimensiunea executabilului, \fBxzdec\fP nu acceptă modul cu mai +multe fire de execuÈ›ie sau localizarea(afiÈ™area mesajelor în limba stabilită +de configurările regionale) È™i nu citeÈ™te opÈ›iunile din variabilele de mediu +\fBXZ_DEFAULTS\fP È™i \fBXZ_OPT\fP. \fBxzdec\fP nu acceptă afiÈ™area informaÈ›iilor +intermediare de progres: trimiterea semnalului \fBSIGINFO\fP la \fBxzdec\fP nu +face nimic, iar trimiterea semnalului \fBSIGUSR1\fP încheie procesul în loc să +afiÈ™eze informaÈ›ii despre progres. +.SH OPÈšIUNI +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +Ignorat pentru compatibilitate cu \fBxz\fP(1). \fBxzdec\fP acceptă numai +decomprimarea. +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ignorat pentru compatibilitate cu \fBxz\fP(1). \fBxzdec\fP nu creează sau elimină +niciodată niciun fiÈ™ier. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Ignorat pentru compatibilitate cu \fBxz\fP(1). \fBxzdec\fP scrie întotdeauna +datele decomprimate la ieÈ™irea standard. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Specificarea acestui lucru o dată nu face nimic, deoarece \fBxzdec\fP nu +afiÈ™ează niciodată avertismente sau notificări. SpecificaÈ›i acest lucru de +două ori pentru a suprima erorile. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Ignorat pentru compatibilitate cu \fBxz\fP(1). \fBxzdec\fP nu foloseÈ™te niciodată +starea de ieÈ™ire 2. +.TP +\fB\-h\fP, \fB\-\-help\fP +AfiÈ™ează un mesaj de ajutor È™i iese cu succes. +.TP +\fB\-V\fP, \fB\-\-version\fP +AfiÈ™ează numărul versiunii \fBxzdec\fP È™i liblzma. +.SH "STARE DE IEȘIRE" +.TP +\fB0\fP +Toate au fost bine. +.TP +\fB1\fP +A apărut o eroare. +.PP +\fBxzdec\fP nu are niciun mesaj de avertizare precum \fBxz\fP(1), astfel că starea +de ieÈ™ire 2 nu este folosită de \fBxzdec\fP. +.SH NOTE +UtilizaÈ›i \fBxz\fP(1) în loc de \fBxzdec\fP sau \fBlzmadec\fP pentru utilizarea +normală de zi cu zi. \fBxzdec\fP sau \fBlzmadec\fP sunt destinate numai +situaÈ›iilor în care este important să aveÈ›i un instrument de decomprimare +mai mic decât \fBxz\fP(1), cu funcÈ›ii complete. +.PP +\fBxzdec\fP È™i \fBlzmadec\fP nu sunt chiar atât de mici. Dimensiunea poate fi +redusă È™i mai mult prin eliminarea caracteristicilor din liblzma în timpul +compilării, dar acest lucru nu ar trebui să se facă de obicei pentru +executabilele distribuite în distribuÈ›ii tipice de sisteme de operare +neîncorporate. Dacă aveÈ›i nevoie de un instrument de decomprimare \fB.xz\fP cu +adevărat mic, luaÈ›i în considerare utilizarea XZ Embedded. +.SH "CONSULTAÈšI ȘI" +\fBxz\fP(1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ro/xzdiff.1 b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzdiff.1 new file mode 100644 index 000000000..cebad3bb3 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzdiff.1 @@ -0,0 +1,70 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Romanian translation for xz-man. +.\" Mesajele în limba română pentru manualul pachetului XZ Utils. +.\" Remus-Gabriel Chelu , 2022 - 2025. +.\" Cronologia traducerii fiÈ™ierului „xz-manâ€: +.\" Traducerea iniÈ›ială, făcută de R-GC, pentru versiunea xz-man 5.4.0-pre1. +.\" Actualizare a traducerii pentru versiunea 5.4.0-pre2, făcută de R-GC, dec-2022. +.\" Actualizare a traducerii pentru versiunea 5.4.3, făcută de R-GC, mai-2023. +.\" Actualizare a traducerii pentru versiunea 5.4.4-pre1, făcută de R-GC, iul-2023. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre1, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre2, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.7.1-dev1, făcută de R-GC, ian-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.0-pre1, făcută de R-GC, mar-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.2-pre1, făcută de R-GC, oct-2025. +.\" Actualizare a traducerii pentru versiunea Y, făcută de X, Z(luna-anul). +.\" +.\" (Note that this file is not based on gzip's zdiff.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDIFF 1 "6 martie 2025" Tukaani "Utilități XZ" +.SH NUME +xzcmp, xzdiff, lzcmp, lzdiff \- compară fiÈ™ierele comprimate +. +.SH REZUMAT +\fBxzcmp\fP [\fIopÈ›iune...\fP] \fIfiÈ™ier1\fP [\fIfiÈ™ier2\fP] +.br +\fBxzdiff\fP \&... +.br +\fBlzcmp\fP \&... (DEPRECIATÄ‚) +.br +\fBlzdiff\fP \&... (DEPRECIATÄ‚) +. +.SH DESCRIERE +\fBxzcmp\fP È™i \fBxzdiff\fP compară conÈ›inutul necomprimat a două fiÈ™iere. Datele +necomprimate È™i opÈ›iunile sunt transmise la \fBcmp\fP(1) sau \fBdiff\fP(1), cu +excepÈ›ia cazului în care se specifică \fB\-\-help\fP sau \fB\-\-version\fP. +.PP +Dacă sunt specificate atât \fIfiÈ™ier1\fP, cât È™i \fIfiÈ™ier2\fP, acestea pot fi +fiÈ™iere necomprimate sau fiÈ™iere în formate pe care \fBxz\fP(1), \fBgzip\fP(1), +\fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1) sau \fBlz4\fP(1) le poate +decomprima. Comenzile de decomprimare necesare sunt determinate de sufixele +numelor de fiÈ™iere \fIfiÈ™ier1\fP È™i \fIfiÈ™ier2\fP. Se presupune că un fiÈ™ier cu un +sufix necunoscut este fie necomprimat, fie într\-un format pe care \fBxz\fP(1) +îl poate decomprima. +.PP +ÃŽn cazul în care se furnizează un singur nume de fiÈ™ier, \fIfiÈ™ier1\fP trebuie +să aibă un sufix al unui format de comprimare acceptat, iar numele pentru +\fIfiÈ™ier2\fP se presupune că este \fIfiÈ™ier1\fP fără sufixul formatului de +comprimare. +.PP +Comenzile \fBlzcmp\fP È™i \fBlzdiff\fP sunt furnizate pentru compatibilitate +retroactivă cu LZMA Utils. Acestea sunt depreciate È™i vor fi eliminate +într\-o versiune viitoare. +. +.SH "STARE DE IEȘIRE" +ÃŽn cazul în care apare o eroare de decomprimare, starea de ieÈ™ire este +\fB2\fP. ÃŽn caz contrar, se utilizează starea de ieÈ™ire \fBcmp\fP(1) sau +\fBdiff\fP(1). +. +.SH "CONSULTAÈšI ȘI" +\fBcmp\fP(1), \fBdiff\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), +\fBzstd\fP(1), \fBlz4\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ro/xzgrep.1 b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzgrep.1 new file mode 100644 index 000000000..fc411dfa1 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzgrep.1 @@ -0,0 +1,107 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Romanian translation for xz-man. +.\" Mesajele în limba română pentru manualul pachetului XZ Utils. +.\" Remus-Gabriel Chelu , 2022 - 2025. +.\" Cronologia traducerii fiÈ™ierului „xz-manâ€: +.\" Traducerea iniÈ›ială, făcută de R-GC, pentru versiunea xz-man 5.4.0-pre1. +.\" Actualizare a traducerii pentru versiunea 5.4.0-pre2, făcută de R-GC, dec-2022. +.\" Actualizare a traducerii pentru versiunea 5.4.3, făcută de R-GC, mai-2023. +.\" Actualizare a traducerii pentru versiunea 5.4.4-pre1, făcută de R-GC, iul-2023. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre1, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre2, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.7.1-dev1, făcută de R-GC, ian-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.0-pre1, făcută de R-GC, mar-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.2-pre1, făcută de R-GC, oct-2025. +.\" Actualizare a traducerii pentru versiunea Y, făcută de X, Z(luna-anul). +.\" +.\" (Note that this file is not based on gzip's zgrep.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZGREP 1 "6 martie 2025" Tukaani "Utilități XZ" +.SH NUME +xzgrep \- caută modele în fiÈ™iere posibil comprimate +. +.SH REZUMAT +\fBxzgrep\fP [\fIopÈ›iune...\fP] \fIlistă\-modele\fP [\fIfiÈ™ier...\fP] +.br +\fBxzegrep\fP \&... +.br +\fBxzfgrep\fP \&... +.br +\fBlzgrep\fP \&... (DEPRECIATÄ‚) +.br +\fBlzegrep\fP \&... (DEPRECIATÄ‚) +.br +\fBlzfgrep\fP \&... (DEPRECIATÄ‚) +. +.SH DESCRIERE +\fBxzgrep\fP invocă \fBgrep\fP(1) asupra conÈ›inutului necomprimat al +fiÈ™ierelor. Formatele \fIfiÈ™ierelor\fP sunt determinate de sufixele numelor de +fiÈ™iere. Orice \fIfiÈ™ier\fP cu un sufix acceptat de \fBxz\fP(1), \fBgzip\fP(1), +\fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1) sau \fBlz4\fP(1) va fi decomprimat; toate +celelalte fiÈ™iere sunt presupuse a fi necomprimate. +.PP +Dacă nu se specifică niciun \fIfiÈ™ier\fP sau dacă \fIfiÈ™ier\fP este \fB\-\fP, se +citeÈ™te intrarea standard. Atunci când se citeÈ™te de la intrarea standard, +sunt decomprimate numai fiÈ™ierele acceptate de \fBxz\fP(1). Se presupune că +celelalte fiÈ™iere sunt deja în format necomprimat. +.PP +Sunt acceptate majoritatea \fIopÈ›iunilor\fP din \fBgrep\fP(1). Cu toate acestea, +următoarele opÈ›iuni nu sunt acceptate: +.IP "" 4 +\fB\-r\fP, \fB\-\-recursive\fP +.IP "" 4 +\fB\-R\fP, \fB\-\-dereference\-recursive\fP +.IP "" 4 +\fB\-d\fP, \fB\-\-directories=\fP\fIacÈ›iune\fP +.IP "" 4 +\fB\-Z\fP, \fB\-\-null\fP +.IP "" 4 +\fB\-z\fP, \fB\-\-null\-data\fP +.IP "" 4 +\fB\-\-include=\fP\fIglobal\fP +.IP "" 4 +\fB\-\-exclude=\fP\fIglobal\fP +.IP "" 4 +\fB\-\-exclude\-from=\fP\fIfiÈ™ier\fP +.IP "" 4 +\fB\-\-exclude\-dir=\fP\fIglobal\fP +.PP +\fBxzegrep\fP este un alias pentru \fBxzgrep \-E\fP. \fBxzfgrep\fP este un alias +pentru \fBxzgrep \-F\fP. +.PP +Comenzile \fBlzgrep\fP, \fBlzegrep\fP È™i \fBlzfgrep\fP sunt furnizate pentru +compatibilitate retroactivă cu LZMA Utils. Acestea sunt depreciate È™i vor fi +eliminate într\-o versiune viitoare. +. +.SH "STARE DE IEȘIRE" +.TP +0 +A fost găsită cel puÈ›in o potrivire din cel puÈ›in unul dintre fiÈ™ierele de +la intrare. Nu au apărut erori. +.TP +1 +Nu au fost găsite potriviri din niciunul dintre fiÈ™ierele de la intrare. Nu +au apărut erori. +.TP +>1 +A apărut una sau mai multe erori. Nu se cunoaÈ™te dacă au fost găsite +potriviri. +. +.SH "VARIABILE DE MEDIU" +.TP +\fBGREP\fP +Dacă variabila de mediu \fBGREP\fP este stabilită la o valoare nevidă, aceasta +este utilizată în locul lui \fBgrep\fP, \fBgrep \-E\fP sau \fBgrep \-F\fP. +. +.SH "CONSULTAÈšI ȘI" +\fBgrep\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), +\fBlz4\fP(1), \fBzgrep\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ro/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzless.1 new file mode 100644 index 000000000..9bd9b2c29 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzless.1 @@ -0,0 +1,60 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Romanian translation for xz-man. +.\" Mesajele în limba română pentru manualul pachetului XZ Utils. +.\" Remus-Gabriel Chelu , 2022 - 2025. +.\" Cronologia traducerii fiÈ™ierului „xz-manâ€: +.\" Traducerea iniÈ›ială, făcută de R-GC, pentru versiunea xz-man 5.4.0-pre1. +.\" Actualizare a traducerii pentru versiunea 5.4.0-pre2, făcută de R-GC, dec-2022. +.\" Actualizare a traducerii pentru versiunea 5.4.3, făcută de R-GC, mai-2023. +.\" Actualizare a traducerii pentru versiunea 5.4.4-pre1, făcută de R-GC, iul-2023. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre1, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre2, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.7.1-dev1, făcută de R-GC, ian-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.0-pre1, făcută de R-GC, mar-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.2-pre1, făcută de R-GC, oct-2025. +.\" Actualizare a traducerii pentru versiunea Y, făcută de X, Z(luna-anul). +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 "6 martie 2025" Tukaani "Utilități XZ" +.SH NUME +xzless, lzless \- vizualizează fiÈ™ierele (text) comprimate xz sau lzma +.SH REZUMAT +\fBxzless\fP [\fIfiÈ™ier\fP...] +.br +\fBlzless\fP [\fIfiÈ™ier\fP...] (DEPRECIATÄ‚) +.SH DESCRIERE +\fBxzless\fP este un filtru care afiÈ™ează textul din fiÈ™ierele comprimate pe un +terminal. FiÈ™ierele acceptate de \fBxz\fP(1) sunt decomprimate; se presupune că +celelalte fiÈ™iere sunt deja în format necomprimat. Dacă nu se dă nici un +\fIfiÈ™ier\fP, \fBxzless\fP citeÈ™te de la intrarea standard. +.PP +\fBxzless\fP foloseÈ™te \fBless\fP(1) pentru a\-È™i prezenta rezultatul. Spre +deosebire de \fBxzmore\fP, alegerea sa de pager nu poate fi modificată prin +definirea unei variabile de mediu. Comenzile se bazează atât pe \fBmore\fP(1) +cât È™i pe \fBvi\fP(1) È™i permit miÈ™carea înainte È™i înapoi È™i +căutarea. ConsultaÈ›i manualul \fBless\fP(1) pentru mai multe informaÈ›ii. +.PP +Comanda numită \fBlzless\fP este furnizată pentru compatibilitatea cu LZMA +Utils. Aceasta este depreciată È™i va fi eliminată într\-o versiune viitoare. +.SH "VARIABILE DE MEDIU" +.TP +\fBLESSMETACHARS\fP +O listă de caractere speciale pentru shell. Definită de \fBxzless\fP, cu +excepÈ›ia cazului în care este deja definită în mediu. +.TP +\fBLESSOPEN\fP +Aceasta este definită în linia de comandă pentru a invoca instrumentul de +decomprimare \fBxz\fP(1) pentru preprocesarea fiÈ™ierelor de intrare pentru +\fBless\fP(1). +.SH "CONSULTAÈšI ȘI" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/ro/xzmore.1 b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzmore.1 new file mode 100644 index 000000000..dbc154183 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/ro/xzmore.1 @@ -0,0 +1,62 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Romanian translation for xz-man. +.\" Mesajele în limba română pentru manualul pachetului XZ Utils. +.\" Remus-Gabriel Chelu , 2022 - 2025. +.\" Cronologia traducerii fiÈ™ierului „xz-manâ€: +.\" Traducerea iniÈ›ială, făcută de R-GC, pentru versiunea xz-man 5.4.0-pre1. +.\" Actualizare a traducerii pentru versiunea 5.4.0-pre2, făcută de R-GC, dec-2022. +.\" Actualizare a traducerii pentru versiunea 5.4.3, făcută de R-GC, mai-2023. +.\" Actualizare a traducerii pentru versiunea 5.4.4-pre1, făcută de R-GC, iul-2023. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre1, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.6.0-pre2, făcută de R-GC, feb-2024. +.\" Actualizare a traducerii pentru versiunea 5.7.1-dev1, făcută de R-GC, ian-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.0-pre1, făcută de R-GC, mar-2025. +.\" Actualizare a traducerii pentru versiunea 5.8.2-pre1, făcută de R-GC, oct-2025. +.\" Actualizare a traducerii pentru versiunea Y, făcută de X, Z(luna-anul). +.\" +.\" (Note that this file is based on xzless.1 instead of gzip's zmore.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZMORE 1 "6 martie 2025" Tukaani "Utilități XZ" +.SH NUME +xzmore, lzmore \- vizualizează fiÈ™ierele (text) comprimate xz sau lzma +. +.SH REZUMAT +\fBxzmore\fP [\fIfiÈ™ier\fP...] +.br +\fBlzmore\fP [\fIfiÈ™ier\fP...] (DEPRECIATÄ‚) +. +.SH DESCRIERE +\fBxzmore\fP afiÈ™ează textul din fiÈ™ierele comprimate pe un terminal folosind +\fBmore\fP(1). FiÈ™ierele acceptate de \fBxz\fP(1) sunt decomprimate; se presupune +că celelalte fiÈ™iere sunt deja în format necomprimat. Dacă nu se dă nici un +\fIfiÈ™iere\fP, \fBxzmore\fP citeÈ™te de la intrarea standard. ConsultaÈ›i manualul +\fBmore\fP(1) pentru comenzile de la tastatură. +.PP +ReÈ›ineÈ›i că este posibil ca derularea înapoi să nu fie posibilă în funcÈ›ie +de implementarea lui \fBmore\fP(1). Acest lucru se datorează faptului că +\fBxzmore\fP utilizează o conductă pentru a transmite datele decomprimate către +\fBmore\fP(1). \fBxzless\fP(1) utilizează \fBless\fP(1) care oferă caracteristici mai +avansate. +.PP +Comanda \fBlzmore\fP este furnizată pentru compatibilitate retroactivă cu LZMA +Utils. Aceasta este depreciată È™i va fi eliminată într\-o versiune viitoare. +. +.SH "VARIABILE DE MEDIU" +.TP +.\" TRANSLATORS: Don't translate the uppercase PAGER. +.\" It is a name of an environment variable. +\fBPAGER\fP +Dacă variabila de mediu \fBPAGER\fP, este definită, valoarea sa este utilizată +ca paginator în loc de \fBmore\fP(1). +. +.SH "CONSULTAÈšI ȘI" +\fBmore\fP(1), \fBxz\fP(1), \fBxzless\fP(1), \fBzmore\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sr/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/sr/lzmainfo.1 new file mode 100644 index 000000000..600a0dc79 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sr/lzmainfo.1 @@ -0,0 +1,42 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Serbian translation of xz-man. +.\" МироÑлав Ðиколић , 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 30.06.2013. Tukaani "XZ Utils" +.SH ÐÐЗИВ +lzmainfo – приказује информације Ñмештене у заглављу .lzma датотеке +.SH СÐЖЕТÐК +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fIдатотека...\fP] +.SH ОПИС +\fBlzmainfo\fP приказује информације које Ñе налазе у заглављу \fB.lzma\fP +датотеке. Чита првих 13 бајтова из наведене \fIдатотеке\fP, дешифрује заглавље +и иÑпиÑује га на Ñтандардни излаз у облику читљивом људима. Ðко ни једна +\fIдатотека\fP није дата или је \fIдатотека\fP \fB\-\fP, чита Ñе Ñтандардни улаз. +.PP +Обично најзанимљивије информације Ñу незапакована величина и величина +речника. Ðезапакована величина може Ñе приказати Ñамо ако је датотека у +варијанти формата \fB.lzma\fP која није ток. Количина меморије потребне за +раÑпакивање датотеке је неколико деÑетина килобајта Ð¿Ð»ÑƒÑ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° речника. +.PP +\fBlzmainfo\fP је Ñадржано у XZ Utils\-у првенÑтвено због повратне ÑаглаÑноÑти +Ñа LZMA Utils\-ом. +.SH "СТÐЊЕ ИЗЛÐЗÐ" +.TP +\fB0\fP +Све је у реду. +.TP +\fB1\fP +Дошло је до грешке. +.SH ГРЕШКЕ +\fBlzmainfo\fP кориÑти \fBMB\fP док тачан ÑÑƒÑ„Ð¸ÐºÑ Ñ‚Ñ€ÐµÐ±Ð° да буде \fBMiB\fP (2^20 +бајтова). Ово је зато да би Ñе задржала ÑаглаÑноÑÑ‚ излаза Ñа LZMA Utils\-ом. +.SH "ВИДИТЕ ТÐКОЂЕ" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sr/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/sr/xz.1 new file mode 100644 index 000000000..82d831001 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sr/xz.1 @@ -0,0 +1,1928 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Serbian translation of xz-man. +.\" МироÑлав Ðиколић , 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 08.03.2025. Tukaani "XZ Utils" +. +.SH ÐÐЗИВ +xz, unxz, xzcat, lzma, unlzma, lzcat – Запакује или раÑпакује „.xz“ и „.lzma +датотеке +. +.SH СÐЖЕТÐК +\fBxz\fP [\fIопција...\fP] [\fIдатотека...\fP] +. +.SH "ÐЛИЈÐСИ ÐÐРЕДБЕ" +\fBunxz\fP је иÑто као и \fBxz \-\-decompress\fP. +.br +\fBxzcat\fP је иÑто као и \fBxz \-\-decompress \-\-stdout\fP. +.br +\fBlzma\fP је иÑто као и \fBxz \-\-format=lzma\fP. +.br +\fBunlzma\fP је иÑто као и \fBxz \-\-format=lzma \-\-decompress\fP. +.br +\fBlzcat\fP је иÑто као и \fBxz \-\-format=lzma \-\-decompress \-\-stdout\fP. +.PP +Приликом пиÑања Ñкрипти које треба да раÑпакују датотеке, препоручује Ñе да +Ñе увек кориÑти назив \fBxz\fP Ñа одговарајућим аргументима (\fBxz \-d\fP или \fBxz \-dc\fP) умеÑто назива \fBunxz\fP и \fBxzcat\fP. +. +.SH ОПИС +\fBxz\fP је алат опште употребе за запакивање података Ñа ÑинтакÑом линије +наредби Ñличан као \fBgzip\fP(1) и \fBbzip2\fP(1). Изворни формат датотеке је +\&\fB.xz\fP формат, али Ñтари \fB.lzma\fP формат који кориÑти LZMA Utils и Ñирови +запаковани токови без заглавља формата Ñу такође подржани. Уз то, +раÑпакивање \fB.lz\fP формата који кориÑти \fBlzip\fP је подржано. +.PP +\fBxz\fP запакује или раÑпакује Ñваку \fIдатотеку\fP у Ñкладу Ñа изабраним режимом +рада. Ðко није дата ни једна \fIдатотека\fP или је датотека \fIfile\fP \fB\-\fP, +\fBxz\fP чита Ñа Ñтандардног улаза и запиÑује обрађене податке на Ñтандардни +излаз. \fBxz\fP ће одбити (приказаће грешку и преÑкочити \fIдатотеку\fP) да пише +запаковане податке на Ñтандардни излаз ако је то терминал. Слично, \fBxz\fP ће +одбити да чита запаковане податке Ñа Ñтандардног улаза ако је то терминал. +.PP +ОÑим ако није наведено \fB\-\-stdout\fP, \fIдатотеке\fP које ниÑу \fB\-\fP Ñе пишу у +нову датотеку чији назив је проиÑтекао из назива изворне \fIдатотеке\fP: +.IP \(bu 3 +Приликом запакивања, ÑÑƒÑ„Ð¸ÐºÑ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° циљне датотеке (\fB.xz\fP или \fB.lzma\fP) Ñе +додаје на назив изворне датотеке да би Ñе добио назив циљне датотеке. +.IP \(bu 3 +Приликом раÑпакивања, ÑÑƒÑ„Ð¸ÐºÑ \fB.xz\fP, \fB.lzma\fP или \fB.lz\fP Ñе уклања из назива +датотеке да би Ñе добио назив циљне датотеке. \fBxz\fP такође препознаје +ÑуфикÑе \fB.txz\fP и \fB.tlz\fP и замењује их ÑуфикÑом \fB.tar\fP. +.PP +Ðко циљна датотека већ пÑтоји, приказује Ñе грешка а \fIдатотека\fP Ñе +преÑкаче. +.PP +ОÑим ако не пише на Ñтандардни излаз, \fBxz\fP ће приказати упозорење и +преÑкочити \fIдатотеку\fP ако Ñе нешто од Ñледећег примењује: +.IP \(bu 3 +\fIДатотека\fP није обична датотека. Симболичке везе Ñе не прате, и Ñтога Ñе +не Ñматра да Ñу обичне датотеке. +.IP \(bu 3 +\fIДатотека\fP има више од једне чврÑте везе. +.IP \(bu 3 +\fIДатотека\fP има поÑтављен „setuid, setgid“ или лепљиви бит. +.IP \(bu 3 +Режим рада је поÑтављен на запакивање а \fIдатотека\fP већ има ÑÑƒÑ„Ð¸ÐºÑ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° +циљне датотеке (\fB.xz\fP или \fB.txz\fP приликом запакивања у \fB.xz\fP формат, а +\&\fB.lzma\fP или \fB.tlz\fP приликом запакивања у \fB.lzma\fP формат). +.IP \(bu 3 +Режим радње је поÑтављен за раÑпакивање а \fIдатотека\fP нема ÑÑƒÑ„Ð¸ÐºÑ Ð½Ð¸ једног +од подржаних формата датотеке (\fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP или +\&\fB.lz\fP). +.PP +Ðакон уÑпешног Ñажимања или раÑпакивања \fIдатотеке\fP, \fBxz\fP умножава +влаÑника, групу, дозволе, време приÑтупа и време измене из изворне +\fIдатотеке\fP у циљну датотеку. Ðко умножавање групе не уÑпе, дозволе Ñу +измењене тако да циљна датотека не поÑтане доÑтупна кориÑницима који ниÑу +имали дозволу за приÑтуп изворној \fIдатотеци\fP. \fBxz\fP не подржава умножавање +других метаподатака попут ÑпиÑка контрола приÑтупа или проширених атрибута. +.PP +Једном када је циљна датотека уÑпешно затворена, изворна \fIдатотека\fP Ñе +уклања оÑим ако Ñе \fB\-keep\fP не наведе. Изворна \fIдатотека\fP Ñе никада не +уклања ако Ñе излаз пише на Ñтандардни излаз или ако дође до грешке. +.PP +Слање \fBSIGINFO\fP или \fBSIGUSR1\fP ка \fBxz\fP процеÑу чини да иÑпише информације +напредовања на Ñтандардну грешку. Ово има ограничено коришћење Ñве док +Ñтандардна грешка јеÑте терминал, коришћење \fB\-\-verbose\fP приказаће +аутоматÑки указивач напретка оÑвежавања. +. +.SS "Коришћење меморије" +Коришћење меморије \fBxz\fP Ñе мења од неколико Ñтотина килобајта до неколико +гигабајта у завиÑноÑти од поÑтавки запакивања. ПоÑтавке коришћене приликом +запакивања датотеке одређују захтеве меморије раÑпакивача. Обично +раÑпакивачу треба 5\ % до 20\ % количине меморије која је потребна +запакивачу приликом прављења датотеке. Ðа пример, раÑпакивање датотеке +направљене Ñа \fBxz \-9\fP тренутно захтева 65\ MiB меморије. Још увек, могуће +је имати \fB.xz\fP датотеке које захтевају неколико гигабајта меморије за +раÑпакивање. +.PP +Ðарочито кориÑници Ñтаријих ÑиÑтема могу наћи доÑадном могућноÑÑ‚ коришћења +врло велике меморије. Да би Ñе Ñпречила нежељена изненађења, \fBxz\fP има +уграђен ограничавач коришћења меморије, који је иÑкључен по оÑнови. Док +неки оперативни ÑиÑтеми пружају начин за ограничавање коришћење меморије за +процеÑе, оÑлањање на то Ñматра Ñе да није довољно прилагодљиво (на пример, +коришћење \fBulimit\fP(1) за ограничавање виртуелне меморије тежи да обогаљи +\fBmmap\fP(2)). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +Ограничавач коришћења меморије Ñе може укључити опцијом линије наредби +\fB\-\-memlimit=\fP\fIограничење\fP. ЧеÑто је најпогодније укључити ограничавач по +оÑнови поÑтављањем променљиве окружења \fBXZ_DEFAULTS\fP, на пример, +\fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP. Могуће је поÑтавити ограничења заÑебно за +запакивање и раÑпакивање коришћењем \fB\-\-memlimit\-compress=\fP\fIограничење\fP и +\fB\-\-memlimit\-decompress=\fP\fIограничење\fP. Коришћење ове две опције ван +\fBXZ_DEFAULTS\fP је ретко кориÑно јер једно покретање \fBxz\fP не може да ради и +запакивање и раÑпакивање а \fB\-\-memlimit=\fP\fIограничење\fP (или \fB\-M\fP +\fIограничење\fP) је краће за куцање на линији наредби. +.PP +Ðко је прекорачено наведено ограничење коришћења меморије, \fBxz\fP ће +приказати грешку а раÑпакивање датотеке неће уÑпети. Ðко је ограничење +прекорачено приликом запакивања, \fBxz\fP ће покушати да умањи поÑтавке тако да +Ñе ограничење више не прекорачује (оÑи када Ñе кориÑти \fB\-\-format=raw\fP или +\fB\-\-no\-adjust\fP). Ðа тај начин радња неће бити неуÑпешна оÑим ако је +ограничење врло мало. Смањење поÑтавке Ñе ради у корацима који Ñе не +подударају Ñа предподешеноÑтима нивоа запакивања, на пример, ако је +ограничење Ñамо незнатно мање од изноÑа потребног за \fBxz \-9\fP, поÑтавке ће +бити Ñмањене Ñамо мало, а не Ñве до \fBxz \-8\fP. +. +.SS "Ðадовезивање и попуњавање Ñа „.xz“ датотекама" +Могуће је додати \fB.xz\fP датотеке као то. \fBxz\fP ће раÑпаковати такве +датотеке као да Ñу биле једна \fB.xz\fP датотека. +.PP +Могуће је уметнути попуњавање између придодатих делова или након поÑледњег +дела. Попуњавање мора да Ñе ÑаÑтоји од празних бајтова а величина +попуњавања мора бити умножак четири бајта. Ово може бити кориÑно, на +пример, ако је \fB.xz\fP датотека Ñмештена на медијуму који мери величине +датотека у блоковима од 512 бајтова. +.PP +Ðадовезивање и попуњавање ниÑу дозвољени Ñа \fB.lzma\fP датотекама или Ñировим +токовима. +. +.SH ОПЦИЈЕ +. +.SS "СуфикÑи целог броја и Ñпецијалне вредноÑти" +Ðа већини меÑта где Ñе очекује аргумент целог броја, опционални ÑÑƒÑ„Ð¸ÐºÑ Ñ˜Ðµ +подржан да би Ñе лако назначили велики цели бројеви. Ðе Ñме бити размака +између целог броја и ÑуфикÑа. +.TP +\fBKiB\fP +Множи цео број Ñа 1.024 (2^10). \fBKi\fP, \fBk\fP, \fBkB\fP, \fBK\fP, и \fBKB\fP Ñе +прихватају као Ñиноними за \fBKiB\fP. +.TP +\fBMiB\fP +Множи цео број Ñа 1.048.576 (2^20). \fBMi\fP, \fBm\fP, \fBM\fP, и \fBMB\fP Ñе +прихватају као Ñиноними за \fBMiB\fP. +.TP +\fBGiB\fP +Множи цео број Ñа 1.073.741.824 (2^30). \fBGi\fP, \fBg\fP, \fBG\fP, и \fBGB\fP Ñе +прихватају као Ñиноними за \fBGiB\fP. +.PP +ПоÑебна вредноÑÑ‚ \fBmax\fP Ñе може кориÑтити да укаже на највећу вредноÑÑ‚ целог +броја подржану опцијом. +. +.SS "Режим рада" +Ðко је дато више опција режима рада, поÑледња има дејÑтва. +.TP +\fB\-z\fP, \fB\-\-compress\fP +Запакује. Ово је оÑновни режим радње када није наведена опција режима радње +и ниједан други режим радње Ñе не подразумева Ñа линије радње (на пример, +\fBunxz\fP подразумева \fB\-\-decompress\fP). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Ðакон уÑпешног запакивања, изворна датотека Ñе уклања оÑим ако Ñе не пише на +Ñтандардни излаз или је наведено \fB\-\-keep\fP. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +РаÑпакује. Ðакон уÑпешног раÑпакивања, изворна датотека Ñе уклања оÑим ако +Ñе не пише на Ñтандардни излаз или је наведено \fB\-\-keep\fP. +.TP +\fB\-t\fP, \fB\-\-test\fP +ТеÑтира целовитоÑÑ‚ запакованих \fIдатотека\fP. Ова опција је иÑто што и +\fB\-\-decompress \-\-stdout\fP оÑим тога што Ñе раÑпаковани подаци одбацују умеÑто +да Ñе пишу на Ñтандардни излаз. Датотеке Ñе не праве нити уклањају. +.TP +\fB\-l\fP, \fB\-\-list\fP +ИÑпиÑује информације о запакованим \fIдатотекама\fP. Ðикакав незапакован излаз +Ñе не добија, а ниједна датотека није направљена или уклоњена. У режиму +ÑпиÑка, програм не може читати запаковане податке Ñа Ñтандардног улаза или +из других нетраживих извора. +.IP "" +ОÑновни ÑпиÑак приказује оÑновне информације о \fIдатотекама\fP, једна датотека +у једном реду. Да добијете подробније информације, кориÑтите такође опцију +\fB\-\-verbose\fP. За чак и више информација, кориÑтите \fB\-\-verbose\fP два пуа, +али знајте да то може бити Ñпоро, јер да би Ñе добиле Ñве додатне +информације потребно је много тражења. Ширина опширног излаза премашује 80 +знакова, тако да преÑпајање излаза на, на пример, \fBless\ \-S\fP може бити +прикладно ако терминал није довољно широк. +.IP "" +Тачан излаз може варирати између \fBxz\fP издања и различитих језика. За излаз +читљив машинама треба да кориÑтите \fB\-\-robot \-\-list\fP. +. +.SS "Измењивачи рада" +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ðе брише улазне датотеке. +.IP "" +Од \fBxz\fP 5.2.6, ова опција такође чини да \fBxz\fP запакује или раÑпакује чак и +ако је улаз Ñимболичка веза ка обичној датотеци, има више од једне чврÑте +везе или има поÑтављен „setuid“, „setgid“ или лепљиви бит. „setuid“, +„setgid“ и лепљиви битови Ñе не умножавају у циљну датотеку. У ранијим +издањима ово Ñе могло урадити Ñамо Ñа \fB\-\-force\fP. +.TP +\fB\-f\fP, \fB\-\-force\fP +Ова опција има неколико дејÑтава: +.RS +.IP \(bu 3 +Ðко циљна датотека већ поÑтоји, брише је пре запакивања или раÑпакивања. +.IP \(bu 3 +Запакује или раÑпакује чак и ако је улаз Ñимболичка веза ка обичној +датотеци, има више од једне чврÑте везе или има поÑтављен „setgid“, „setgid“ +или лепљиви бит. „setgid“, „setgid“ или лепљиви бит Ñе не умножавају у +циљну датотеку. +.IP \(bu 3 +Када Ñе кориÑти Ñа \fB\-\-decompress\fP \fB\-\-stdout\fP и \fBxz\fP не може да препозна +врÑту изворне датотеке, умножава изворну датотеку као такву на Ñтандардни +излаз. Ово омогућава да Ñе \fBxzcat\fP \fB\-\-force\fP кориÑти као \fBcat\fP(1) за +датотекекоје ниÑу запаковане Ñа \fBxz\fP. Знајте да ће у будућноÑти, \fBxz\fP +моћи да подржава нове формате запаковане датотеке, који могу учинити да +\fBxz\fP раÑпакује још врÑта датотека умеÑто да их умножи какве јеÑу на +Ñтандардни излаз. \fB\-\-format=\fP\fIформат\fP Ñе може кориÑтити да ограничи \fBxz\fP +да раÑпакује Ñамо формат једне датотеке. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Пише запаковане или раÑпаковане податке на Ñтандардни излаз умеÑто у +датотеку, Ово подразумева \fB\-\-keep\fP. +.TP +\fB\-\-single\-stream\fP +РаÑпакује Ñамо први \fB.xz\fP ток, и тихо занемарује могуће преоÑтале улазне +податке који Ñледе ток. Ðормално такво пратеће Ñмеће чини да \fBxz\fP прикаже +грешку. +.IP "" +\fBxz\fP никада не раÑпакује више од једног тока из \fB.lzma\fP датотека или +Ñирових токова, али ова опција чини да \fBxz\fP још увек занемари могуће +пратеће податке након \fB.lzma\fP датотеке или Ñировог тока. +.IP "" +Ова опција нема дејÑтва ако режим рада није \fB\-\-decompress\fP или \fB\-\-test\fP. +.IP "" +Од \fBxz\fP 5.7.1alpha, \fB\-\-single\-stream\fP подразумева \fB\-\-keep\fP. +.TP +\fB\-\-no\-sparse\fP +ИÑкључује Ñтварање развучених датотека. По оÑнови, ако раÑпакује у обичну +датотеку, \fBxz\fP покушава да учини датотеку развученом ако раÑпаковани подаци +Ñадрже дуге низове бинарних нула. Такође ради приликом пиÑања на Ñтандардни +излаз Ñве док је Ñтандардни излаз повезан Ñа обичном датотеком а одређени +додатни уÑлови Ñу иÑпуњени да је учине безбедном. Стварање развучених +датотека може уштедети проÑтор на диÑку и убрзати раÑпакивање Ñмањењем +количине У/И диÑка. +.TP +\fB\-S\fP \fI.suf\fP, \fB\-\-suffix=\fP\fI.suf\fP +Приликом запакивања, кориÑтите \fI.suf\fP као ÑÑƒÑ„Ð¸ÐºÑ Ð·Ð° циљну датотеку умеÑто +\&\fB.xz\fP или \fB.lzma\fP. Ðко Ñе не пише на Ñтандардни излаз а изворна датотека +већ има ÑÑƒÑ„Ð¸ÐºÑ \fI.suf\fP, приказује Ñе упозорење и датотека Ñе преÑкаче. +.IP "" +Приликом раÑпакивања, препознаје датотеке Ñа ÑуфикÑом \fI.suf\fP поред датотека +Ñа ÑуфикÑом \fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP, or \fB.lz\fP. Ðко изворна +датотека има ÑÑƒÑ„Ð¸ÐºÑ \fI.suf\fP, ÑÑƒÑ„Ð¸ÐºÑ Ñе уклања да би Ñе добио назив циљне +датотеке. +.IP "" +Приликом запакивања или раÑпакивања Ñирових токова (\fB\-\-format=raw\fP), ÑÑƒÑ„Ð¸ÐºÑ +мора увек бити наведен оÑим ако Ñе не пише на Ñтандардни излаз, јер не +поÑтоји оÑновни ÑÑƒÑ„Ð¸ÐºÑ Ð·Ð° Ñирове токове. +.TP +\fB\-\-files\fP[\fB=\fP\fIдатотека\fP] +Чита називе датотека за обраду из \fIдатотеке\fP; ако Ñе \fIдатотека\fP изоÑтави, +називи датотека Ñе читају Ñа Ñтандардног улаза. Ðазиви датотека Ñе морају +завршавати знаком новог реда. Цртица (\fB\-\fP) Ñе узима као редован назив +датотеке; а не Ñтандардни улаз. Ðко Ñу називи датотека дати такође као +аргументи линије наредби, обрађују Ñе пре него што Ñе називи датотека +прочитају из \fIдатотеке\fP. +.TP +\fB\-\-files0\fP[\fB=\fP\fIдатотека\fP] +Ово је иÑто као и \fB\-\-files\fP[\fB=\fP\fIдатотека\fP] изузев тога што Ñваки назив +датотеке мора да Ñе завршава „null“ знаком. +. +.SS "ОÑновни формат датотеке и опције запакивања" +.TP +\fB\-F\fP \fIформат\fP, \fB\-\-format=\fP\fIформат\fP +Ðаводи \fIформат\fP датотеке за запакивање или раÑпакивање: +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +Ово је оÑновно. Приликом запакивања, \fBauto\fP је иÑто што и \fBxz\fP. Приликом +раÑпакивања, формат улазне датотеке Ñе аутоматÑки препознаје. Знајте да +Ñирови токови (направљени Ñа \fB\-\-format=raw\fP) не могу бити аутоматÑки +препознати. +.TP +\fBxz\fP +Пакује у \fB.xz\fP формат датотеке, или прихвата Ñамо \fB.xz\fP датотеке приликом +раÑпакивања. +.TP +\fBlzma\fP, \fBalone\fP +Пакује у Ñтари \fB.lzma\fP формат датотеке, или прихвата Ñамо \fB.lzma\fP датотеке +приликом раÑпакивања. Ðлтернативни назив \fBalone\fP Ñе доÑтавља зарад +повратне ÑаглаÑноÑти Ñа LZMA помагалима. +.TP +\fBlzip\fP +Прихвата Ñамо \fB.lz\fP датотеке приликом раÑпакивања. Запакивање није +подржано. +.IP "" +Формат \fB.lz\fP издања 0 и 1 је подржан. Датотеке издања 0 Ñу наÑтале Ñа +\fBlzip\fP 1.3 и Ñтаријим. Такве датотеке ниÑу уобичајене али Ñе могу наћи у +архивама датотека јер је неколико пакета извора издато у овом формату. +Такође можда неко има Ñтаре личне датотеке у овом формату. Подршка +раÑпакивања за формат издања 0 је уклоњена у \fBlzip\fP 1.18. \fBlzip\fP 1.4 и +новији Ñтвара датотеке у формату издања 1. +.TP +\fBraw\fP +Запакује или раÑпакује Ñирови ток (без заглавља). Ово је замишљено Ñамо за +напредне кориÑнике. Да дешифрујете Ñирове токове, треба да кориÑтите +\fB\-\-format=raw\fP и да изричито наведете ланац филтера, што би обично требало +да буде Ñмештено у заглављима контејнера. +.RE +.TP +\fB\-C\fP \fIпровера\fP, \fB\-\-check=\fP\fIпровера\fP +Ðаводи врÑту провере целовитоÑти. Провера Ñе израчунава из незапакованих +података и Ñмештених у \fB.xz\fP датотеци. Ова опција има дејÑтва Ñамо +приликом запакивања у \fB.xz\fP формат; \fB.lzma\fP формат не подржава провере +целовитоÑти. Провера целовитоÑти (ако је има) Ñе проверава када је \fB.xz\fP +датотека раÑпакована. +.IP "" +Подржане врÑте \fIпровере\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +Уопште не израчунава проверу целовитоÑти. Ово је обично лоша идеја. Ово +може бити кориÑно када Ñе целовитоÑÑ‚ података ипак проверава на друге +начине. +.TP +\fBcrc32\fP +Израчунава CRC32 кориÑтећи полином из IEEE\-802.3 (Етернет). +.TP +\fBcrc64\fP +Израчунава CRC64 кориÑтећи полином из ECMA\-182. Ово је оÑновно, јер је +незнатно боље од CRC32 у откривању оштећених датотека а разлика брзине је +занемарљива. +.TP +\fBsha256\fP +Израчунава SHA\-256. Ово је нешто Ñпорије од CRC32 и CRC64. +.RE +.IP "" +ЦеловитоÑÑ‚ \fB.xz\fP заглавља Ñе увек проверава Ñа CRC32. Ðе може Ñе изменити +нити иÑкључити. +.TP +\fB\-\-ignore\-check\fP +Ðе проверава проверу целовитоÑти запакованих података приликом раÑпакивања. +CRC32 вредноÑти у \fB.xz\fP заглављима биће још увек нормално проверене. +.IP "" +\fBÐемојте кориÑтити ову опцију оÑим ако Ñтварно знате шта радите.\fP Могући +разлози за коришћење ове опције: +.RS +.IP \(bu 3 +Покушава да опорави податке из оштећене „.xz“ датотеке. +.IP \(bu 3 +Убрзава раÑпакивање. Ово има значаја углавном Ñа SHA\-256 или Ñа датотекама +које Ñу запаковане Ñтварно добро. Препоручује Ñе да не кориÑтите ову опцију +за ову Ñврху оÑим ако је целовитоÑÑ‚ датотеке проверена Ñпоља на неки други +начин. +.RE +.TP +\fB\-0\fP ... \fB\-9\fP +Бира ниво преподешеноÑти запакивања. Подразумевано је \fB\-6\fP. Ðко је +наведено више нивоа преподешеноÑти, поÑледња има дејÑтва. Ðко је произвољни +ланац филтера већ наведен, поÑтављање нивоа преподешеноÑти запакивања уклања +произвољни ланац филтера. +.IP "" +Разлике између предподешеноÑти Ñу још значајније него Ñа \fBgzip\fP(1) и +\fBbzip2\fP(1). Изабране поÑтавке запакивања одређују захтеве меморије +раÑпакивача, Ñтога коришћење превиÑоког нивоа предподешеноÑти може отежати +раÑпакивање датотеле на Ñтаром ÑиÑтему Ñа мало RAM\-а. Ðарочито, \fBније добра замиÑао Ñлепо кориÑтити \-9 за било шта\fP као што је чеÑто Ñа \fBgzip\fP(1) +и \fBbzip2\fP(1). +.RS +.TP +\fB\-0\fP ... \fB\-3\fP +Ово Ñу некако брзе предподешеноÑти. \fB\-0\fP је понекад брже од \fBgzip \-9\fP док +запакује много боље. Оне више чеÑто имају брзину упоредиву Ñа \fBbzip2\fP(1) +Ñа упоредивом или бољом Ñтопом запакивања, иако резултати завиÑе много од +врÑте података који Ñе запакују. +.TP +\fB\-4\fP ... \fB\-6\fP +Добро до врло добро запакивање које одржава коришћење меморије раÑпакивача +разумним чак и за Ñтаре ÑиÑтеме. \fB\-6\fP је оÑновно, што је обично добар +избор за раÑподелу датотека које треба да могу да Ñе раÑпакују чак и на +ÑиÑтемима Ñа Ñамо 16\ MiB RAM\-а. (\fB\-5e\fP или \fB\-6e\fP може бити вредно +узимања у обзир. Видите \fB\-\-extreme\fP.) +.TP +\fB\-7 ... \-9\fP +Као \fB\-6\fP али Ñа већим захтевима меморије запакивача и раÑпакивача. КориÑне +Ñу Ñамо приликом запакивања датотека већих од 8\ MiB, 16\ MiB и 32\ MiB. +.RE +.IP "" +Ðа иÑтом хардверу, брзина раÑпакивања је приближно Ñталан број бајтова +запакованих података у Ñекунди. Другим речима, биће боље запакивање, брже +раÑпакивање. То такође значи да количина незапакованог излаза произведеног +у Ñекунди може много да Ñе разликује. +.IP "" +Следећа табела резимира функције предподешеноÑти: +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +ПреподешеноÑÑ‚;ВлчРчнка;ЗапакЦПЈ;ЗапакМем;РаÑпМем +\-0;256 KiB;0;3 MiB;1 MiB +\-1;1 MiB;1;9 MiB;2 MiB +\-2;2 MiB;2;17 MiB;3 MiB +\-3;4 MiB;3;32 MiB;5 MiB +\-4;4 MiB;4;48 MiB;5 MiB +\-5;8 MiB;5;94 MiB;9 MiB +\-6;8 MiB;6;94 MiB;9 MiB +\-7;16 MiB;6;186 MiB;17 MiB +\-8;32 MiB;6;370 MiB;33 MiB +\-9;64 MiB;6;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +ОпиÑи колона: +.RS +.IP \(bu 3 +ВлчРчнка је величина LZMA2 речника. Коришћење речника већег од величине +незапаковане датотеке је губитак меморије. Зато је добро избегавати +коришћење предподешеноÑти \fB\-7\fP ... \fB\-9\fP када за њима нема Ñтварне +потребе. Са \fB\-6\fP и нижим, количина изгубљене меморије је обично довољно +ниÑка да нема значаја. +.IP \(bu 3 +ЗапакЦПЈ је поједноÑтављено предÑтављање LZMA2 поÑтавки које утичу на брзину +запакивања. Величина речника такође утиче на брзину, тако док је ЗапакЦПЈ +иÑто за нивое \fB\-6\fP ... \fB\-9\fP, виши нивои још увек теже да буду Ñпорији. Да +добијете још Ñпорије и Ñамим тим можда боље запакивање, видите \fB\-\-extreme\fP. +.IP \(bu 3 +ЗапакМем Ñадржи захтеве меморије запакивача у режиму једне нити. Може +незнатно да Ñе разликује између \fBxz\fP издања. +.IP \(bu 3 +РаÑпМем Ñадржи захтеве меморије раÑпакивача. Тако је, поÑтавке запакивања +одређују захтеве меморије раÑпакивача. Тачно коришћење меморије раÑпакивача +је незнатно веће од величине LZMA2 речника, али Ñу вредноÑти у табели +заокружене на Ñледећи цео MiB. +.RE +.IP "" +Захтеви меморије режима Ñа више нити Ñу значајно већи него ли режима једне +нити. Са оÑновном вредношћу \fB\-\-block\-size\fP, Ñвакој нити треба 3*3*ВлчРчнка +Ð¿Ð»ÑƒÑ Ð—Ð°Ð¿Ð°ÐºÐœÐµÐ¼ или РаÑпМем. Ðа пример, за четири нити Ñа предподешавањем +\fB\-6\fP потребно је 660\(en670\ MiB меморије. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +КориÑтите Ñпорију варијанту изабраног нивоа предподешеноÑти запакивања +(\fB\-0\fP ... \fB\-9\fP) у нади да ћете добити мало бољу Ñтопу запакивања, али уз +лошу Ñрећу ово је може учинити гором. Ðе утиче на коришћење меморије +раÑпакивача, али Ñе коришћење меморије запакивача мало повећава на нивоима +предподешеноÑти \fB\-0\fP ... \fB\-3\fP. +.IP "" +Како поÑтоје две предподешеноÑти Ñа величинама речника од 4\ MiB и 8\ MiB, +предподешеноÑти \fB\-3e\fP и \fB\-5e\fP кориÑте незнатно брже поÑтавке (ниже +CompCPU) него \fB\-4e\fP и \fB\-6e\fP. Ðа тај начин нема две иÑтоветне +предподешеноÑти. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +ПреподешеноÑÑ‚;ВлчРчнка;ЗапакЦПЈ;ЗапакМем;РаÑпМем +\-0e;256 KiB;8;4 MiB;1 MiB +\-1e;1 MiB;8;13 MiB;2 MiB +\-2e;2 MiB;8;25 MiB;3 MiB +\-3e;4 MiB;7;48 MiB;5 MiB +\-4e;4 MiB;8;48 MiB;5 MiB +\-5e;8 MiB;7;94 MiB;9 MiB +\-6e;8 MiB;8;94 MiB;9 MiB +\-7e;16 MiB;8;186 MiB;17 MiB +\-8e;32 MiB;8;370 MiB;33 MiB +\-9e;64 MiB;8;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Ðа пример, има укупно четири предподешавања која кориÑте 8\ MiB речник, чији +поредак од најбржег до најÑпоријег је \fB\-5\fP, \fB\-6\fP, \fB\-5e\fP и \fB\-6e\fP. +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +Ово Ñу помало погрешни алијаÑи за \fB\-0\fP и \fB\-9\fP. ДоÑтављени Ñу Ñамо зарад +повратне ÑаглаÑноÑти Ñа LZMA Utils\-ом. Избегавајте коришћење ових опција. +.TP +\fB\-\-block\-size=\fP\fIвеличина\fP +Приликом запакивања у \fB.xz\fP формат, дели улазне податке на блокове +\fIвеличина\fP бајта. Блокови Ñе запакују незавиÑно један од другог, што +помаже у раду Ñа више нити и чини ограничено раÑпакивање наÑумичног приÑтупа +могућим. Ова опција Ñе обично кориÑти да Ñе препише оÑновна величина блока +у режиму Ñа више нити, али Ñе ова опција може такође кориÑтити и у режиму +једне нити. +.IP "" +У режиму више нити око три пута \fIвеличина\fP бајтова биће додељено у Ñвакој +нити за међумемориÑање улаза и излаза. ОÑновна \fIвеличина\fP је три пута +величине LZMA2 речника или 1 MiB, шта год да је више. Обично добра вредноÑÑ‚ +је 2\(en4 пута величина LZMA2 речника или барем 1 MiB. Коришћење +\fIвеличине\fP мање од величине LZMA2 речника је трошење RAM\-а јер тада +међумеморија LZMA2 речника никада неће бити потпуно коришћена. У режиму +више нити, величине блокова Ñе чувају у заглављима блока. Ова информација +величине је потребна за раÑпакивање Ñа више нити. +.IP "" +У режиму једне нити никаква подела блока Ñе не ради по оÑнови. ПоÑтављање +ове опције не утиче на коришћење меморије. Ðикакве информације о величини +Ñе не чувају у заглављима блока, Ñтога датотеке направљене у режиму једне +нити неће бити иÑте као датотеке направљене у режиму више нити. ÐедоÑтатак +информација о величини такође значи да \fBxz\fP неће моћи да раÑпакује датотеке +у режиму више нити. +.TP +\fB\-\-block\-list=\fP\fIÑтавке\fP +Приликом запакивања у \fB.xz\fP формат, почиње нови блок Ñа изборним +произвољним ланцем филтера након датих интервала незапакованих података. +.IP "" +\fIСтавке\fP Ñу ÑпиÑак одвојен зарезом. Свака Ñтавка Ñе ÑаÑтоји од изборног +броја ланца филтера између 0 и 9 за којим Ñледи двотачка (\fB:\fP) и захтевана +величина незапакованих података . ИзоÑтављање неке Ñтавке (два или више +узаÑтопна зареза) је пречица за коришћење величине и филтера претходне +Ñтавке. +.IP "" +Ðко је улазна датотека већа од збира величина у \fIÑтавкама\fP, поÑледња Ñтавка +Ñе понавља Ñве до краја датотеке. Специјална вредноÑÑ‚ \fB0\fP може Ñе +кориÑтити као поÑледња величина да назначи да оÑтатак датотеке треба да буде +шифрован као један блок. +.IP "" +Ðлтернативни ланац филтера за Ñваки блок Ñе може навеÑти у комбинацији Ñа +опцијама \fB\-\-filters1=\fP\fIфилтера\fP \&...\& \fB\-\-filters9=\fP\fIфилтери\fP. Ове +опције дефинишу ланце филтера Ñа одредником између 1\(en9. Ланац филтера 0 +Ñе може кориÑтити да упућује на оÑновно ланац филтера, који је иÑти јер Ñе +ланац филтера не наводи. Одредник ланца филтера Ñе може кориÑтити пре +незапаковане величине, за којим Ñледи двотачка (\fB:\fP). Ðа пример, ако +наведемо \fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP тада ће Ñе за +прављење блокова кориÑтити: +.RS +.IP \(bu 3 +Ланац филтера наведен Ñа \fB\-\-filters1\fP и 2 MiB улазом +.IP \(bu 3 +Ланац филтера наведен Ñа \fB\-\-filters3\fP и 2 MiB улазом +.IP \(bu 3 +Ланац филтера наведен Ñа \fB\-\-filters2\fP и 4 MiB улазом +.IP \(bu 3 +Ланац филтера наведен Ñа \fB\-\-filters2\fP и 4 MiB улазом +.IP \(bu 3 +ОÑновни ланац филтера и 2 MiB улаз +.IP \(bu 3 +ОÑновни ланац филтера и 4 MiB улаз за Ñваки блок до краја улаза. +.RE +.IP "" +Ðко наведемо величину која премашује величину блока шифрера (било оÑновну +вредноÑÑ‚ у режиму нити или вредноÑÑ‚ наведену Ñа +\fB\-\-block\-size=\fP\fIвеличина\fP), шифрер ће направити додатне блокове док ће +задржати границе наведене у \fIÑтавкама\fP. Ðа пример, ако наведемо +\fB\-\-block\-size=10MiB\fP \fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP а улазна +датотека је 80 MiB, добићемо 11 блокова: 5, 10, 8, 10, 2, 10, 10, 4, 10, 10 +и 1 MiB. +.IP "" +У режиму Ñа више нити величине блокова Ñе чувају у заглављима блока. Ово Ñе +не ради у режиму једне нити, тако да шифровани излаз неће бити иÑтоветан +ономе у режиму Ñа више нити. +.TP +\fB\-\-flush\-timeout=\fP\fIиÑтек_времена\fP +Приликом запакивања, ако је више од \fIвреме_иÑтека\fP милиÑекунди (позитиван +цео број) прошло од претходног иÑпирања и читање више улаза ће блокирати, +Ñви заказани улазни подаци Ñе иÑпирају из шифрера и чине доÑтупним у +излазном току. Ово може бити кориÑно ако је \fBxz\fP коришћен за запакивање +података који Ñу Ñлати преко мреже. Мала вредноÑÑ‚ \fIвременÑког_иÑтека\fP чини +податке доÑтупним на пријемни крај Ñа малим закашњењем, али велика вредноÑÑ‚ +\fIвремена_иÑтека\fP даје бољу Ñтопу запакивања. +.IP "" +Ова функција је иÑкључена по оÑнови. Ðко је ова опција наведена више пута, +поÑледња има дејÑтва. Ðарочита вредноÑÑ‚ \fIвременÑког иÑтека\fP \fB0\fP може Ñе +кориÑтити за изричито иÑкључивање ове функције. +.IP "" +Ова функција је доÑтупна Ñамо на POSIX ÑиÑтемима. +.IP "" +.\" FIXME +\fBОва функција је још увек екÑпериментална.\fP Тренутно \fBxz\fP није погодан за +раÑпакивање тока у реалном времену због начина на који \fBxz\fP ради +међумемориÑање. +.TP +\fB\-\-no\-sync\fP +Ðе уÑклађује циљну датотеку и њену фаÑциклу на Ñмештајном уређају пре +уклањања изворне датотеке. Ово може побољшати учинковитоÑÑ‚ ако Ñе запакује +или раÑпакује много малих датотека. Међутим, ако Ñе ÑиÑтем уруши одмах +након бриÑања, може бити да циљна датотека не буде упиÑана на Ñмештајном +уређају али радња бриÑања јеÑте. У том Ñлучају неће бити доÑтупна ни +оригинална изворна ни циљна датотека. +.IP "" +Ова опција има дејÑтво Ñамо када Ñе \fBxz\fP Ñпрема да уклони изворну +датотеку. У оÑталим Ñлучајевима уÑклађивање Ñе не ради никада. +.IP "" +Синхронизација и \fB\-\-no\-sync\fP Ñу додате у \fBxz\fP 5.7.1alpha. +.TP +\fB\-\-memlimit\-compress=\fP\fIограничење\fP +ПоÑтавља ограничење коришћења меморије запакивања. Ðко је ова опција +наведена више пута, поÑледња Ñтупа у дејÑтво. +.IP "" +Ðко поÑтавке запакивања премаше \fIограничење\fP, \fBxz\fP ће покушати да врати +назад поÑтавке тако да ограничење више није прекорачено и приказаће +обавештење да је урађено аутоматÑко дотеривање. Дотеривања Ñе раде Ñледећим +редом: Ñмањење броја нити, пребацивање на режим једне нити ако чак и једна +нит у режиму више нити премаши \fIограничење\fP и на крају Ñмањење величине +LZMA2 речника. +.IP "" +Приликом запакивања Ñа \fB\-\-format=raw\fP или ако је наведено \fB\-\-no\-adjust\fP, +Ñамо број нити може бити умањен јер може да Ñе уради а да Ñе не делује на +излаз запакованог. +.IP "" +Ðко \fIограничење\fP не може бити задовољено чак и Ñа поравнањима опиÑаним +изнад, приказује Ñе грешка и \fBxz\fP ће изаћи Ñа излазним Ñтањем 1. +.IP "" +\fIОграничење\fP Ñе може навеÑти на више начина: +.RS +.IP \(bu 3 +\fIОграничење\fP може бити апÑолутна величина у бајтима. Коришћење ÑуфикÑа +целог броја као \fBMiB\fP може бити кориÑно. Пример: +\fB\-\-memlimit\-compress=80MiB\fP +.IP \(bu 3 +\fIОграничење\fP Ñе може навеÑти као проценат укупне физичке меморије (RAM). +Ово може бити кориÑно нарочито приликом поÑтављања променљиве окружења +\fBXZ_DEFAULTS\fP у Ñкрпти покретања конзоле која Ñе дели између различитих +рачунара. Ðа тај начин ограничење је аутоматÑки веће на ÑиÑтемима Ñа више +меморије. Пример: \fB\-\-memlimit\-compress=70%\fP +.IP \(bu 3 +\fIОграничење\fP Ñе може вратити на Ñвоју оÑновну вредноÑÑ‚ његовим поÑтављањем +на \fB0\fP. Ово је тренутно иÑто што и поÑтављање \fIограничења\fP на \fBmax\fP (без +ограничења коришћења меморије). +.RE +.IP "" +За \fBxz\fP 32\-бита имамо поÑебан Ñлучај: ако \fIограничење\fP треба да буде преко +\fB4020\ MiB\fP, \fIограничење\fP Ñе поÑтавља на \fB4020\ MiB\fP. Ðли на MIPS32 +кориÑти Ñе \fB2000\ MiB\fP. (Ðа вредноÑти \fB0\fP и \fBmax\fP ово не утиче. Слична +функција не поÑтоји за раÑпакивање.) Ово може бити од помоћи када извршна +од 32\-бита има приÑтуп адреÑном проÑтору од 4\ GiB (2 GiB на MIPS32) док +Ñрећом не чини ништа лоше у оÑталим приликама. +.IP "" +Видите такође одељак \fBКоришћење меморије\fP. +.TP +\fB\-\-memlimit\-decompress=\fP\fIограничење\fP +ПоÑтавља ограничење коришћења меморије за раÑпакивање. Ово такође утиче на +\fB\-\-list\fP режим. Ðко радња није могућа а да Ñе не премаши \fIограничење\fP, +\fBxz\fP ће приказати грешку а раÑпакивање датотеке неће уÑпети. Видите +\fB\-\-memlimit\-compress=\fP\fIограничење\fP за могуће начине о навођењу +\fIограничења\fP. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fIограничење\fP +ПоÑтавља ограничење коришћења меморије за раÑпакивање Ñа више нити. Ово +може утицати Ñамо на број нити; ово никада неће учинити да \fBxz\fP одбије да +раÑпакује датотеке. Ðко је \fIограничење\fP превише ниÑко да омогући било који +рад Ñа више нити, \fIограничење\fP Ñе занемарује а \fBxz\fP ће наÑтавити у режиму +једне нити. Знајте да ако Ñе такође кориÑти \fB\-\-memlimit\-decompress\fP, увек +ће Ñе применити и на режим једне и на режим више нити, и тако да Ñтварно +\fIограничење\fP за више нити никада неће бити више од ограничења поÑтављеног +Ñа \fB\-\-memlimit\-decompress\fP. +.IP "" +У ÑупротноÑти Ñа другим опцијама ограничења коришћења меморије, +\fB\-\-memlimit\-mt\-decompress=\fP\fIограничење\fP има ÑиÑтему Ñпецифично оÑновно +\fIограничење\fP. \fBxz \-\-info\-memory\fP Ñе може кориÑтити да видите тренутну +вредноÑÑ‚. +.IP "" +Ова опција и њена оÑновна вредноÑÑ‚ поÑтоје јер без икаквог ограничења нитни +раÑпакивач ће завршити Ñа додељивањем неразумног изноÑа меморије Ñа неким +улазним датотекама. Ðко је оÑновно \fIограничење\fP превише ниÑко на вашем +ÑиÑтему, Ñлободно повећајте \fIограничење\fP али га никада не поÑтављајте на +вредноÑÑ‚ већу од изноÑа употребљивог RAM\-а јер Ñа одговарајућим улазним +датотекама \fBxz\fP ће покушати да кориÑти тај Ð¸Ð·Ð½Ð¾Ñ Ð¼ÐµÐ¼Ð¾Ñ€Ð¸Ñ˜Ðµ чак и Ñа малим +бројем нити. ОÑтајући без меморије или разменом неће Ñе побољшати +учинковитоÑÑ‚ раÑпакивања. +.IP "" +Видите \fB\-\-memlimit\-compress=\fP\fIограничење\fP за могуће начине за навођење +\fIограничења\fP. ПоÑтављање \fIограничења\fP на \fB0\fP враћа \fIограничење\fP на +ÑиÑтему Ñпецифичну оÑновну вредноÑÑ‚. +.TP +\fB\-M\fP \fIограничење\fP, \fB\-\-memlimit=\fP\fIограничење\fP, \fB\-\-memory=\fP\fIограничење\fP +Ово је иÑто као и навођење \fB\-\-memlimit\-compress=\fP\fIограничење\fP +\fB\-\-memlimit\-decompress=\fP\fIограничење\fP +\fB\-\-memlimit\-mt\-decompress=\fP\fIограничење\fP. +.TP +\fB\-\-no\-adjust\fP +Приказује грешку и излази ако ограничење коришћења меморије не може бити +задовољено без дотеривања поÑтавки које утичу на запаковани излаз. Тако је, +ово Ñпречава \fBxz\fP да промени шифрера из режима више нити у режим једне нити +и да Ñмањи величину LZMA2 речника. Чак и када Ñе ова опција кориÑти број +нити Ñе може Ñмањити да задовољи ограничење коришћења меморије јер то неће +утицати на запаковани излаз. +.IP "" +ÐутоматÑко дотеривање је увек иÑкључено приликом Ñтварања Ñирових токова +(\fB\-\-format=raw\fP). +.TP +\fB\-T\fP \fIнити\fP, \fB\-\-threads=\fP\fIнити\fP +Ðаводи број нити радника за коришћење. ПоÑтављање \fIнити\fP на поÑебну +вредноÑÑ‚ \fB0\fP чини да \fBxz\fP кориÑти онолико нити колико процеÑор на ÑиÑтему +подржава. Стварни број нити може бити мањи од \fIнити\fP ако улазна датотека +није довољно велика за нитиÑање Ñа датим поÑтавкама или ако ће коришћење +више нити премашити ограничење коришћења меморије. +.IP "" +Запакивачи једне нити и више нити дају различите излазе. запакивач једне +нити даће мању величину датотеке али Ñамо излаз из запакивача више нити може +бити раÑпакован коришћењем више нити. ПоÑтављање \fIнити\fP на \fB1\fP кориÑтиће +режим једне нити. ПоÑтављање \fIнити\fP на неку другу вредноÑÑ‚, укључујући +\fB0\fP, кориÑтиће запакивач више нити чак и ако ÑиÑтем подржава Ñамо једну нит +хардвера. (\fBxz\fP 5.2.x је кориÑтио режим једне нити у овој прилици.) +.IP "" +Да кориÑтите вишенитни режим Ñа Ñамо једном нити, поÑтавите \fIнити\fP на +\fB+1\fP. ÐŸÑ€ÐµÑ„Ð¸ÐºÑ \fB+\fP нема дејÑтва Ñа вредноÑтима које ниÑу \fB1\fP. Ограничење +коришћења меморије може још увек учинити да Ñе \fBxz\fP пребаци на режим једне +нити оÑим ако Ñе не кориÑти \fB\-\-no\-adjust\fP. Подршка за Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ \fB+\fP је +додата у \fBxz\fP 5.4.0. +.IP "" +Ðко је затражен аутоматÑки број нити и није наведено ограничење коришћења +меморије, тада ће Ñе кориÑтити оÑновно меко ограничење Ñпецифично за ÑиÑтем +за могуће ограничење броја нити. То је меко ограничење у ÑмиÑлу да Ñе +занемарује ако број нити поÑтане један, дакле меко ограничење никада неће +зауÑтавити \fBxz\fP од запакивања или раÑпакивања. Ово оÑновно меко ограничење +неће учинити да Ñе \fBxz\fP пребаци из режима више нити у режим једне нити. +Ðктивно ограничење Ñе може видети Ñа + \fBxz \-\-info\-memory\fP. +.IP "" +Тренутно једина метода нитиÑања је да Ñе подели улаз на блокове и да Ñе +запакују незавиÑно један од другог. ОÑновна величина блока завиÑи од нивоа +запакивања и може Ñе препиÑати опцијом \fB\-\-block\-size=\fP\fIвеличина\fP. +.IP "" +Ðитно раÑпакивање ради Ñамо на датотекама које Ñадрже више блокова Ñа +информацијом величине у заглављима блока. Све довољно велике датотеке +запаковане у вишенитном режиму задовољавају овај уÑлов, али датотеке +запаковане у једнонитном режиму не чак и ако је коришћено +\fB\-\-block\-size=\fP\fIвеличина\fP. +.IP "" +ОÑновна вредноÑÑ‚ за \fIнити\fP је \fB0\fP. У \fBxz\fP 5.4.x и Ñтаријим оÑновно је +\fB1\fP. +. +.SS "Произвољни ланци филтера запакивача" +Произвољни ланац филтера омогућава детаљно одређивање подешавања Ñажимања +умеÑто да Ñе оÑлања на подешавања повезана Ñа предподешавањима. Када је +произвољни ланац филтера наведен, опције предподешавања (\fB\-0\fP \&...\& \fB\-9\fP +и \fB\-extreme\fP) раније на линији наредби Ñе заборављају. Ðко је опција +предподешавања наведена након једне или више опција произвољног ланца +филтера, ново предподешавање Ñтупа на Ñнагу а раније наведене опције +произвољног ланца филтера Ñе заборављају. +.PP +Ланац филтера је упоредив Ñа Ñпојкама на линији наредби. Приликом Ñажимања, +неÑажети улаз иде на први филтер, чији излаз иде на Ñледећи филтер (ако фа +има). Излаз поÑледњег филтера бива запиÑан у Ñажету датотеку. Ðајвећи број +филтера у ланцу је четири, али обично ланац филтера има Ñамо један или два +филтера. +.PP +Многи филтери имају ограничења о томе где могу бити у ланцу филтера: неки +филтери могу радити Ñамо као поÑледњи филтер у ланцу, неки Ñамо као +не\-поÑледњи филтер, а неки раде на било ком меÑту у ланцу. ОвиÑно о +филтеру, ово ограничење је или ÑвојÑтвено дизајну филтера или поÑтоји како +би Ñе Ñпречили проблеми безбедноÑти. +.PP +Произвољни ланац филтера Ñе може навеÑти на два различита начина. Опције +\fB\-\-filters=\fP\fIфилтери\fP и \fB\-\-filters1=\fP\fIфилтери\fP \&...\& +\fB\-\-filters9=\fP\fIфилтери\fP омогућавају навођење читавог ланца опција у једној +опцији коришћењем ÑинтакÑу ниÑке „liblzma“ филтера. Другачије, ланац +филтера Ñе може навеÑти коришћењем једне или више појединачних опција +филтера редом како Ñе траже у ланцу филтера. То је то, редоÑлед +појединачних опција филтера је важан! Приликом дешифровања Ñирових токова +(\fB\-\-format=raw\fP), ланац филтера мора бити наведен иÑтим редом као када је +био наведен приликом Ñажимања. Било који појединачни филтер или опције +предподешавања наведене пре опције читавог ланца (\fB\-\-filters=\fP\fIфилтери\fP) +биће заборављене. Појединачни филтери наведени поÑле опције читавог ланца +ће поништити поÑтавку ланца филтера. +.PP +Обе опције и пуног и појединачног филтера узимају филтеру Ñпецифичне +\fIопције\fP као зарезом раздвојен ÑпиÑак. Додатни зарези у \fIопцијама\fP Ñе +занемарују. Свака опција има оÑновну вредноÑÑ‚, тако да треба да наведете +оне које желите да измените. +.PP +Да видите читав ланац филтера и \fIопције\fP, кориÑтите \fBxz \-vv\fP (тако је, +кориÑтите \fB\-\-verbose\fP два пута). Ово ради такође за преглед опција ланца +филтера коришћених од Ñтране предподешеноÑти. +.TP +\fB\-\-filters=\fP\fIфилтери\fP +Ðаводи цео ланац филтера или предподешеноÑÑ‚ у једној опцији. Сваки филтер +Ñе може одвојити размацима или Ñа две цртице (\fB\-\-\fP). \fIФилтери\fP можда +треба да буду под наводницима на линији наредби конзоле тако да Ñе +проÑлеђују као једна опција. Да означите \fIопције\fP, кориÑтите \fB:\fP или +\fB=\fP. ПредподешеноÑти Ñе може додати Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ \fB\-\fP и може га пратити нула +или још заÑтавица. Једина подржана заÑтавица је \fBe\fP за примену иÑтих +опција као \fB\-\-extreme\fP. +.TP +\fB\-\-filters1\fP=\fIфилтери\fP ... \fB\-\-filters9\fP=\fIфилтери\fP +Ðаводи до девет додатних ланаца филтера који Ñе могу кориÑтити Ñа +\fB\-\-block\-list\fP. +.IP "" +Ðа пример, приликом запакивања архиве Ñа извршним датотекама за којима Ñледе +текÑтуалне датотеке, извршни део треба да кориÑти ланац филтера Ñа BCJ +филтером а текÑтуални део Ñамо LZMA2 филтер. +.TP +\fB\-\-filters\-help\fP +Приказује поруку помоћи опиÑујући како Ñе наводе предподешавања и произвољни +ланци филтера у опцијама \fB\-\-filters\fP и \fB\-\-filters1=\fP\fIфилтери\fP \&...\& +\fB\-\-filters9=\fP\fIфилтери\fP, и уÑпешно излази. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fIопције\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fIопције\fP] +.PD +Додаје LZMA1 или LZMA2 филтер у ланац филтера. Ови филтери Ñе могу +кориÑтити Ñамо као поÑледњи филтер у ланцу. +.IP "" +LZMA1 је Ñтари филтер, који је подржан углавном Ñамо због Ñтарог формата +\&\fB.lzma\fP датотеке, који подржава Ñамо LZMA1. LZMA2 је оÑвежено издање LZMA1 +које поправља неке практичне проблеме LZMA1. \fB.xz\fP формат кориÑти LZMA2 и +не подржава LZMA1 уопште. Брзина запакивања и одноÑи LZMA1 и LZMA2 Ñу +практично иÑти. +.IP "" +LZMA1 и LZMA2 деле иÑти Ñкуп \fIопција\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fIпредподешавање\fP +Враћа Ñве LZMA1 или LZMA2 \fIопције\fP на \fIпредподешеноÑÑ‚\fP. \fIПредпдешеноÑÑ‚\fP +Ñе ÑаÑтоји од целог броја, за којим може да Ñледи једноÑловни измењивач +предподешеноÑти. Цео број може бити од \fB0\fP до \fB9\fP, поклапајући опције +линије наредби \fB\-0\fP \&...\& \fB\-9\fP. Једини тренутно подржани измењивач је +\fBe\fP, који Ñе поклапа Ñа \fB\-\-extreme\fP. Ðко \fBpreset\fP није наведено, оÑновне +вредноÑти LZMA1 или LZMA2 \fIопција\fP Ñе узимају из предподешеноÑти \fB6\fP. +.TP +\fBdict=\fP\fIвеличина\fP +\fIВеличина\fP речника (међумеморија иÑторијата) указује на то колико је +бајтова недавно обрађених нераÑпакованих података задржано у меморији. +Ðлгоритам покушава да нађе понављајуће низове бајтова (поклапања) у +нераÑпакованим подацима, и да их замени Ñа упутама ка подацима који Ñу +тренутно у речнику. Што је већи речник, већа је вероватноћа за налажење +поклапања. Стога, повећање \fIвеличине \fP речника обично побољшава Ñтопу +запакивања, али речник већи од незапаковане датотеке јеÑте утрошак меморије. +.IP "" +Уобичајена \fIвеличина\fP речника је од 64\ KiB до 64\ MiB. Ðајмање је 4\ KiB. Ðајвише за запакивање тренутно је 1.5\ GiB (1536\ MiB). РаÑпакивач +већ подржава речнике до једног бајта мање од 4\ GiB, што је макÑимум за +формате LZMA1 и LZMA2 тока. +.IP "" +\fIВеличина\fP речника и налазач поклапања (\fImf\fP) заједно одређују коришћење +меморије за LZMA1 или LZMA2 шифрере. ИÑта (или већа) \fIвеличина\fP речника је +потребна за раÑпакивање као она која је коришћена за запаквање, Ñтога Ñе +коришћење меморије дешифрера одређује према величини речника коришћеног за +запакивање. \fB.xz\fP заглавља чувају \fIвеличину\fP речника или као 2^\fIn\fP или +2^\fIn\fP + 2^(\fIn\fP\-1), тако да Ñу те \fIвеличине\fP некако пожељније за +запакивање. Друге \fIвеличине\fP биће заокружене приликом чувања у \fB.xz\fP +заглављима. +.TP +\fBlc=\fP\fIlc\fP +Ðаводи број битова контекÑта литерала. Ðајмање је 0 а највише је 4; оÑновно +је 3. Као додатак, збир \fIlc\fP и \fIlp\fP не Ñме да премаши 4. +.IP "" +Сви бајтови који Ñе не могу шифровати јер Ñу поклапања шифрована као +литерали. То је то, литерали Ñу једноÑтавно 8\-битни бајтови који Ñу +шифровани један по један. +.IP "" +Кодирање литерала врши претпоÑтавку да највећи \fIlc\fP битови претходног +незапакованог бајта Ñу у узајамној вези Ñа Ñледећим бајтом. Ðа пример, у +уобичајеном енглеÑком текÑту, за великим Ñловом чеÑто Ñледи мало Ñлово, а за +малим Ñловом обично Ñледи још једно мало Ñлово. У Ñкупу US\-ASCII знакова, +највиша три бита Ñу 010 за велика Ñлова и 011 за мала Ñлова. Када је \fIlc\fP +барем 3, кодирање литерала може имати предноÑÑ‚ овог ÑвојÑтва у незапакованим +подацима. +.IP "" +ОÑновна вредноÑÑ‚ (3) је обично добра. Ðко желите највеће запакивање, +иÑпробајте \fBlc=4\fP. Ðекад то мало помогне а некад чини запакивање горим. +Ðко га учини горим, иÑпробајте такође \fBlc=2\fP. +.TP +\fBlp=\fP\fIlp\fP +Ðаводи број битова положаја литерала. Ðајмање је 0 а највише је 4; оÑновно +је 0. +.IP "" +\fILp\fP утиче на то која врÑта поравнања у незапакованим подацима Ñе +подразумева приликом шифровања литерала. Видите \fIpb\fP иÑпод за више +информација о поравнању. +.TP +\fBpb=\fP\fIpb\fP +Ðаводи број битова положаја. Ðајмање је 0 а највише је 4; оÑновно је 2. +.IP "" +\fIPb\fP утиче на то која врÑта поравнања у незапакованим подацима Ñе +подразумева у опште. ОÑновно значи четворобајтно поравнање (2^\fIpb\fP=2^2=4), +што је чеÑто добар избор када нема бољег решења. +.IP "" +Када је поравнање познато, поÑтављање одговарајућег \fIpb\fP може мало да Ñмањи +величину датотеке. Ðа пример, Ñа датотекама текÑта које имају поравнање +једног бајта (US\-ASCII, ISO\-8859\-*, UTF\-8), поÑтављање \fBpb=0\fP може незнатно +да побољша запакивање. За UTF\-16 текÑÑ‚, \fBpb=1\fP је добар избор. Ðко је +поравнање непаран број као 3 бајта, \fBpb=0\fP може бити најбољи избор. +.IP "" +Иако Ñе претпоÑтављено поравнање може подеÑити Ñа \fIpb\fP и \fIlp\fP, LZMA1 и +LZMA2 и даље незнатно фаворизују 16\-бајтно поравнање. То би могло бити +вредно узети у обзир приликом дизајнирања формата датотека које ће вероватно +бити чеÑто запаковане Ñа LZMA1 или LZMA2. +.TP +\fBmf=\fP\fImf\fP +Ðалазач поклапања има главни утицај на брзину шифрера, коришћење меморије и +Ñтопу запакивања. Обично Hash Chain налазачи поклапања Ñу бржи од Binary +Tree налазача поклапања. ОÑновноÑÑ‚ завиÑи од \fIпредподешеноÑти\fP: 0 кориÑти +\fBhc3\fP, 1\(en3 кориÑти \fBhc4\fP, а оÑтало кориÑти \fBbt4\fP. +.IP "" +Следећи налазачи поклапања Ñу подржани. Формуле коришћења меморије иÑпод Ñу +грубе апрокÑимације које Ñу ближе ÑтварноÑти када је \fIречник\fP Ñтепен +двојке. +.RS +.TP +\fBhc3\fP +Ланац хеша Ñа хеширањем 2\- и 3\-бајта +.br +Ðајмања вредноÑÑ‚ за \fIфино\fP: 3 +.br +Коришћење меморије: +.br +\fIречник\fP * 7.5 (ако је \fIречник\fP <= 16 MiB); +.br +\fIречник\fP * 5.5 + 64 MiB (if \fIречник\fP > 16 MiB) +.TP +\fBhc4\fP +Ланац хеша Ñа хеширањем 2\-, 3\- и 4\-бајта +.br +Ðајмања вредноÑÑ‚ за \fIфино\fP: 4 +.br +Коришћење меморије: +.br +\fIречник\fP * 7.5 (ако је \fIречник\fP <= 32 MiB); +.br +\fIречник\fP * 6.5 (ако је \fIречник\fP > 32 MiB) +.TP +\fBbt2\fP +Бинарно Ñтабло Ñа 2\-бајта хеширања +.br +Ðајмања вредноÑÑ‚ за \fIфино\fP: 2 +.br +Коришћење меморије: \fIречник\fP * 9.5 +.TP +\fBbt3\fP +Бинарно Ñтабло Ñа 2\- и 3\-бајта хеширања +.br +Ðајмања вредноÑÑ‚ за \fIфино\fP: 3 +.br +Коришћење меморије: +.br +\fIречник\fP * 11.5 (if \fIречник\fP <= 16 MiB); +.br +\fIречник\fP * 9.5 + 64 MiB (ако је \fIречник\fP > 16 MiB) +.TP +\fBbt4\fP +Бинарно Ñтабло Ñа 2\-, 3\-, и 4\-бајта хеширања +.br +Ðајмања вредноÑÑ‚ за \fIфино\fP: 4 +.br +Коришћење меморије: +.br +\fIречник\fP * 11.5 (if \fIречник\fP <= 32 MiB); +.br +\fIречник\fP * 10.5 (if \fIречник\fP > 32 MiB) +.RE +.TP +\fBmode=\fP\fIрежим\fP +\fIРежим\fP запакивања наводи методу за анализу података које произведе налазач +поклапања. Подржани \fIрежими\fP Ñу \fBfast\fP и \fBnormal\fP. Подразумева Ñе +\fBfast\fP за \fIпредподешавања\fP 0\(en3 и \fBnormal\fP за \fIпредподешавања\fP 4\(en9. +.IP "" +Обично Ñе \fBfast\fP кориÑти Ñа налазачима Hash Chain поклапања а \fBnormal\fP Ñа +налазачима Binary Tree поклапања. Ово је иÑто што раде и +\fIпредподешеноÑти\fP. +.TP +\fBnice=\fP\fIфино\fP +Ðаводи оно што Ñе Ñматра да је фина дужина за поклапање. Када Ñе поклапање +од барем \fInice\fP бајтова нађе, алгоритам зауÑтавља тражење могућих бољих +поклапања. +.IP "" +\fIФино\fP може бити 2\(en273 бајта. Веће вредноÑти теже да дају бољу Ñтопу +запакивања на уштрб брзине. ОÑновно завиÑи од \fIпредподешавања\fP. +.TP +\fBdepth=\fP\fIдубина\fP +Ðаводи највећу дубину претраге у налазачу поклапања. ОÑновно је поÑебна +вредноÑÑ‚ 0, која чини да запакивач одреди разумљиву \fIдубину\fP из \fImf\fP и +\fInice\fP. +.IP "" +Разумљива \fIдубина\fP за ланце хеша је 4\(en100 и 16\(en1000 за Ñтабло +извршних. Коришћење врло великих вредноÑти за \fIдубину\fP може учинити шифрер +врло Ñпорим Ñа неким датотекама. Избегавајте поÑтављање \fIдубине\fP преко +1000 оÑим ако ниÑте Ñпремни да прекинете запакивање у Ñлучају да потраје +превише дуго. +.RE +.IP "" +Приликом дешифровања Ñирових токова (\fB\-\-format=raw\fP), LZMA2 треба Ñамо +\fIвеличина\fP речника. LZMA1 треба такође \fIlc\fP, \fIlp\fP и \fIpb\fP. +.TP +\fB\-\-x86\fP[\fB=\fP\fIопције\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fIопције\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fIопције\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fIопције\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fIопције\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fIопције\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fIопције\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIопције\fP] +.PD +Додаје „branch/call/jump“ (BCJ) филтер ланцу филтера. Ови филтери могу Ñе +кориÑтити Ñамо ако ниÑу поÑледњи филтер у ланцу филтера. +.IP "" +BCJ филтер претвара релативне адреÑе у машинÑком коду на њихове апÑолутне +двојнике. Ово не мења величину података, али повећава ÑувишноÑÑ‚, што може +помоћи LZMA2 да произведе 0\(en15\% мању \fB.xz\fP датотеку. BCJ филтери Ñу +увек реверзибилни, Ñтога коришћење BCJ филтера за погрешну врÑту података не +доводи ни до каквог губитка података, мада може да учини Ñтепен Ñажимања +нешто лошијим. BCJ филтери Ñу врло брзи и кориÑте безначајну количину +меморије. +.IP "" +Ови BCJ филтери имају познате проблеме везане за Ñтопу запакивања: +.RS +.IP \(bu 3 +Ðеке врÑте датотека које Ñадрже извршни код (на пример, објектне датотеке, +Ñтатичке библиотеке и модули Ð›Ð¸Ð½ÑƒÐºÑ ÐºÐµÑ€Ð½ÐµÐ»Ð°) имају адреÑе у упутÑтвима +иÑпуњеним вредноÑтима попуњавача. Ови BCJ филтери и даље ће радити +претварање адреÑе, што ће запакивање учинити горим Ñа овим датотекама. +.IP \(bu 3 +Ðко Ñе BCJ филтер примени на архиву, могуће је да ће учинити Ñтопу +запакивања лошијим него кад Ñе не би кориÑтио. Ðа пример, ако поÑтоје +Ñличне или чак иÑтоветне извршне тада ће филтрирање вероватно учинити +датотеке мање Ñличним и Ñтога је запакивање лошије. Садржај не\-извршних +датотека у иÑтој архиви је такође важан. У пракÑи Ñе мора покушати Ñа и без +BCJ филтера да би Ñе видело шта је боље у којој прилици. +.RE +.IP "" +Различити Ñкупови упутÑтава имају различита поравнања: извршна датотека мора +бити поравната на множилац ове вредноÑти у улазним подацима како би филтер +радио. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +Филтер;Поравнање;Ðапомене +x86;1;32\-бита или 64\-бита x86 +ARM;4; +ARM\-Thumb;2; +ARM64;4;4096\-бита поравнање је најбоље +PowerPC;4;Само велика крајноÑÑ‚ +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +Како Ñу BCJ\-филтрирани подаци обично запаковани Ñа LZMA2, Ñтопа запакивања +може бити незнатно побољшана ако Ñу LZMA2 опције поÑтављене да поклопе +поравнање изабраног BCJ филтера. Примери: +.RS +.IP \(bu 3 +IA\-64 филтер има поравнање 16\-бајта тако да је \fBpb=4,lp=4,lc=0\fP добро Ñа +LZMA2 (2^4=16). +.IP \(bu 3 +RISC\-V код има поравнање од 2 или 4 бајта у завиÑноÑти од тога да ли +датотека Ñадржи запаковане инÑтрукције од 16 бита (проширење C). Када Ñе +кориÑте инÑтрукције од 16 бита, \fBpb=2,lp=1,lc=3\fP или \fBpb=1,lp=1,lc=3\fP је +добро. Када нема инÑтрукција од 16 бита, \fBpb=2,lp=2,lc=2\fP је најбоље. +\fBreadelf \-h\fP Ñе може кориÑтити да Ñе провери да ли Ñе „RVC“ јавља у реду +„ЗаÑтавице“. +.IP \(bu 3 +ARM64 је увек 4\-бајта поравнат тако да је \fBpb=2,lp=2,lc=2\fP најбоље. +.IP \(bu 3 +Филтер x86 је изузетак. Обично је добро придржавати Ñе LZMA2 оÑновноÑти +(\fBpb=2,lp=0,lc=3\fP) приликом запакивања x86 извршних. +.RE +.IP "" +Сви BCJ филтери подржавају иÑте \fIопције\fP: +.RS +.TP +\fBstart=\fP\fIпомерај\fP +Ðаводи \fIпомерај\fP почетка који Ñе кориÑти приликом претварања између +релативних и апÑолутних адреÑа. \fIПомерај\fP мора бити производ поравнања +филтера (видите табелу изнад). ОÑновно је нула. У пракÑи, оÑновноÑÑ‚ је +добра; навођење произвољног \fIпомераја\fP Ñкоро никада није од кориÑти. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fIопције\fP] +Додаје Delta филтер у ланац филтера. Делта филтер може Ñе кориÑтити Ñамо +ако није поÑледњи филтер у ланцу филтера. +.IP "" +Тренутно је подржан Ñамо једноÑтаван делта прорачун једног по једног бита. +Може бити кориÑтан приликом запакивања, на пример, незапакованих битмап +Ñлика или незапакованог PCM звука. Међутим, алгоритми поÑебне намене могу +дати знатно боље резултате него Delta + LZMA2. Ово је тачно, поÑебно Ñа +звуком, који Ñе запакује брже и боље, на пример, Ñа \fBflac\fP(1). +.IP "" +Подржане \fIопције\fP: +.RS +.TP +\fBdist=\fP\fIраÑтојање\fP +Ðаводи \fIраÑтојање\fP делта прорачуна у бајтима. \fIРаÑтојање\fP мора бити +1\(en256. ОÑновно је 1. +.IP "" +Ðа пример, Ñа \fBdist=2\fP и оÑмобајтним улазом A1 B1 A2 B3 A3 B5 A4 B7, излаз +ће бити A1 B1 01 02 01 02 01 02. +.RE +. +.SS "ОÑтале опције" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +ПотиÑкује упозорења и обавештења. Ðаведите ово два пута да потиÑнете и +грешке. Ова опција нема утицаја на Ñтање излаза. Тако је, чак и ако је +упозорење потиÑнуто, Ñтање излаза које указује на упозорење Ñе и даље +кориÑти. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +Бива опширан. Ðко је Ñтандардна грешка повезана Ñа терминалом, \fBxz\fP ће +приказати указивач напретка. Ðавођењем \fB\-\-verbose\fP два пута добија Ñе још +опширнији излаз. +.IP "" +Указивач напредовања показује Ñледеће информације: +.RS +.IP \(bu 3 +Проценат довршеноÑти Ñе показује ако је величина улазне датотеке позната. +Тако је, проценат Ñе не може приказати у Ñпојкама. +.IP \(bu 3 +Количина запакованих података проиÑтеклих (запакивање) или утрошених +(раÑпакивање). +.IP \(bu 3 +Количина раÑпакованих података утрошених (запакивање) или проиÑтеклих +(раÑпакивање). +.IP \(bu 3 +Размера паковања, која Ñе израчунава дељењем количине запакованих података +обрађених до Ñада количином незапакованих података до Ñада обрађених. +.IP \(bu 3 +Брзина запакивања или раÑпакивања. Ово Ñе мери као количина незапакованих +података утрошених (запакивање) или добијених (раÑпакивање) у Ñекунди. +Приказује Ñе након неколико Ñекунде након што \fBxz\fP започне обраду датотеке. +.IP \(bu 3 +Протекло време у формату М:СС или Ч:ММ:СС. +.IP \(bu 3 +Процењено преоÑтало време Ñе приказује Ñамо када је величина улазне датотеке +позната и неколико Ñекунди је већ протекло од кад је \fBxz\fP започео обраду +датотеке. Време Ñе приказује у мање тачном формату које никада нема +двотачке, на пример, 2 мин 30 Ñек. +.RE +.IP "" +Када Ñтандардна грешка није терминал, \fB\-\-verbose\fP ће учинити да \fBxz\fP +иÑпише назив датотеке, запаковану величину, незапаковану величину, Ñтопу +запакивања и по могућÑтву такође брзину и протекло време на једном реду на +Ñтандардну грешку након запакивања или раÑпакивања датотеке. Брзина и +протекло време Ñу укључени Ñамо када радња потраје барем неколико Ñекунде. +Ðко Ñе радња не заврши, на пример, уÑлед што кориÑник прекине, такође Ñе +иÑпиÑује проценат завршеноÑти ако је величина улазне датотеке позната. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Ðе поÑтавља Ñтање излаза на 2 чак и ако је уÑлов вредан упозорења откривен. +Ова опција не утиче на ниво опширноÑти, Ñтога и \fB\-\-quiet\fP и \fB\-\-no\-warn\fP +треба да Ñе кориÑте да Ñе не приказују упозорења и да Ñе не измени Ñтање +излаза. +.TP +\fB\-\-robot\fP +ИÑпиÑује поруке у формату обрадивом машинама. Ово је замишљено да олакша +пиÑање челника који желе да кориÑте \fBxz\fP умеÑто „liblzma“, што може бити +Ñлучај Ñа разним Ñкриптама. Излаз Ñа овом опцијом укљученом је замишљен да +буде Ñтабилан кроз \fBxz\fP издања. Видите одељак \fBРЕЖИМ РОБОТÐ\fP за више о +томе. +.TP +\fB\-\-info\-memory\fP +Приказује, у формату читљивом људима, колико физичке меморије (RAM) и колико +нити процеÑора \fBxz\fP миÑли да ÑиÑтем има и ограничења коришћења меморије за +запакивање и раÑпакивање и излази уÑпешно. +.TP +\fB\-h\fP, \fB\-\-help\fP +Приказује поруку помоћи опиÑујући најчешће коришћених опција, и уÑпешно +излази. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +Приказује поруку помоћи опиÑујући Ñве функције \fBxz\fP, и уÑпешно излази +.TP +\fB\-V\fP, \fB\-\-version\fP +Приказује број издања за \fBxz\fP и „liblzma“ у формату читљивом људима. Да +добијете излаз машинама обрадив, наведите \fB\-\-robot\fP пре \fB\-\-version\fP. +. +.SH "РЕЖИМ РОБОТÐ" +Режим робота Ñе покреће опцијом \fB\-\-robot\fP. Чини да излаз \fBxz\fP буде лакши +за обраду другим програмима. Тренутно \fB\-\-robot\fP је подржано Ñамо заједно +Ñа \fB\-\-list\fP, \fB\-\-filters\-help\fP, \fB\-\-info\-memory\fP, и \fB\-\-version\fP. Биће +подржан за запакивање и раÑпакивање у будућноÑти. +. +.SS "Режим ÑпиÑка" +\fBxz \-\-robot \-\-list\fP кориÑти излаз раздвојен табулатором. Прва колона +Ñваког реда Ñадржи ниÑку која указује на врÑту информације која Ñе налази у +том реду: +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP (назив) +Ово је увек први ред приликом почетка лиÑтања датотеке. Друга колона у реду +је назив датотеке. +.TP +\fBfile\fP (датотека) +Овај ред Ñадржи Ñвеукупне информације о \fB.xz\fP датотеци. Овај ред Ñе увек +иÑпиÑује поÑле реда \fBназив\fP. +.TP +\fBstream\fP (ток) +Ова врÑта реда Ñе кориÑти Ñамо када је \fB\-\-verbose\fP наведено. Има толико +редова \fBтока\fP колико има токова у \fB.xz\fP даатотеци. +.TP +\fBblock\fP (блок) +Ова врÑта реда Ñе кориÑти Ñамо када је \fB\-\-verbose\fP наведено. Има онолико +редова \fBблока\fP колико има блокова у \fB.xz\fP датотеци. Редови \fBблока\fP Ñе +приказују након Ñвих редова \fBтока\fP; различите врÑте реда Ñе не преплићу. +.TP +\fBsummary\fP (Ñажетак) +Ова врÑта реда Ñе кориÑти Ñамо када је \fB\-\-verbose\fP наведено два пута. Овај +ред Ñе иÑпиÑује након Ñвих редова \fBблока\fP. Као ред \fBдатотека\fP, ред +\fBÑажетка\fP Ñадржи преглед информација о \fB.xz\fP датотеци. +.TP +\fBtotals\fP (укупноÑÑ‚) +Овај ред је увек поÑледњи ред на ÑпиÑку излаза. Показује укупне збирове и +величине. +.PP +Колоне редова \fBдатотеке\fP: +.PD 0 +.RS +.IP 2. 4 +Број токова у датотеци +.IP 3. 4 +Укупан број блокова у току(овима) +.IP 4. 4 +Величина запаковане датотеке +.IP 5. 4 +Величина незапаковане датотеке +.IP 6. 4 +Размера паковања, на пример, \fB0.123\fP. Ðко је размера преко 9.999, три +цртице (\fB\-\-\-\fP) Ñе приказују умеÑто размере. +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +Зарезом раздвојен ÑпиÑак назива провера целовитоÑти. Следеће ниÑке Ñе +кориÑте за познате врÑте провера: \fBNone\fP, \fBCRC32\fP, \fBCRC64\fP и \fBSHA\-256\fP. +За непознате врÑте провера, кориÑти Ñе \fBUnknown\-\fP\fIN\fP, где је \fIN\fP ИД +провере као децимални број (једна или две цифре). +.IP 8. 4 +Укупна величина попуњавања тока у датотеци +.RE +.PD +.PP +Колоне редова \fBтока\fP: +.PD 0 +.RS +.IP 2. 4 +Број тока (први ток је 1) +.IP 3. 4 +Број блокова у току +.IP 4. 4 +Померај почетка запакованог +.IP 5. 4 +Померај почетка незапаковане +.IP 6. 4 +Величина запакованог (не укључује попуну тока) +.IP 7. 4 +Величина незапаковане +.IP 8. 4 +Размера паковања +.IP 9. 4 +Ðазив провере целовитоÑти +.IP 10. 4 +Величина попуне тока +.RE +.PD +.PP +Колоне редова \fBблока\fP: +.PD 0 +.RS +.IP 2. 4 +Број тока који Ñадржи овај блок +.IP 3. 4 +Број блока релативан на почетак тока (први блок је 1) +.IP 4. 4 +Број блока релативан на почетак датотеке +.IP 5. 4 +Померај почетка запакованог одноÑан на почетак датотеке +.IP 6. 4 +Померај почетка незапаковане одноÑан на почетак датотеке +.IP 7. 4 +Укупна запакована величина блока (заједно Ñа заглављима) +.IP 8. 4 +Величина незапаковане +.IP 9. 4 +Размера паковања +.IP 10. 4 +Ðазив провере целовитоÑти +.RE +.PD +.PP +Ðко је \fB\-\-verbose\fP наведено два пута, додатне колоне Ñу укључене у редовима +\fBблока\fP. Они Ñе не приказују Ñа једним \fB\-\-verbose\fP, јер добијање ове +информације захтева много тражења и Ñтога може бити Ñпоро: +.PD 0 +.RS +.IP 11. 4 +ВредноÑÑ‚ провере целовитоÑти у хекÑадецималном облику +.IP 12. 4 +Величина заглавља блока +.IP 13. 4 +ЗаÑтавице блока: \fBc\fP указује да је величина запакованог приÑутна, а \fBu\fP +указује да је величина нераÑпакованог приÑутна. Ðко заÑтавица није +поÑтављена, цртица (\fB\-\fP) Ñе приказује умеÑто да Ñе наÑтави Ñа поправком +дужине ниÑке. У будућноÑти нове заÑтавице могу бити додате на крај ниÑке. +.IP 14. 4 +Величина Ñтварних запакованих података у блоку (ово иÑкључује заглавље +блока, попуњавање блока и поља провере) +.IP 15. 4 +Количина меморије (у бајтовима) потребна за раÑпакивање овог блока Ñа овим +\fBxz\fP издањем +.IP 16. 4 +Ланац филтера. Знајте да већина опција коришћених за време запакивања не +може бити познато, јер Ñе Ñамо опције које Ñу потребне за раÑпакивање чувају +у \fB.xz\fP заглављима. +.RE +.PD +.PP +Колоне редова \fBÑажетка\fP: +.PD 0 +.RS +.IP 2. 4 +Количина меморије (у бајтовима) потребна за раÑпакивање ове датотеке Ñа овим +\fBxz\fP издањем +.IP 3. 4 +\fByes\fP или \fBno\fP указује да ли Ñва заглавља блока имају и величину +запакованог и величину незапакованог Ñачуване у њима +.PP +\fIОд\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +Потребно је најмање \fBxz\fP издање за раÑпакивање датотеке +.RE +.PD +.PP +Колоне редова \fBукупноÑти\fP: +.PD 0 +.RS +.IP 2. 4 +Број токова +.IP 3. 4 +Број блокова +.IP 4. 4 +Величина запакованог +.IP 5. 4 +Величина незапаковане +.IP 6. 4 +ПроÑечан Ñтепен запакивања +.IP 7. 4 +СпиÑак зарезом раздвојених назива провере целовитоÑти која Ñу била приÑутна +у датотекама +.IP 8. 4 +Величина попуњавања тока +.IP 9. 4 +Број датотека. Ту Ñе држи поредак ранијих колона иÑто као у редовима +\fBдатотеке\fP. +.PD +.RE +.PP +Ðко је \fB\-\-verbose\fP наведено два пута, додатне колоне Ñу укључене у реду +\fBtotals\fP: +.PD 0 +.RS +.IP 10. 4 +Ðајвећа количина меморије (у бајтима) потребна за раÑпакивање датотеке Ñа +овим \fBxz\fP издањем +.IP 11. 4 +\fByes\fP или \fBno\fP указује да ли Ñва заглавља блока имају и величину +запакованог и величину незапакованог Ñачуване у њима +.PP +\fIОд\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +Потребно је најмање \fBxz\fP издање за раÑпакивање датотеке +.RE +.PD +.PP +Будућа издања могу додати нове врÑте реда и нове колоне Ñе могу додати +поÑтојећим врÑтама реда, али поÑтојеће колоне Ñе неће променити. +. +.SS "Помоћ филтера" +\fBxz \-\-robot \-\-filters\-help\fP иÑпиÑује подржане филтере у Ñледећем формату: +.PP +\fIфилтер\fP\fB:\fP\fIопција\fP\fB=<\fP\fIвредноÑÑ‚\fP\fB>,\fP\fIопција\fP\fB=<\fP\fIвредноÑÑ‚\fP\fB>\fP... +.TP +\fIфилтер\fP +Ðазив филтера +.TP +\fIопција\fP +Ðазив филтера Ñпецифичне опције +.TP +\fIвредноÑÑ‚\fP +ОпÑези бројевних \fIвредноÑти\fP Ñе јављају као +\fB<\fP\fImin\fP\fB\-\fP\fImax\fP\fB>\fP. \fIВредноÑÑ‚\fP ниÑке избора Ñе приказују +унутар \fB< >\fP и раздвојене Ñу знаком \fB|\fP. +.PP +Сваки филтер Ñе иÑпиÑује на Ñвом ÑопÑтвеном реду. +. +.SS "Информације о ограничењу меморије" +\fBxz \-\-robot \-\-info\-memory\fP иÑпиÑује један ред Ñа више колона раздвојених +табулатором: +.IP 1. 4 +Укупна количина физичке меморије (RAM) у бајтима. +.IP 2. 4 +Ограничење коришћења меморије за запакивање у бајтима +(\fB\-\-memlimit\-compress\fP). Специјална вредноÑÑ‚ \fB0\fP означава оÑновно +подешавање које је за режим једне нити иÑто као без ограничења. +.IP 3. 4 +Ограничење коришћења меморије за раÑпакивање у бајтима +(\fB\-\-memlimit\-decompress\fP). Специјална вредноÑÑ‚ \fB0\fP означава оÑновно +подешавање које је за режим једне нити иÑто као без ограничења. +.IP 4. 4 +Од \fBxz\fP 5.3.4alpha: Коришћење меморије за раÑпакивање Ñа више нити у +бајтима (\fB\-\-memlimit\-mt\-decompress\fP). Ово никада није нула јер ÑиÑтему +Ñпецифична оÑновна вредноÑÑ‚ приказана у колони 5 Ñе кориÑти ако ограничење +није изричито наведено. Такође никада није веће од вредноÑти у колони 3 чак +и ако је наведена већа вредноÑÑ‚ Ñа \fB\-\-memlimit\-mt\-decompress\fP. +.IP 5. 4 +Од \fBxz\fP 5.3.4alpha: СиÑтему Ñпецифично оÑновно ограничење коришћења +меморије које Ñе кориÑти за ограничавање броја нити приликом запакивања Ñа +аутоматÑким бројем нити (\fB\-\-threads=0\fP) и без наведеног ограничења +коришћења меморије (\fB\-\-memlimit\-compress\fP). Ово Ñе такође кориÑти као +оÑновна вредноÑÑ‚ за \fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +Од \fBxz\fP 5.3.4alpha: Број доÑтупних нити обрађивача. +.PP +У будуће, излаз \fBxz \-\-robot \-\-info\-memory\fP може имати више колона, али +никада више од једног реда. +. +.SS Издање +\fBxz \-\-robot \-\-version\fP иÑпиÑује број издања за \fBxz\fP и „liblzma“ у Ñледећем +формату: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +Главно издање. +.TP +\fIYYY\fP +Споредно издање. Парни бројеви Ñу Ñтабилна а непарни Ñу алфа или бета +издања. +.TP +\fIZZZ\fP +Ðиво закрпе за Ñтабилна издања или Ñамо бројач за развојна издања. +.TP +\fIS\fP +СтабилноÑÑ‚. 0 је алфа, 1 је бета, а 2 је Ñтабилно. \fIS\fP треба увек да буде +2 када је \fIYYY\fP парно. +.PP +\fIXYYYZZZS\fP Ñу иÑти у оба реда ако Ñу \fBxz\fP и „liblzma“ из иÑтог издања XZ +Utils\-а. +.PP +Примери: 4.999.9beta је \fB49990091\fP и 5.0.0 је \fB50000002\fP. +. +.SH "СТÐЊЕ ИЗЛÐЗÐ" +.TP +\fB0\fP +Све је у реду. +.TP +\fB1\fP +Дошло је до грешке. +.TP +\fB2\fP +ДеÑило Ñе нешто вредно упозорења, али није дошло до Ñтварних грешака. +.PP +Обавештења (без упозорења или грешака) иÑпиÑано на Ñтандардној грешци не +утичу на Ñтање излаза. +. +.SH ОКРУЖЕЊЕ +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP обрађује размаком одвојени ÑпиÑак опција из променљивих окружења +\fBXZ_DEFAULTS\fP и \fBXZ_OPT\fP, тим редом, пре обраде опција Ñа линије наредби. +Знајте да Ñе обрађују Ñамо опције из променљивих окружења; Ñве што ниÑу +опције Ñе тихо занемарује. Обрада Ñе ради Ñа \fBgetopt_long\fP(3) која Ñе +кориÑти такође за аргументе линије наредби. +.PP +\fBУпозорење:\fP ПоÑтављањем ових променљивих окружења, ефективно мењате +програме и Ñкрипте које покреће \fBxz\fP. У већини Ñлучајева је безбедно +поÑтавити ограничење коришћења, број нити и опција паковања путем +променљивих окружења. Међутим, неке опције могу да уруше Ñкрипте. +Очигледан пример је \fB\-\-help\fP која чини да \fBxz\fP прикаже текÑÑ‚ помоћи умеÑто +да запакује или раÑпакује датотеку. Суптилнији примери Ñу \fB\-\-quiet\fP и +\fB\-\-verbose\fP. У многим Ñлучајевима добро функционише омогућавање указивача +напредовања коришћењем \fB\-\-verbose\fP, али у неким Ñитуацијама додатне поруке +Ñтварају проблеме. Ðиво опширноÑти такође утиче на понашање \fB\-\-list\fP +.TP +\fBXZ_DEFAULTS\fP +КориÑнику Ñпецифичне или Ñвеопште ÑиÑтемÑке оÑновне опције. Обично је ово +поÑтављено у Ñкрипти покретања конзоле за укључивање \fBxz\fP ограничавача +коришћења меморије по оÑнови или за поÑтављање оÑновног броја нити. +ИÑкључивање Ñкрипти покретања конзоле и Ñличних Ñпецијалних Ñлучајева, +Ñкрипте не Ñмеју никада да поÑтаве или пониште \fBXZ_DEFAULTS\fP. +.TP +\fBXZ_OPT\fP +Ово је за проÑлеђивање опција ка \fBxz\fP када није могуће поÑтавити опције +директно на \fBxz\fP линији наредби. Ово је Ñлучај када је \fBxz\fP покренут +Ñкриптом или алатом, на пример, Ñа Гну \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +Скрипте могу да кориÑте \fBXZ_OPT\fP, на пример, за поÑтављање оÑновних опција +запакивања Ñпецифичних Ñкрипти. Још увек Ñе препоручује омогућавање +кориÑницима да пишу преко \fBXZ_OPT\fP ако је то разумљиво. Ðа пример, у +\fBsh\fP(1) Ñкриптама неко може кориÑтити нешто као ово: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "LZMA UTILS СÐДЕЈСТВЕÐОСТ" +СинтакÑа линије наредби \fBxz\fP је практично Ñупер Ñкуп \fBlzma\fP, \fBunlzma\fP и +\fBlzcat\fP као што Ñе налази у LZMA Utils 4.32.x. У већини Ñлучајева, могуће +је заменити LZMA Utils Ñа XZ Utils без оштећења поÑтојећих Ñкрипти. Има +неких неÑаглаÑноÑти такође, које понекад могу довеÑти до проблема. +. +.SS "Ðивои предподешавања запакивања" +Ðабрајање предподешеноÑти нивоа запакивања није иÑто у \fBxz\fP и LZMA Utils. +Ðајважнија разлика је у томе како Ñе величине речника мапирају у различитим +предподешеноÑтима. Величина речника је отприлике иÑта као и коришћење +меморије раÑпакивача. +.RS +.PP +.TS +tab(;); +c c c +c n n. +Ðиво;xz;LZMA Utils +\-0;256 KiB;Ð/Д +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +Разлике величине речника делују такође на коришћење меморије запакивање, али +поÑтоје још неке разлике између LZMA Utils и XZ Utils, што чини разлике још +већим: +.RS +.PP +.TS +tab(;); +c c c +c n n. +Ðиво;xz;LZMA Utils 4.32.x +\-0;3 MiB;Ð/Д +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +ОÑновни ниво предподешеноÑти у LZMA Utils је \fB\-7\fP док у XZ Utils је \fB\-6\fP, +тако да оба кориÑте 8 MiB речник по оÑнови. +. +.SS "Токовне наÑпрам не\-токовних „.lzma“ датотеке" +Ðезапакована величина датотеке Ñе може чувати у \fB.lzma\fP заглављу. LZMA +Utils то ради приликом запакивања обичних датотека. Ðлтернатива је да Ñе +означи та незапакована величина као непозната и да Ñе кориÑти означавач +краја утовара да назначи где раÑпакивач треба да Ñтане. LZMA Utils кориÑти +ову методу када незапакована величина није позната, што је Ñлучај, на +пример, у Ñпојкама. +.PP +\fBxz\fP подржава раÑпакивање \fB.lzma\fP датотека Ñа или без означавача краја +утовара, али ће Ñве \fB.lzma\fP датотеке направљене Ñа \fBxz\fP кориÑтити +означавач краја утовара и означити незапаковану величину непознатом у +\&\fB.lzma\fP заглављу. Ово може бити проблем у неким неуобичајеним +Ñитуацијама. Ðа пример, \fB.lzma\fP раÑпакивач у угнежденом уређају може +радити Ñамо Ñа датотекама које имају незапаковану величину. Ðко наиђете на +тај проблем, треба да кориÑтите LZMA Utils или LZMA SDK да направите +\&\fB.lzma\fP датотеке Ñа познатом незапакованом величином. +. +.SS "Ðеподржане „.lzma“ датотеке" +Формат \fB.lzma\fP омогућава \fIlc\fP вредноÑти Ñве до 8, а \fIlp\fP вредноÑти Ñве до +4. LZMA Utils може да раÑпакује датотеке Ñа било којим \fIlc\fP и \fIlp\fP, али +увек прави датотеке Ñа \fBlc=3\fP и \fBlp=0\fP. Прављење датотека Ñа другим \fIlc\fP +и \fIlp\fP је мгуће Ñа \fBxz\fP и Ñа LZMA SDK. +.PP +Примена филтера LZMA1 у „liblzma“ захтева да збир \fIlc\fP и \fIlp\fP не Ñме да +премаши 4. Стога, \fB.lzma\fP датотеке, које премаше ово ограничење, не могу +да Ñе раÑпакују Ñа \fBxz\fP. +.PP +LZMA Utils прави Ñамо \fB.lzma\fP датотеке које имају величину речника од +2^\fIn\fP (Ñтепен 2) али прихвата датотеке Ñа било којом величином речника. +„liblzma“ прихвата Ñамо \fB.lzma\fP датотеке које имају величину речника од +2^\fIn\fP или 2^\fIn\fP + 2^(\fIn\fP\-1). Ово је да Ñе Ñмање лажни позитивни +резултати приликом откривања \fB.lzma\fP датотека. +.PP +Ова ограничења не би требало да буду проблем у пракÑи, јер Ñу практично Ñве +\&\fB.lzma\fP датотеке запаковане Ñа поÑтавкама које ће „liblzma“ прихватити. +. +.SS "Пратеће Ñмеће" +Приликом раÑпакивања, LZMA Utils тихо занемарује Ñве поÑле првог \fB.lzma\fP +тока. У већини прилика, ово је грешка. Ово такође значи да LZMA Utils не +подржава раÑпакивање надовезаних \fB.lzma\fP датотека. +.PP +Ðко Ñу оÑтали подаци након првог \fB.lzma\fP тока, \fBxz\fP Ñматра да је датотека +оштећена оÑим ако је коришћено \fB\-\-single\-stream\fP. Ово може прекинути +нејаÑне Ñкрипте које Ñу претпоÑтавиле да је пратеће Ñмеће занемарено. +. +.SH ÐÐПОМЕÐЕ +. +.SS "Излаз запакованог може бити променљив" +Тачан запаковани излаз добијен из иÑте незапаковане улазне датотеке може Ñе +разликовати између XZ Utils издања чак и ако Ñу опције запакивања +иÑтоветне. Ово је због тога што шифрер може бити побољшан (брже и боље +запакивање) а да не утиче на формат датотеке. Излаз Ñе може разликовати +између различитих изградњи иÑтог XZ Utils издања, ако Ñу коришћене другачије +опције изградње. +.PP +Ово изнад значи да када Ñе \fB\-\-rsyncable\fP једном примени, резултирајућа +датотека неће неопходно бити r\-уÑкладива оÑим ако и Ñтара и нова датотека +ниÑу запаковане иÑтим xz издањем. Овај проблем може бити поправљен ако је +део примене шифрера замрзнут да држи r\-уÑкладив излаз Ñтабилним кроз xz +издања. +. +.SS "Угнеждени „.xz“ раÑпакивачи" +Примена угнежденог \fB.xz\fP раÑпакивача као што је XZ Embedded неопходно не +подржава датотеке направљене врÑтама \fIпровере\fP целовитоÑти оÑим \fBnone\fP и +\fBcrc32\fP. Како је оÑновно \fB\-\-check=crc64\fP, морате да кориÑтите +\fB\-\-check=none\fP или \fB\-\-check=crc32\fP када правите датотеке за угнеждене +ÑиÑтеме. +.PP +Споља уграђени ÑиÑтеми, Ñви раÑпакивачи \fB.xz\fP формата подржавају Ñве врÑте +\fIпровере\fP, или барем могу да раÑпакују датотеку без иÑпитивања провере +целовитоÑти ако одређена \fIпровера\fP није подржана. +.PP +XZ Embedded подржава BCJ филтере, али Ñамо Ñа оÑновним померајем почетка. +. +.SH ПРИМЕРИ +. +.SS ОÑновно +Запакује датотеку \fIfoo\fP у \fIfoo.xz\fP кориÑтећи оÑновни ниво запакивања +(\fB\-6\fP), и уклања \fIfoo\fP ако је запакивање уÑпешно: +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +РаÑпакује \fIbar.xz\fP у \fIbar\fP и не уклања \fIbar.xz\fP чак и када је раÑпакивање +уÑпешно: +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +Ствара \fIbaz.tar.xz\fP Ñа предподешавањем \fB\-4e\fP (\fB\-4 \-\-extreme\fP), које је +Ñпорије него оÑновно \fB\-6\fP, али захтева мање меморије за запакивање и +раÑпакивање (48\ MiB и 5\ MiB): +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +Мешавина Ñажетих и неÑажетих датотека Ñе може раÑпаковати на Ñтандардни +излаз једном наредбом: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "Паралелно запакивање више датотека" +Ðа GNU и *BSD, \fBfind\fP(1) и \fBxargs\fP(1) Ñе могу кориÑтити за паралелно +запакивање више датотека: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +Опција \fB\-P\fP за \fBxargs\fP(1) поÑтавља број паралелних \fBxz\fP процеÑа. Ðајбоља +вредноÑÑ‚ за опцију \fB\-n\fP завиÑи од тога колико датотека има за запакивање. +Ðко има Ñамо неколико датотека, вредноÑÑ‚ би вероватно требала да буде 1; Ñа +више хиљада датотека, 100 или чак и више може бити одговарајуће за Ñмањење +броја \fBxz\fP процеÑа које би \fBxargs\fP(1) евентуално направио. +.PP +Опција \fB\-T1\fP за \fBxz\fP је ту да га примора на једнонитни режим, јер Ñе +\fBxargs\fP(1) кориÑти за контролу количине паралелизације. +. +.SS "Режим робота" +Израчунава колико је бајтова укупно Ñачувано након запакивања више датотека: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +Скрипта може желети да зна да кориÑти најновији \fBxz\fP. Следећа Ñкрипта +\fBsh\fP(1) проверава да ли је број издања \fBxz\fP алата барем 5.0.0. Ова +метода је ÑаглаÑна Ñа Ñтарим бета издањима која не подржавају \fB\-\-robot\fP +опцију: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Ваш „xz“ је превише Ñтар." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +ПоÑтавља ограничење коришћења меморије за раÑпакивање коришћењем \fBXZ_OPT\fP, +али ако је ограничење већ поÑтављено, не повећава је: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "Произвољни ланци филтера запакивача" +ÐајједноÑтавнија употреба за произвољне ланце филтера прилагођава LZMA2 +предподешеноÑÑ‚. Ово може бити кориÑно, јер предподешеноÑти покривају Ñамо +подÑкуп потенцијално кориÑних комбинација поÑтавки запакивања. +.PP +Колоне ЗапакЦПЈ у табелама из опиÑа опција \fB\-0\fP ... \fB\-9\fP и \fB\-\-extreme\fP Ñу +кориÑне приликом прилагођавања LZMA2 предподешеноÑти. Овде Ñу значајни +делови прикупљени из те две табеле: +.RS +.PP +.TS +tab(;); +c c +n n. +ПреподешеноÑÑ‚;ЗапакЦПЈ +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +Ðко знате да датотека захтева нешто велики речник (на пример, 32 \ MiB) за +добро запакивање, али желите да је запакујете брже него што би то \fBxz \-8\fP +урадио, предподешеноÑÑ‚ Ñа ниÑком вредношћу ЗапакМем (на пример, 1) може Ñе +изменити да кориÑти већи речник: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +Са одређеним датотекама, горња наредба може бити бржа од \fBxz \-6\fP а +запакивање значајно боље. Међутим, мора бити наглашено да Ñамо неке +датотеке имају кориÑÑ‚ од великог речника док одржавају вредноÑÑ‚ ЗапакЦПЈ +ниÑком. Ðајочигледнија Ñитуација, у којој велики речник може доÑта помоћи, +јеÑте архива која Ñадржи врло Ñличне датотеке где Ñвака има најмање неколико +мегабајта. Величина речника треба да буде значајно већа од Ñваке заÑебне +датотеке да би Ñе омогућило да LZMA2 има потпуну предноÑÑ‚ од ÑличноÑти +између узаÑтопних датотека. +.PP +Ðко је веома велико коришћење меморије запакивача и раÑпакивача у реду, а +датотека која Ñе запакује је барем неколико Ñтотина мегабајта, може бити +кориÑно кориÑтити још већи речник од 64 MiB који ће \fBxz \-9\fP кориÑтити: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +Коришћење \fB\-vv\fP (\fB\-\-verbose \-\-verbose\fP) као у горњем примеру може бити +кориÑно да Ñе виде захтеви за меморијом запакивача и раÑпакивача. Знајте да +је коришћење речника већег од величине незапаковане датотеке губитак +меморије, тако да горња наредба није кориÑна за мале датотеке. +.PP +Понекад време запакивања није важно, али коришћење меморије раÑпакивача +треба да Ñе одржава ниÑким, на пример, да би Ñе учинило могућим раÑпакивање +датотеке на угнежденом ÑиÑтему, Следеће наредбе кориÑте \fB\-6e\fP (\fB\-6 \-\-extreme\fP) као оÑнову и поÑтављају речник на Ñамо 64\ KiB. Резултујућа +датотека Ñе може раÑпаковати Ñа XZ Embedded (због тога је ту +\fB\-\-check=crc32\fP) кориÑтећи око 100\ KiB меморије. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +Ðко желите да иÑцедите што је више могуће бајтова, дотеривање броја битова +контекÑта литерала (\fIlc\fP) и броја битова положаја (\fIpb\fP) може понекад да +помогне. Дотеривање броја битова положаја литерала (\fIlp\fP) може такође да +помогне, али обично \fIlc\fP и \fIpb\fP Ñу важнији. Ðа пример, архива извора кода +Ñадржи углавном US\-ASCII текÑÑ‚, тако да нешто као Ñледеће може да да +незнатно (око 0.1\ %) мању датотеку него \fBxz \-6e\fP (пробајте такође без +\fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar\fR +.fi +.RE +.PP +Коришћење још једног филтера заједно Ñа LZMA2 може побољшати запакивање Ñа +одређеним врÑтама датотека. Ðа пример, за запакивање x86\-32 или x86\-64 +дељене библиотеке коришћењем x86 BCJ филтера: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +Знајте да поредак опција филтера има значај. Ðко је \fB\-\-x86\fP наведено након +\fB\-\-lzma2\fP, \fBxz\fP ће дати грешку, јер не Ñме бити никаквог филтера поÑле +LZMA2, и такође зато што Ñе x86 BCJ филтер не може кориÑтити као поÑледњи +филтер у ланцу. +.PP +Delta филтер заједно Ñа LZMA2 може дати добре резултате Ñа битмап Ñликама. +Требало би обично да надјача PNG, који има нешто више напредних филтера него +једноÑтавни делта али кориÑти Deflate за Ñтварно запакивање. +.PP +Слика треба да Ñе Ñачува у незапакованом формату, на пример, као +незапакована TIFF. Параметар раÑтојања Delta филтера је поÑтављен да Ñе +подудари Ñа бројем бајтова по пикÑелу у Ñлици. Ðа пример, RGB битмапа од 24 +бита захтева \fBdist=3\fP, а такође је добро проÑледити \fBpb=0\fP за LZMA2 да Ñе +прилагоди поравнање од три бајта: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +Ðко је више Ñлика Ñтављено у једну архиву (на пример, \fB.tar\fP), Delta филтер +ће радити на томе такође Ñве док Ñве Ñлике не буду имале иÑти број бајтова +по пикÑелу. +. +.SH "ВИДИТЕ ТÐКОЂЕ" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ Utils: +.br +XZ Embedded: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sr/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzdec.1 new file mode 100644 index 000000000..c9bbe26f4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzdec.1 @@ -0,0 +1,81 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Serbian translation of xz-man. +.\" МироÑлав Ðиколић , 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 08.04.2024. Tukaani "XZ Utils" +.SH ÐÐЗИВ +xzdec, lzmadec – Мали „.xz“ и „.lzma“ раÑпакивачи +.SH СÐЖЕТÐК +\fBxzdec\fP [\fIопција...\fP] [\fIдатотека...\fP] +.br +\fBlzmadec\fP [\fIопција...\fP] [\fIдатотека...\fP] +.SH ОПИС +\fBxzdec\fP је алат Ñамо за раÑпакивање заÑнован на „liblzma“ за \fB.xz\fP (и Ñамо +\&\fB.xz\fP) датотеке. \fBxzdec\fP је намењен да ради као тренутна замена за +\fBxz\fP(1) у најопштијим Ñитуацијама где је Ñкрипта напиÑана да кориÑти \fBxz \-\-decompress \-\-stdout\fP (и по могућÑтву још неколико других обично коришћених +опција) за раÑпакивање \fB.xz\fP датотека. \fBlzmadec\fP је иÑтоветна Ñа \fBxzdec\fP +оÑим што \fBlzmadec\fP подржава \fB.lzma\fP датотеке умеÑто of \fB.xz\fP датотека. +.PP +За Ñмањење величине извршне, \fBxzdec\fP не подржава више нити или +локализацију, и не чита опције из променљивих окружења \fBXZ_DEFAULTS\fP и +\fBXZ_OPT\fP. \fBxzdec\fP не подржава приказивање поÑредничких информација +напредовања: Ñлање \fBSIGINFO\fP ка \fBxzdec\fP не ради ништа, али Ñлање +\fBSIGUSR1\fP окончава Ð¿Ñ€Ð¾Ñ†ÐµÑ ÑƒÐ¼ÐµÑто да прикаже информације о напредовању. +.SH ОПЦИЈЕ +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +Занемарено зарад \fBxz\fP(1) ÑаглаÑноÑти. \fBxzdec\fP подржава Ñамо раÑпакивање. +.TP +\fB\-k\fP, \fB\-\-keep\fP +Занемарено зарад \fBxz\fP(1) ÑаглаÑноÑти. \fBxzdec\fP никада не прави или уклања +датотеке. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Занемарено зарад \fBxz\fP(1) ÑаглаÑноÑти. \fBxzdec\fP увек пише раÑпаковане +податке на Ñтандардни излаз. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Ðавођењем овога једном не ради ништа јер \fBxzdec\fP никада не приказује +упозорења или обавештења. Ðаведите ово два пута да потиÑнете грешке. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Занемарено зарад \fBxz\fP(1) ÑаглаÑноÑти. \fBxzdec\fP никада не кориÑти излазно +Ñтање 2. +.TP +\fB\-h\fP, \fB\-\-help\fP +Приказује поруку помоћи и излази Ñ ÑƒÑпехом. +.TP +\fB\-V\fP, \fB\-\-version\fP +Приказује број издања за \fBxzdec\fP и „liblzma“. +.SH "СТÐЊЕ ИЗЛÐЗÐ" +.TP +\fB0\fP +Све беше у реду. +.TP +\fB1\fP +Дошло је до грешке. +.PP +\fBxzdec\fP нема поруке упозорења као што има \fBxz\fP(1), Ñтога \fBxzdec\fP не +кориÑти излазно Ñтање 2. +.SH ÐÐПОМЕÐЕ +КориÑтите \fBxz\fP(1) умеÑто \fBxzdec\fP или \fBlzmadec\fP за обично Ñвакодневно +коришћење. \fBxzdec\fP или \fBlzmadec\fP Ñу замишљени Ñамо Ñитуације у којима је +важно имати мањи раÑпакивач неко потпуно функционалан \fBxz\fP(1). +.PP +\fBxzdec\fP и \fBlzmadec\fP ниÑу баш тако мали. Величина може бити још Ñмањена +одбацивањем функција из „liblzma“ за време превођења, али то не треба обично +да Ñе ради за извршне доÑтављене у типичним не\-угнежденим диÑтрибуцијама +оперативног ÑиÑтема. Ðко вам треба Ñтварно мали \fB.xz\fP раÑпакивач, +размотрите коришћење XZ Embedded\-а. +.SH "ВИДИТЕ ТÐКОЂЕ" +\fBxz\fP(1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sr/xzdiff.1 b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzdiff.1 new file mode 100644 index 000000000..6c9ef9938 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzdiff.1 @@ -0,0 +1,54 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Serbian translation of xz-man. +.\" МироÑлав Ðиколић , 2025. +.\" +.\" (Note that this file is not based on gzip's zdiff.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDIFF 1 06.03.2025. Tukaani "XZ Utils" +.SH ÐÐЗИВ +xzcmp, xzdiff, lzcmp, lzdiff – упоређује запаковане датотеке +. +.SH СÐЖЕТÐК +\fBxzcmp\fP [\fIопција...\fP] \fIдатотека1\fP [\fIдатотека2\fP] +.br +\fBxzdiff\fP \&... +.br +\fBlzcmp\fP \&... (ЗÐСТÐРЕЛО) +.br +\fBlzdiff\fP \&... (ЗÐСТÐРЕЛО) +. +.SH ОПИС +\fBxzcmp\fP и \fBxzdiff\fP пореди незапаковане Ñадржаје две датотеке. +Ðезапаковани подаци и опције Ñе проÑлеђују ка \fBcmp\fP(1) или \fBdiff\fP(1) оÑим +ако није наведено \fB\-\-help\fP or \fB\-\-version\fP. +.PP +Ðко Ñу наведене и \fIдатотека1\fP и \fIдатотека2\fP, оне могу бити незапаковане +датотеке или датотеке у форматима које \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), +\fBlzop\fP(1), \fBzstd\fP(1) или \fBlz4\fP(1) могу да раÑпакују. Захтеване наредбе +раÑпакивања Ñе одређују из ÑуфикÑа назива \fIдатотеке1\fP и \fIдатотеке2\fP. +Датотека Ñа непознатим ÑуфикÑом Ñе претпоÑтавља да је незапакована или да је +у формату који \fBxz\fP(1) може да раÑпакује. +.PP +Ðко је доÑтављен Ñамо један назив датотеке, \fIдатотека1\fP мора да има ÑÑƒÑ„Ð¸ÐºÑ +подржаних формата запакивања а назив за \fIдатотеку2\fP Ñе подразумева да је +\fIдатотека1\fP Ñа уклоњеним ÑуфикÑом формата запакивања. +.PP +Ðаредбе \fBlzcmp\fP и \fBlzdiff\fP Ñе доÑтављају зарад назадне ÑаглаÑноÑти Ñа LZMA +Utils. ЗаÑтареле Ñу и биће уклоњене у будућем издању. +. +.SH "СТÐЊЕ ИЗЛÐЗÐ" +Ðко дође до грешке раÑпакивања,излазно Ñтање је \fB2\fP. У Ñупротном излазно +Ñтање од \fBcmp\fP(1) или \fBdiff\fP(1) Ñе кориÑти. +. +.SH "ВИДИТЕ ТÐКОЂЕ" +\fBcmp\fP(1), \fBdiff\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), +\fBzstd\fP(1), \fBlz4\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sr/xzgrep.1 b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzgrep.1 new file mode 100644 index 000000000..263fed998 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzgrep.1 @@ -0,0 +1,92 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Serbian translation of xz-man. +.\" МироÑлав Ðиколић , 2025. +.\" +.\" (Note that this file is not based on gzip's zgrep.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZGREP 1 06.03.2025. Tukaani "XZ Utils" +.SH ÐÐЗИВ +xzgrep – претражује могуће запаковане датотеке за шаблонима +. +.SH СÐЖЕТÐК +\fBxzgrep\fP [\fIопција...\fP] [\fIÑпиÑак_шаблона\fP] [\fIдатотека...\fP] +.br +\fBxzegrep\fP \&... +.br +\fBxzfgrep\fP \&... +.br +\fBlzgrep\fP \&... (ЗÐСТÐРЕЛО) +.br +\fBlzegrep\fP \&... (ЗÐСТÐРЕЛО) +.br +\fBlzfgrep\fP \&... (ЗÐСТÐРЕЛО) +. +.SH ОПИС +\fBxzgrep\fP призива \fBgrep\fP(1) на незапакованим Ñадржајима датотека. Формати +\fIдатотека\fP Ñе одређују из ÑуфикÑа назива датотека. Било која \fIдатотека\fP +Ñа ÑуфикÑом подржаним од Ñтране \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), +\fBlzop\fP(1), \fBzstd\fP(1) или \fBlz4\fP(1) биће раÑпакована; Ñве оÑтале датотеке +Ñе подразумевају да ниÑу запаковане. +.PP +Ðко \fIдатотеке\fP ниÑу наведене или \fIдатотека\fP је \fB\-\fP тада Ñе чита +Ñтандардни улаз. Приликом читања Ñа Ñтандардног улаза, Ñамо датотеке +подржане Ñа \fBxz\fP(1) Ñе раÑпакују. Друге датотеке Ñе подразумева да Ñу већ +у незапакованом облику. +.PP +Већина \fIопција\fP \fBgrep\fP(1) је подржана. Међутим, Ñледеће опције ниÑу +подржане: +.IP "" 4 +\fB\-r\fP, \fB\-\-recursive\fP +.IP "" 4 +\fB\-R\fP, \fB\-\-dereference\-recursive\fP +.IP "" 4 +\fB\-d\fP, \fB\-\-directories=\fP\fIрадња\fP +.IP "" 4 +\fB\-Z\fP, \fB\-\-null\fP +.IP "" 4 +\fB\-z\fP, \fB\-\-null\-data\fP +.IP "" 4 +\fB\-\-include=\fP\fIglob\fP +.IP "" 4 +\fB\-\-exclude=\fP\fIglob\fP +.IP "" 4 +\fB\-\-exclude\-from=\fP\fIдатотека\fP +.IP "" 4 +\fB\-\-exclude\-dir=\fP\fIglob\fP +.PP +\fBxzegrep\fP је Ð°Ð»Ð¸Ñ˜Ð°Ñ Ð·Ð° \fBxzgrep \-E\fP. \fBxzfgrep\fP је Ð°Ð»Ð¸Ñ˜Ð°Ñ Ð·Ð° \fBxzgrep \-F\fP. +.PP +Ðаредбе \fBlzgrep\fP, \fBlzegrep\fP и \fBlzfgrep\fP Ñе доÑтављају зарад назадне +ÑаглаÑноÑти Ñа LZMA Utils. ЗаÑтареле Ñу и биће уклоњене у будућем издању. +. +.SH "СТÐЊЕ ИЗЛÐЗÐ" +.TP +0 +Ðајмање једно поклапање је пронађено из барем једне од улазних датотека. +Ðије било грешака. +.TP +1 +Ðикаква поклапања ниÑу пронађена ни из једне од улазних датотека. Ðије дошло +до грешака. +.TP +>1 +Дошло је до једне или више грешака. Ðије познато да ли Ñу поклапања нађена. +. +.SH ОКРУЖЕЊЕ +.TP +\fBGREP\fP +Ðко је \fBGREP\fP поÑтављено на не\-празну вредноÑÑ‚, кориÑти Ñе умеÑто \fBgrep\fP, +\fBgrep \-E\fP или \fBgrep \-F\fP. +. +.SH "ВИДИТЕ ТÐКОЂЕ" +\fBgrep\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), +\fBlz4\fP(1), \fBzgrep\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sr/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzless.1 new file mode 100644 index 000000000..af9fd3a0e --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzless.1 @@ -0,0 +1,47 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Serbian translation of xz-man. +.\" МироÑлав Ðиколић , 2025. +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 06.03.2025. Tukaani "XZ Utils" +.SH ÐÐЗИВ +xzless, lzless – приказује „xz“ или „lzma“ запаковане (текÑтуалне) датотеке +.SH СÐЖЕТÐК +\fBxzless\fP [\fIдатотека\fP...] +.br +\fBlzless\fP [\fIдатотека\fP...] (ЗÐСТÐРЕЛО) +.SH ОПИС +\fBxzless\fP је филтер који приказује текÑÑ‚ из запакованих датотека у +терминалу. Датотеке које подржава \fBxz\fP(1) Ñе раÑпакују; оÑтале датотеке Ñе +већ подразумева да Ñу у незапакованом облику. Ðко није дата ни једна +\fIдатотека\fP, \fBxzless\fP чита Ñа Ñтандардног улаза. +.PP +\fBxzless\fP кориÑти \fBless\fP(1) да предÑтави Ñвој излаз. За разлику од +\fBxzmore\fP, његов избор Ñтраничара Ñе не може изменити поÑтављањем променљиве +окружења. Ðаредбе Ñе заÑнивају и на \fBmore\fP(1) и на \fBvi\fP(1) и дозвољавају +померање и претрагу назад и напред. Видите упутÑтво \fBless\fP(1) за више +информација. +.PP +Ðаредба \fBlzless\fP Ñе доÑтавља зарад назадне ÑаглаÑноÑти Ñа LZMA +Utils. ЗаÑтарела је и биће уклоњена у будућем издању. +.SH ОКРУЖЕЊЕ +.TP +\fBLESSMETACHARS\fP +СпиÑак знакова нарочитих за шкољку. ПоÑтавите Ñа \fBxzless\fP оÑим ако већ +није поÑтављено у окружењу. +.TP +\fBLESSOPEN\fP +ПоÑтавља да линија наредби призове \fBxz\fP(1) раÑпакивач за предобраду улазних +датотека на \fBless\fP(1). +.SH "ВИДИТЕ ТÐКОЂЕ" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sr/xzmore.1 b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzmore.1 new file mode 100644 index 000000000..23df9c6cf --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sr/xzmore.1 @@ -0,0 +1,49 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Serbian translation of xz-man. +.\" МироÑлав Ðиколић , 2025. +.\" +.\" (Note that this file is based on xzless.1 instead of gzip's zmore.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZMORE 1 06.03.2025. Tukaani "XZ Utils" +.SH ÐÐЗИВ +xzmore, lzmore – приказује „xz“ или „lzma“ запаковане (текÑтуалне) датотеке +. +.SH СÐЖЕТÐК +\fBxzmore\fP [\fIдатотека\fP...] +.br +\fBlzmore\fP [\fIдатотека\fP...] (ЗÐСТÐРЕЛО) +. +.SH ОПИС +\fBxzmore\fP приказује текÑÑ‚ из запакованих датотека у терминалу кориÑтећи +\fBmore\fP(1). Датотеке које подржава \fBxz\fP(1) Ñе раÑпакују; оÑтале датотеке +Ñе подразумева да Ñу већ у незапакованом облику. Ðко није дата ни једна +\fIдатотека\fP, \fBxzmore\fP чита Ñа Ñтандардног улаза. Видите упутÑтво +\fBmore\fP(1) за више информација. +.PP +Знајте да клизање уназад можда неће бити могуће у завиÑноÑти од примене +\fBmore\fP(1). Ово је зато што \fBxzmore\fP кориÑти Ñпојку за проÑлеђивање +раÑпакованих података ка \fBmore\fP(1). \fBxzless\fP(1) кориÑти \fBless\fP(1) које +обезбеђује напреднијим функцијама. +.PP +Ðаредба \fBlzmore\fP Ñе доÑтавља зарад назадне ÑаглаÑноÑти Ñа LZMA +Utils. ЗаÑтарела је и биће уклоњена у будућем издању. +. +.SH ОКРУЖЕЊЕ +.TP +.\" TRANSLATORS: Don't translate the uppercase PAGER. +.\" It is a name of an environment variable. +\fBPAGER\fP +Ðко је \fBPAGER\fP поÑтављено, његова вредноÑÑ‚ Ñе кориÑти као Ñтраничар умеÑто +\fBmore\fP(1). +. +.SH "ВИДИТЕ ТÐКОЂЕ" +\fBmore\fP(1), \fBxz\fP(1), \fBxzless\fP(1), \fBzmore\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sv/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/sv/lzmainfo.1 new file mode 100644 index 000000000..bb72d25c5 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sv/lzmainfo.1 @@ -0,0 +1,42 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Swedish translation of xz-man +.\" Göran Uddeborg , 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 2013\-06\-30 Tukaani "XZ Utils" +.SH NAMN +lzmainfo — visa information lagrad i filhuvudet i .lzma +.SH SYNOPSIS +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fIfil…\fP] +.SH BESKRIVNING +\fBlzmainfo\fP visar information som finns lagrad i filhuvudet i \fB.lzma\fP. Den +läser de första 13 byten frÃ¥n den angivna \fIfilen\fP, avkodar huvudet, och +skriver ut det till standard ut i mänskligt läsbart format. Om inga \fIfiler\fP +anges eller \fIfil\fP är \fB\-\fP, läses standard in. +.PP +Vanligen är den intressantaste informationen den okomprimerade storleken och +lexikonstorleken. Okomprimerad storlek kan endast visas om filen är i den +icke\-strömmande \fB.lzma\fP\-formatvarianten. Mängden minne som krävs för att +dekomprimera filen är nÃ¥gra dussin kilobyte plus lexikonstorleken. +.PP +\fBlzmainfo\fP inkluderas i XZ Utils primärt för bakÃ¥tkompatibilitet med LZMA +Utils. +.SH SLUTSTATUS +.TP +\fB0\fP +Allt är bra. +.TP +\fB1\fP +Ett fel uppstod. +.SH FEL +\fBlzmainfo\fP använder \fBMB\fP medan det korrekta suffixet vore \fBMiB\fP (2²Ⱐ+byte). Detta är för att behÃ¥lla utdata kompatibel med LZMA Utils. +.SH "SE ÄVEN" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sv/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/sv/xz.1 new file mode 100644 index 000000000..1fb596e1a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sv/xz.1 @@ -0,0 +1,1954 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Swedish translation of xz-man +.\" Göran Uddeborg , 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 2025\-03\-08 Tukaani "XZ Utils" +. +.SH NAMN +xz, unxz, xzcat, lzma, unlzma, lzcat — Komprimera eller dekomprimera .xz\- +och .lzma\-filer +. +.SH SYNOPSIS +\fBxz\fP [\fIflagga…\fP] [\fIfil…\fP] +. +.SH KOMMANDOALIAS +\fBunxz\fP är ekvivalent med \fBxz \-\-decompress\fP. +.br +\fBxzcat\fP är ekvivalent med \fBxz \-\-decompress \-\-stdout\fP. +.br +\fBlzma\fP är ekvivalent med \fBxz \-\-format=lzma\fP. +.br +\fBunlzma\fP är ekvivalent med \fBxz \-\-format=lzma \-\-decompress\fP. +.br +\fBlzcat\fP är ekvivalent med \fBxz \-\-format=lzma \-\-decompress \-\-stdout\fP. +.PP +När man skriver skript som behöver dekomprimera filer rekommenderas det att +altid använda namnet \fBxz\fP mäd lämpliga argument (\fBxz \-d\fP eller \fBxz \-dc\fP) +istället för namnen \fBunxz\fP och \fBxzcat\fP. +. +.SH BESKRIVNING +\fBxz\fP är ett datakomprimeringsverktyg för allmänt bruk med en +kommandoradssyntax som liknar \fBgzip\fP(1) och \fBbzip2\fP(1). Det egna +filformatet är formatet \fB.xz\fP, men det förÃ¥ldrade formatet \fB.lzma\fP som +anändes av LZMA\-verktyg och rÃ¥a komprimerade strömmar utan huvuden för +behÃ¥llarformatet stödjs ocksÃ¥. Dessutom stödjs dekomprimering av formatet +\&\fB.lz\fP som används av \fBlzip\fP. +.PP +\fBxz\fP komprimerar och dekomprimerar varje \fIfil\fP i enlighet med det valda +arbetsläget. Om inga \fIfiler\fP anges eller \fIfil\fP är \fB\-\fP läser \fBxz\fP frÃ¥n +standard in och skriver den behandade datan pÃ¥ standard ut. \fBxz\fP kommer +vägra (visa ett felmeddelande och hoppa över \fIfilen\fP) att skriva +komprimerad data direkt till standard ut om det är en terminal. PÃ¥ samma +sätt kommer \fBxz\fP vägra att läsa komprimerade data frÃ¥n standard in om det +är en terminal. +.PP +Om inte \fB\-\-stdout\fP anges skrivs andra \fIfiler\fP än \fB\-\fP till en ny fil vars +namn härleds frÃ¥n käll\fIfilens\fP namn: +.IP \(bu 3 +Vid kompringering läggs suffixet till pÃ¥ mÃ¥lfilsformatet (\fB.xz\fP eller +\&\fB.lzma\fP) pÃ¥ slutet av källfilnamnet för att fÃ¥ mÃ¥lfilnamnet. +.IP \(bu 3 +Vid dekomprimering tas suffixet \fB.xz\fP, \fB.lzma\fP eller \fB.lz\fP bort frÃ¥n +filnamnet för att fÃ¥ mÃ¥lfilnamnet. \fBxz\fP känner även igen suffixen \fB.txz\fP +och \fB.tlz\fP, och ersätter dem med suffixet \fB.tar\fP. +.PP +Om mÃ¥lfilen redan finns visas ett felmeddelande och \fIfilen\fP hoppas över. +.PP +Utom när den skriver till standard ut kommer \fBxz\fP visa en varning och hoppa +över \fIfilen\fP om nÃ¥got av följande inträffar: +.IP \(bu 3 +\fIFil\fP är inte en vanlig fil. Symboliska länkar följs inte, och därför anses +de inte vara vanliga filer. +.IP \(bu 3 +\fIFil\fP har mer än en hÃ¥rd länk. +.IP \(bu 3 +\fIFil\fP har biten setuid, setgid eller sticky satt. +.IP \(bu 3 +Arbetsläget är satt till att komprimera och \fIfilen\fP har redan ett suffix +enligt mÃ¥lfilformatet (\fB.xz\fP eller \fB.txz\fP vid komprimering till formatet +\&\fB.xz\fP, och \fB.lzma\fP eller \fB.tlz\fP vid komprimering till formatet \fB.lzma\fP). +.IP \(bu 3 +Arbetsläget är satt till att dekomprimera och \fIfilen\fP har inte ett suffix +enligt nÃ¥got av de stödda filformaten (\fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP +eller \fB.lz\fP). +.PP +Efter att ha kunnat komprimera eller dekomprimera \fIfilen\fP kopierar \fBxz\fP +ägaren, gruppen, rättigheterna, Ã¥tkomsttiden och ändringstiden frÃ¥n +käll\fIfilen\fP till mÃ¥lfilen. Om kopieringen av grupp misslyckas ändras +rättigheterna sÃ¥ att mÃ¥lfilen inte blir Ã¥tkomlig för användare som inte har +rättigheter att komma Ã¥t käll\fIfilen\fP. \fBxz\fP stödjer inte kopiering av annan +metadata sÃ¥som Ã¥tkomststyrhingslistor eller utökade attribut ännu. +.PP +När mÃ¥lfilen har stängts framgÃ¥ngsrikt tas käll\fIfilen\fP bort sÃ¥vida inte +\fB\-\-keep\fP angavs. Käll\fIfilen\fP tas aldrig bort om utdata skrevs till +standard ut eller om nÃ¥got fel inträffade. +.PP +Att skicka \fBSIGINFO\fP eller \fBSIGUSR1\fP till \fBxz\fP\-processen fÃ¥r den att +skriva ut förloppsinformation till standard fel. Detta är bara av begränsat +värde eftersom när standard fel gÃ¥r till en terminal sÃ¥ kommer användning av +\fB\-\-verbose\fP att skriva ut en automatiskt uppdaterande förloppsindikator. +. +.SS Minnesanvändning +\fBxz\fP:s minnesanvändning varierar frÃ¥n nÃ¥gra fÃ¥ hundra kilobyte till flera +gigabyte beroende pÃ¥ komprimeringsinställningarna. Inställningen som +användes när en fil komprimerades avgör minnesbehovet hos +dekomprimeraren. Typiskt behöver dekomprimeraren 5\ % till 20\ % av +minnesbehovet som komprimeraren behöver när en fil skapas. Till exempel, att +dekomprimera en fil skapad med \fBxz \-9\fP kräver för närvarande 65\ MiB +minne. ÄndÃ¥ är det möjligt att ha \fB.xz\fP\-filer som behöver flera gigabyte +minne för att dekomprimeras. +.PP +Särskilt användare av äldre system kan finna möjligheten av väldigt stor +minnesanvändning störande. För att förhindra obehagliga överraskningar har +\fBxz\fP en inbyggd minnesanvändningsbegränsare, vilken är avaktiverad som +standard. Även om vissa operativsystem kan tillhandahÃ¥lla möjligheter att +begränsa minnesanvändningen hos processer bedömdes det inte som flexibelt +nog att lita pÃ¥ det (till exempel, att använda \fBulimit\fP(1) för att begränsa +det virtuella minnet tenderar att hämma \fBmmap\fP(2). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +Minnesanvändningsbegränsaren kan aktiveras med kommandoradsflaggan +\fB\-\-memlimit=\fP\fIgräns\fP. Ofta är det bekvämare att aktivera begränsaren som +standard genom att sätta miljövariabeln \fBXZ_DEFAULTS\fP, till exempel, +\fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP. Det är möjligt att sätta gränser separat +för komprimering och dekomprimering genom att använda +\fB\-\-memlimit\-compress=\fP\fIlimit\fP och \fB\-\-memlimit\-decompress=\fP\fIlimit\fP. Att +använda dessa tvÃ¥ flaggor utanför \fBXZ_DEFAULTS\fP är sällan meningsfullt +eftersom en enskild körning av \fBxz\fP inte kan göra bÃ¥de komprimering och +dekomprimering och and \fB\-\-memlimit=\fP\fIgräns\fP (eller \fB\-M\fP \fIgräns\fP) är +kortare att skriva pÃ¥ kommandoraden. +.PP +Om den angivna minnesanvändningsgränsen överskrid vid dekomprimering kommer +\fBxz\fP visa ett fel och dekomprimeringen av filen misslyckas. Om gröensen +överskrids vid komprimering kommer \fBxz\fP försöka skala ner inställningen sÃ¥ +att gränsen inte längre överskrids (utom när \fB\-\-format=raw\fP eller +\fB\-\-no\-adjust\fP används). PÃ¥ detta sätt kommer Ã¥tgärden inte misslyckas om +inte gränsen är väldigt liten. Skalningen av inställningen görs i steg som +inte matchar de förinställda komprimeringsnivÃ¥erna, till exempel, om gränsen +endast är nÃ¥got mindre än den mängd som behövs till \fBxz \-9\fP kommer +inställningen bara skalas ner lite, inte hela vägen ner till \fBxz \-8\fP. +. +.SS "Konkatenering och utfyllnad av .xz\-filer" +Det är möjligt att konkatenera \fB.xz\fP\-filer som de är. \fBxz\fP kommer +dekomprimera sÃ¥dana filer som om de vore en enda \fB.xz\fP\-fil. +.PP +Det är möjligt att infoga utfyllnad mellan de konkatenerade delarna eller +efter den sista delen. Utfyllnaden mÃ¥ste bestÃ¥ av null\-bytear och storleken +pÃ¥ utfyllnaden mÃ¥ste vara en multipel av fyra byte. Detta kan vara +användbart, till exempel, om \fB.xz\fP\-filen lagras pÃ¥ ett medium som mäter +filstorlekar i 512\-byteblock. +.PP +Konkaternering och utfyllnad är inte tillÃ¥tet med \fB.lzma\fP\-filer eller rÃ¥a +strömmar. +. +.SH FLAGGOR +. +.SS "Heltalssuffix och speciella värden" +PÃ¥ de flesta platser där ett heltalsargument förväntas stödjs ett frivilligt +suffix för att enkelt indikera stora heltal. Det fÃ¥r inte finnas nÃ¥got +mellanrumm mellan heltalet och suffixet. +.TP +\fBKiB\fP +Multiplicera heltalet med 1 024 (2¹â°). \fBKi\fP, \fBk\fP, \fBkB\fP, \fBK\fP och \fBKB\fP är +tillÃ¥tna som synomymer till \fBKiB\fP. +.TP +\fBMiB\fP +Multiplicera heltalet med 1 048 576 (2²â°). \fBMi\fP, \fBm\fP, \fBM\fP och \fBMB\fP är +tillÃ¥tna som synomymer till \fBMiB\fP. +.TP +\fBGiB\fP +Multiplicera heltalet med 1 073 741 824 (2³â°). \fBGi\fP, \fBg\fP, \fBG\fP och \fBGB\fP +är tillÃ¥tna som synonymer till \fBGiB\fP. +.PP +Specialvärdet \fBmax\fP kan användas för att indikera det maximala heltalet som +stödjs av flaggan. +. +.SS Arbetsläge +Om flera arbetslägesflaggor ges gäller den sista. +.TP +\fB\-z\fP, \fB\-\-compress\fP +Komprimera. Detta är standardarbetsläget när ingen arbetslägesflagga anges +och inget annat arbetsläge impliceras frÃ¥n kommandonamnet (till exempel +implicerar \fBunxz\fP \fB\-\-decompress\fP). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Efter lyckad komprimering källfilen bort sÃ¥vida man inte skriver till +standard ut eller \fB\-\-keep\fP angavs. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Dekomprimera. Efter lyckad dekomprimering tas källfilen bort sÃ¥vida man inte +skriver till standard ut eller \fB\-\-keep\fP angavs. +.TP +\fB\-t\fP, \fB\-\-test\fP +Testa integriteten hos komprimerade \fIfiler\fP. Denna flagga är ekvivalent med +\fB\-\-decompress \-\-stdout\fP förutom att den dekomprimerade datan slängs +istället för att skrivas pÃ¥ standard ut. Inga filer skapas eller tas bort. +.TP +\fB\-l\fP, \fB\-\-list\fP +Skriv information om komprimerade \fIfiler\fP. Inge dekomprimeringsutdata +skapas, och inga filer skapas eller tas bort. I listläge kan programmet inte +läsa komprimerad data frÃ¥n standard in eller frÃ¥n andra källor där man inte +kan söka. +.IP "" +Standardlistningen visar grundläggande information om \fIfiler\fP, en fil per +rad. För att fÃ¥ mer detaljerad information, använd även flaggan +\fB\-\-verbose\fP. För ännu mer information, använd \fB\-\-verbose\fP tvÃ¥ gÃ¥nger, men +observera att detta kan vara lÃ¥ngsamt, eftersom det behövs mÃ¥nga sökningar +fÃ¥r att samla all den extra informationen. Bredden av utförlig utdata +överskrider 80 tecken, sÃ¥ att skicka utdata i ett rör till, till exempel, +\fBless\ \-S\fP kan vara bekvämt om terminalen inte är bred nog. +.IP "" +Den exakta utdatan kan variera mellan versioner av \fBxz\fP och olika +lokaler. För maskinläsbar utdata bör \fB\-\-robot \-\-list\fP användas. +. +.SS Arbetsmodifierare +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ta inte bort indatafilerna. +.IP "" +FrÃ¥n \fBxz\fP 5.2.6 gör denna flagga även att \fBxz\fP komprimerar eller +dekomprimerar även om indatan är en symbolisk länk till en normal fil, har +mer än en hÃ¥rd länk eller har biten setuid, setgid eller sticky +satt. Bitarna setuid, setgid och sticky kopieras inte till mÃ¥lfilen. I +tidigare versioner gjordes detta bara med \fB\-\-force\fP. +.TP +\fB\-f\fP, \fB\-\-force\fP +Denna flagga har flera funktioner: +.RS +.IP \(bu 3 +Om mÃ¥lfilen redan finns, radera den före komprimering eller dekomprimering. +.IP \(bu 3 +Komprimera eller dekomprimera även om indatan är en symbolisk länk till en +normal fil, har mer än en hÃ¥rd länk eller har biten setuid, setgid eller +sticky satt. Bitarna setuid, setgid och sticky kopieras inte till mÃ¥lfilen. +.IP \(bu 3 +När den används med \fB\-\-decompress\fP \fB\-\-stdout\fP och \fBxz\fP inte känner igen +typen pÃ¥ källfilen, kopiera källfilen som den är till standard ut. Detta gör +att \fBxzcat\fP \fB\-\-force\fP kan användas som \fBcat\fP(1) för filer som inte har +komprimerats med \fBxz\fP. Observera att i framtiden kan \fBxz\fP komma att stödja +nya komprimeringsfilformat, vilket kan fÃ¥ \fBxz\fP att dekomprimera fler typer +av filer istället för att kopiera dem till standard ut. +\fB\-\-format=\fP\fIformat\fP kan användas för att begränsa \fBxz\fP till att +dekomprimera endast ett enda filformat. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Skriv den komprimerade eller dekomprimerade datan till standard ut istället +för en fil. Detta implicerar \fB\-\-keep\fP. +.TP +\fB\-\-single\-stream\fP +Dekomprimera endast den första \fB.xz\fP\-strömmen, och ignorera tys eventuella +Ã¥terstÃ¥ende indata som följer efter strömmen. Normalt fÃ¥r sÃ¥dant avslutande +skräp \fBxz\fP att visa ett fel. +.IP "" +\fBxz\fP dekomprimerar aldrig mer än en ström frÃ¥n \fB.lzma\fP\-filer eller rÃ¥a +strömmar, men denna flagga gör ändÃ¥ att \fBxz\fP ignorerar den möjliga +efterföljande datan efter \fB.lzma\fP\-filen eller den rÃ¥a strömmen. +.IP "" +Denna flagga har ingen effekt om arbetsläget inte är \fB\-\-decompress\fP eller +\fB\-\-test\fP. +.IP "" +Sedan \fBxz\fP 5.7.1alpha, implicerar \fB\-\-single\-stream\fP \fB\-\-keep\fP. +.TP +\fB\-\-no\-sparse\fP +Avaktivera att glesa filer skapas. Som standard, om den dekomprimerar till +en normal fil, försöker \fBxz\fP att göra filen gles om den dekomprimerade +datan innehÃ¥ller lÃ¥nga sekvenser av binära nollor. Det fungerar även när den +skriver till standard ut sÃ¥ länga standard ut är kopplad till en normal fil +och vissa ytterligare villkor möts för att göra det säkert. Att skapa glesa +filer kan spara diskutrymme och snabba upp dekomprimeringen genom att +begränsa mängden disk\-I/O. +.TP +\fB\-S\fP \fI.suf\fP, \fB\-\-suffix=\fP\fI.suf\fP +Vid komprimering, använd \fI.suf\fP som suffixet för mÃ¥lfilen istället för +\&\fB.xz\fP eller \fB.lzma\fP. Om den inte skriver till standard ut och källfilen +redan har suffixet \fI.suf\fP visas en varning och filen hoppas över. +.IP "" +Vid dekomprimering, känn igen filer med suffixet \fI.suf\fP utöver filer +medsuffixen \fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP eller \fB.lz\fP. Om källfilen +har suffixet \fI.suf\fP tas suffixet bort för att fÃ¥ mÃ¥lfilnamnet. +.IP "" +Vid komprimering eller dekomprimering av rÃ¥a strömmar (\fB\-\-format=raw\fP) +mÃ¥ste alltid suffixet anges om den inte skriver till standard ut, eftersom +det inte finns nÃ¥got standardsuffix för rÃ¥a strömmar. +.TP +\fB\-\-files\fP[\fB=\fP\fIfil\fP] +Läs filnamnen att arbeta pÃ¥ frÃ¥n \fIfil\fP; om \fIfil\fP utelämnas läses filnamn +frÃ¥n standard in. Filnamn mÃ¥ste avslutas med nyradstecknet. Ett bindestreck +(\fB\-\fP) tas som ett vanligt filnamn; det betyder inte standard in. Om filnamn +även anges som kommandoradsargument, bearbetas de före filnamnen som läses +frÃ¥n \fIfil\fP. +.TP +\fB\-\-files0\fP[\fB=\fP\fIfil\fP] +Detta är identiskt med \fB\-\-files\fP[\fB=\fP\fIfil\fP] förjutom att varje filnamn +mÃ¥ste avslutas med ett nulltecken. +. +.SS "Grundläggande flaggor för filformat och komprimering" +.TP +\fB\-F\fP \fIformat\fP, \fB\-\-format=\fP\fIformat\fP +Angi filens \fIformat\fP att komprimera eller dekomprimera: +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +Detta är standard. Vid komprimering är \fBauto\fP ekvivalent med \fBxz\fP. Vid +dekomprimering detekteras automatiskt formatet pÃ¥ indatafilen. Observera att +rÃ¥a strömmar (skapade med \fB\-\-format=raw\fP inte kan detekteras automatiskt. +.TP +\fBxz\fP +Komprimera till filformatet \fB.xz\fP, eller acceptera endast \fB.xz\fP\-filer vid +dekomprimering. +.TP +\fBlzma\fP, \fBalone\fP +Komprimera till det förÃ¥ldrade filformatet \fB.lzma\fP, eller acceptera endast +\&\fB.lzma\fP\-filer fid dekomprimering. Det alternativa namnet \fBalone\fP +tillhandahÃ¥lls för bakÃ¥tkompatibilitet med LZMA Utils. +.TP +\fBlzip\fP +Acceptera endast \fB.lz\fP\-filer vid dekomprimering. Komprimering stödjs inte. +.IP "" +\&\fB.lz\fP\-formatet version 0 och 1 stödjs. Version 0\-filer producerades av +\fBlzip\fP 1.3 och tidigare. SÃ¥dana filer är inte vanliga men kan hittas frÃ¥n +filarkiv eftersom nÃ¥gra källpaket släpptes i detta format. Folk kan ha även +ha gamla personliga filer i detta format. Dekomprimeringsstöd för format +version 0 togs bort i \fBlzip\fP 1.18. \fBlzip\fP 1.4 och senare kan skapa filer i +formatversion 1. +.TP +\fBraw\fP +Komprimera eller dekomprimera en rÃ¥ ström (inga huvuden). Detta är endast +avsett för avancerade användare. För att avkoda rÃ¥a strömmar behöver man +använda \fB\-\-format=raw\fP och explicit angi filterkedjan, vilken normalt +skulle ha lagrats i behÃ¥llarens huvuden. +.RE +.TP +\fB\-C\fP \fIkontroll\fP, \fB\-\-check=\fP\fIkontroll\fP +Ange typen av integritetskontroll. Kontrollen beräknas frÃ¥n den +dekomprimerade datan och lagras i \fB.xz\fP\-filen. Denna flagga har endast +nÃ¥gon inverkan när man komprimerar till formatet \fB.xz\fP; formatet \fB.lzma\fP +stödjer inte integritetskontroller. Integritetskontrollen (om nÃ¥gon) +verifieras när \fB.xz\fP\-filen dekomprimeras. +.IP "" +\fIKontroll\fPtyper som stödjs: +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +Beräkna inte nÃ¥gon integritetskontroll alls. Detta är normalt en dÃ¥lig +idé. Det kan vara användbart när datans integritet ändÃ¥ verifieras pÃ¥ andra +sätt. +.TP +\fBcrc32\fP +Beräkna CRC32 med polynomet frÃ¥n IEEE\-802.3 (Ethernet). +.TP +\fBcrc64\fP +Beräkna CRC64 med polynomet frÃ¥n ECMA\-182. Detta är standard, eftersom det +är nÃ¥got bättre än CRC32 pÃ¥ att upptäcka skadade filer och +hastighetsskillnaden är försumbar. +.TP +\fBsha256\fP +Beräkna SHA\-256. Detta är nÃ¥got lÃ¥ngsammare än CRC32 och CRC64. +.RE +.IP "" +Integriteten hos \fB.xz\fP\-huvuden verifieras alltid med CRC32. Det är inte +möjligt att ändra eller avaktivera det. +.TP +\fB\-\-ignore\-check\fP +Verifiera inte integritetskontrollen av den komprimerade datan vid +dekomprimering. CRC32\-värden i \fB.xz\fP\-huvudena kommer fortfarande verifieras +normalt +.IP "" +\fBAnvänd inte denna flagga om du inte vet vad du gör.\fP Möjliga anledningar +till att använda denna flagga: +.RS +.IP \(bu 3 +Försöka Ã¥tervinna data frÃ¥n en trasig .xz\-fil. +.IP \(bu 3 +Snabba upp dekomprimering. Detta har störst betydelse med SHA\-256 eller med +filer som har komprimerats extremt mycket. Det rekommenderas att inte +använda denna flagga för detta ändamÃ¥l om inte filintegriteten verifieras +externt pÃ¥ nÃ¥got annat sätt. +.RE +.TP +\fB\-0\fP … \fB\-9\fP +Välj en förinställningsnivÃ¥ för komprimering. Standard är \fB\-6\fP. Om flera +förinställningsnivÃ¥er anges gäller den sist angivna. Om en anpassad +fileterkedja redan angivits gör en inställning av en förinställningsnivÃ¥ för +komprimering att den anpassade filterkedjan töms. +.IP "" +Skillnaden mellan förinställningarna har större betydelse än med \fBgzip\fP(1) +och \fBbzip2\fP(1). Den valda komprimeringsinställningen avgör minneskraven för +dekomprimeraren, att använda en för hög förinställningsnivÃ¥ kan alltsÃ¥ göra +det plÃ¥gsamt att dekomprimera filer pÃ¥ ett gammalt system med lite +RAM. Specifikt \fBär det inte en bra ide att blint använda \-9 för allt\fP +liksom det ofta är med \fBgzip\fP(1) och \fBbzip2\fP(1). +.RS +.TP +\fB\-0\fP … \fB\-3\fP +Dessa är ganska snabba förinställningar. \fB\-0\fP är ibland snabbare än \fBgzip \-9\fP samtidigt som komprimeringen är mycket bättre. De högre har ofta +hastighet jämförbar med \fBbzip2\fP(1) med jämförbar eller bättre +komprimeringsförhÃ¥llande, även om resultatet mycket beror pÃ¥ typen av data +som komprimeras. +.TP +\fB\-4\fP … \fB\-6\fP +Bra för väldigt god komprimering samtidigt som dekomprimerarens +minnesanvändning hÃ¥lls rimlig även pÃ¥ gamla system. \fB\-6\fP är standardvärdet, +vilket vanligen är ett bra val för att distribuera filer so behöver +dekomprimeras även pÃ¥ ssytem med endast 16\ MiB RAM. (\fB\-5e\fP eller \fB\-6e\fP +kan ocksÃ¥ vara värda att överväga. Se \fB\-\-extreme\fP.) +.TP +\fB\-7 … \-9\fP +Dessa liknar \fB\-6\fP med med högre krav pÃ¥ minne till komprimerare och +dekomprimerare. Dessa är bara användbara vid komprimering av filer större än +8\ MiB, 16\ MiB respektive 32\ MiB. +.RE +.IP "" +PÃ¥ samma hÃ¥rdvara är dekomprimeringshastigheten ungefär ett konstant antal +byt av komprimerad data per sekund. Med andra ord, ju bättre komprimering, +desto snabbare kommer dekomprimeringen vanligen vara. Detta betyder även att +mängden av okomprimerad utdata skapad per sekund kan variera mycket. +.IP "" +Följande tabell sammanfattar funktionerna hos förinställningarna: +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Förinställning;LexStrl;KompCPU;KompMin;DekMin +\-0;256 KiB;0;3 MiB;1 MiB +\-1;1 MiB;1;9 MiB;2 MiB +\-2;2 MiB;2;17 MiB;3 MiB +\-3;4 MiB;3;32 MiB;5 MiB +\-4;4 MiB;4;48 MiB;5 MiB +\-5;8 MiB;5;94 MiB;9 MiB +\-6;8 MiB;6;94 MiB;9 MiB +\-7;16 MiB;6;186 MiB;17 MiB +\-8;32 MiB;6;370 MiB;33 MiB +\-9;64 MiB;6;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Kolumnbeskrivningar: +.RS +.IP \(bu 3 +LexStrl är storleken pÃ¥ LZMA2:s lexikon. Det är slöseri med minne att +använda ett större lexikon än storleken pÃ¥ den okomprimerade filen. Detta är +anledningen till att det är bra att undvika förinställningarna \fB\-7\fP … \fB\-9\fP +när det inte finns nÃ¥got verkligt behov av dem. PÃ¥ \fB\-6\fP och lägre är +mängden bortslösat minne vanligen litet nog att inte ha nÃ¥gon betydelse. +.IP \(bu 3 +KompCPU är en förenklad representation av LZMA2\-inställningar som pÃ¥verkar +komprimeringshastigheten. Lexikonstorleken pÃ¥verkar ocksÃ¥ hastigheten, sÃ¥ +medan KompCPU är samma för nivÃ¥erna \fB\-6\fP … \fB\-9\fP tenderar fortfarande högre +nivÃ¥er att vara lite lÃ¥ngsmmare. För ännu lÃ¥ngsammare och möjligen bättre +komprimering, se \fB\-\-extreme\fP. +.IP \(bu 3 +KompMem innehÃ¥ller komprimerarens minneskrav i enkeltrÃ¥dat läge. Det kan +variera nÃ¥got mellan versioner av \fBxz\fP. +.IP \(bu 3 +DekMin innehÃ¥ller dekomprimerarens minneskrav. Det vill säga, komprimerarens +inställningar avgör minneskravet för dekomprimeraren. Den exakta +minnesanvändningen hos dekomprimeraren är nÃ¥got mer än +LZMA2\-lexikonstorleken, men värdena i tabellen har avrundats upp till nästa +nästa hela MiB. +.RE +.IP "" +Minneskravet för det multitrÃ¥dade läget är signifikant högre än det för +enkeltrÃ¥dat läge. Med standardvärdet pÃ¥ \fB\-\-block\-size\fP behöver varje trÃ¥d +3·3·LexStrl plus KompMin eller DekMin. Till exempel, fyra trÃ¥dar med +förinställningen behöver 660\(en670 MiB minne. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +Använd en lÃ¥ngsammare variant av den valda förinställningsnivÃ¥n för +komprimering (\fB\-0\fP … \fB\-9\fP) för att förhoppningsvis fÃ¥ lite bättre +komprimeringsförhÃ¥llande, men med otur kan detta även göra det +sämre. Dekomprimerarens minnesanvändning pÃ¥verkas inte, men komprimerarens +minnesanvändning ökar lite vid förinställningsnivÃ¥erna \fB\-0\fP … \fB\-3\fP. +.IP "" +Eftersom det finns tvÃ¥ förinställningar med lexikonstorlekar 4\ MiB och 8\ MiB använder förinställningarna \fB\-3e\fP och \fB\-5e\fP nÃ¥got snabbare +inställningar (lägre KompCPU) än \fB\-4e\fP respektive \fB\-6e\fP. PÃ¥ det sättet är +inte tvÃ¥ förinställningar identiska. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Förinställning;LexStrl;KompCPU;KompMin;DekMin +\-0e;256 KiB;8;4 MiB;1 MiB +\-1e;1 MiB;8;13 MiB;2 MiB +\-2e;2 MiB;8;25 MiB;3 MiB +\-3e;4 MiB;7;48 MiB;5 MiB +\-4e;4 MiB;8;48 MiB;5 MiB +\-5e;8 MiB;7;94 MiB;9 MiB +\-6e;8 MiB;8;94 MiB;9 MiB +\-7e;16 MiB;8;186 MiB;17 MiB +\-8e;32 MiB;8;370 MiB;33 MiB +\-9e;64 MiB;8;674 MiB;65 MiB +.TE +.RE +.RE +.IP "" +Till exempel finns det totalt fyra förinställningar som använder 8\ MiB +lexikon, vars ordning frÃ¥n den snabbaste till den lÃ¥ngsammaste är \fB\-5\fP, +\fB\-6\fP, \fB\-5e\fP och \fB\-6e\fP. +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +Dessa är nÃ¥got missledande alias för \fB\-0\fP respektive \fB\-9\fP. Dessa finns +endast för bakÃ¥tkompatibilitet med LZMA\-verktyg. Undvik att använda dessa +flaggor. +.TP +\fB\-\-block\-size=\fP\fIstorlek\fP +Vid komprimering till formatet \fB.xz\fP, dela indatai block med \fIstorlek\fP +bytes. Blocken komprimeras oberoende av varandra, vilket hjälper till vid +multitrÃ¥dning och gör begränsad random\-access\-dekomprimering möjlig. Denna +flagga används typiskt för att Ã¥sidosätta blockstorleken i multitrÃ¥dat läge, +men denna flagga kan användas även i enkeltrÃ¥dat läge. +.IP "" +I multitrÃ¥dat läge kommer ungefär tre gÃ¥nger \fIstorlek\fP byte att allokeras i +varje trÃ¥d för buffring av indata och utdata. Standardvärdet pÃ¥ \fIstorlek\fP +är det större av tre gÃ¥nger LZMA2\-lexikonstorleken eller 1 MiB. Typiskt är +ett bra värde 2\(en4 gÃ¥nger storleken pÃ¥ LZMA2\-lexikonet eller Ã¥tminstone 1 +MiB. Att använda en \fIstorlek\fP mindre än LZMA2\-lexikonstorleken utgör +slöseri med RAM eftersom LZMA2\-lexikonbufferten dÃ¥ aldrig kommer användas +helt. I multitrÃ¥dat läge lagras storlekarna pÃ¥ plocken i +blockhuvudena. Denna storleksinformation krävs för multitrÃ¥dad +dekomprimering. +.IP "" +I singletrÃ¥dat läge görs som standard ingen uppdelning i block. Att göra +denna inställning pÃ¥verark inte minnesanvändningen. Ingen +storleksinformation lagras i blockhuvuden, därmed kommer filer som skapas i +enkeltrÃ¥dat läge inte att vara identiska med filer skapade i multitrÃ¥dat +läge. Avsaknaden av sotrleksinformation betyder ocksÃ¥ att \fBxz\fP inte kommer +kunna dekomprimera filerna i multitrÃ¥dat läge. +.TP +\fB\-\-block\-list=\fP\fIposter\fP +Vid komprimering till formatet \fB.xz\fP, börja ett nytt block med en möjlig +anpassad filterkedja efter de angivna intervallen med okomprimerade data. +.IP "" +\fIPosterna\fP är en kommaseparerad lista. Varje post bestÃ¥r av ett möjligt +filterkedjenummer mellan 0 och 9 följt av ett kolon (\fB:\fP) och en +obligatorisk storlek för okomprimerade data. Att utelämna en post (tvÃ¥ pÃ¥ +varandra följande komman) är en kortform för att använda storleken och +filtren frÃ¥n föregÃ¥ende post. +.IP "" +Om indatafiler är större än summan av storlekarna i \fIposter\fP repeteras den +sista posten fram till slutet pÃ¥ filen. Ett speciellt värde \fB0\fP kan +användas som den sista storleken för att indikera att resten av filen skall +kodas som ett enda block. +.IP "" +En alternativ filterkedja för varje block kan anges i kombinaton med +flaggorna \fB\-\-filters1=\fP\fIfilter\fP \&…\& \fB\-\-filters9=\fP\fIfilter\fP. Dessa +flaggor definierar filterkedjor med en identifierare mellan +1\(en9. Filterkedja 0 kan användas för att referera till +standardfilterkedjan, vilket är samma sak som att inte ange nÃ¥gon +filterkedja. Filterkedjeidentifierare kan användas före den okomprimerade +sotrleken, följt av ett kolon (\fB:\fP). Till exempel, om man anger +\fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP kommer block skapas med: +.RS +.IP \(bu 3 +Filterkedjan angiven av \fB\-\-filters1\fP och 2 MiB indata +.IP \(bu 3 +Filterkedjan angiven av \fB\-\-filters3\fP och 2 MiB indata +.IP \(bu 3 +Filterkedjan angiven av \fB\-\-filters2\fP och 4 MiB indata +.IP \(bu 3 +Filterkedjan angiven av \fB\-\-filters2\fP och 4 MiB indata +.IP \(bu 3 +Standardfilterkedjan och 2 MiB indata +.IP \(bu 3 +Standardfilterkedjan och 4 MiB indata för varje block till slutet av indata. +.RE +.IP "" +Om man anger en storlek som överskrider kodarens blockstorlek (antingen +standardvärdet i trÃ¥dat läge eller värdet som anges med +\fB\-\-block\-size=\fP\fIstorlek\fP) kommer kodaren skapa ytterligare block med +hänsyn taget till gränserna som anges i \fIposter\fP. Till exempel, om man +anger \fB\-\-block\-size=10MiB\fP \fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP och +indatafilen är 80 MiB kommer man fÃ¥ 11 block: 5, 10, 8, 10, 2, 10, 10, 4, +10, 10 och 1 MiB. +.IP "" +I multitrÃ¥dat läge lagras storleken pÃ¥ blocken i blockhuvudena. Detta görs +inte i enkeltrÃ¥dat läge, sÃ¥ den kodade utdatan kommer inte vara identisk med +den frÃ¥n det multitrÃ¥dade läget. +.TP +\fB\-\-flush\-timeout=\fP\fItidsgräns\fP +Vid komprimering, om mer än \fItidsgräns\fP millisekunder (ett positivt heltal) +har gÃ¥tt sedan den föregÃ¥nde tömningen och en läsning av mer indata skulle +blockera töms all väntande indata frÃ¥n kodaren och görs tillgänglig i +utdataströmmen. Detta kan vara användbart om \fBxz\fP används för att +komprimera data som strömmas över ett nätverk. SmÃ¥ värden pÃ¥ \fItidsgräns\fP +gör data tillgänglig vid den mottagande änden med en liten fördröjning, men +större värden pÃ¥ \fItidsgräns\fP ger bättre komprimeringsförhÃ¥llande. +.IP "" +Denna funktion är avaktiverad som standard. Om denna flagga anges mer än en +gÃ¥ng gäller den sista. Dett speciella värdet \fB0\fP pÃ¥ \fItidsgräns\fP kan +användas för att uttryckligen avaktivera denna funktion. +.IP "" +Denna funktion är inte tillgänglig pÃ¥ icke\-POSIX\-system. +.IP "" +.\" FIXME +\fBDenna funktion är fortfarande experimentell.\fP För närvarande är \fBxz\fP +olämplig för dekomprimering av strömmen i realtid pÃ¥ grund av hur \fBxz\fP +buffrar. +.TP +\fB\-\-no\-sync\fP +Synkronisera inte mÃ¥lfilen och dess katalog med lagringsenheten före +källfilen tas bort. Detta kan förbättra prestanda vid komprimering eller +dekomprimering av mÃ¥nga smÃ¥ filer. Dock, om systemet kraschar snart efter +raderingen är det möjligt att mÃ¥lfilen inte skrevs till lagringsenheten men +att raderingen gjordes det. I det fallet är varken originalkällfilen eller +mÃ¥lfilen tillgänglig. +.IP "" +Denna flagga har bara nÃ¥gon effekt när \fBxz\fP kommer att ta bort källfilen. I +andra fall görs aldrig nÃ¥gon synkronisering. +.IP "" +Synkroniseringen och \fB\-\-no\-sync\fP lades till i \fBxz\fP 5.7.1alpha. +.TP +\fB\-\-memlimit\-compress=\fP\fIgräns\fP +Sätt en gräns pÃ¥ minnesanvändningen för komprimeringen. Om denna flaggan +anges flera gÃ¥nger gäller den sista. +.IP "" +Om komprimeringsinställnigarna överskrider \fIgränsen\fP kommer \fBxz\fP försöka +justera inställningarna nerÃ¥t sÃ¥ att gränsen inte längre överskrids och visa +en notis om att en automatisk justering gjorts. Justeringen görs i denna +ordning: reducera antalet trÃ¥dar, byta till enkeltrÃ¥dat läge om även en trÃ¥d +i multitrÃ¥dat läge överskrider \fIgränsen\fP och slutligen reducera +LZMA2\-lexikonstorleken. +.IP "" +Vid komprimering med \fB\-\-format=raw\fP eller om \fB\-\-no\-adjust\fP har angetts kan +endast antalet trÃ¥dar reduceras eftersom det kan göras utan att pÃ¥verka den +komprimerade utdatan. +.IP "" +Om \fIgränsen\fP inte kan uppfyllas ens med justeringarna som beskrivs ovan +visas ett felmeddelande och \fBxz\fP kommer avsluta med slutstatus 1. +.IP "" +\fIGränsen\fP kan anges pÃ¥ flera sätt: +.RS +.IP \(bu 3 +\fIGränsen\fP kan vara ett absolut värde i byte. Att använda ett heltalssuffix +som \fBMiB\fP kan vara praktiskt. Exempel: \fB\-\-memlimit\-compress=80MiB\fP +.IP \(bu 3 +\fIGränsen\fP kan anges som en procentsats av det totala fysiska minnet +(RAM). Detta kan vara användbart särskilt när man sätter miljövariabeln +\fBXZ_DEFAULTS\fP i ett skalinitieringsskript som delas mellan olika +datorer. PÃ¥ det sättet är gränsen automatiskt större pÃ¥ system med mer +minne. Exempel: \fB\-\-memlimit\-compress=70%\fP +.IP \(bu 3 +\fIGränsen\fP kan Ã¥terställas tillbaka till sitt standardvärde genom att sätta +den till \fB0\fP. Detta är för närvarande ekvivalent med att sätta \fIgränsen\fP +till \fBmax\fP (ingen gräns pÃ¥ minnesanvändning). +.RE +.IP "" +För 32\-bitars \fBxz\fP finns det ett specialfall: om \fIgränsen\fP skulle vara +över \fB4020\ MiB\fP sätts \fIgränsen\fP till \fB4020\ MiB\fP. PÃ¥ MIPS32 används +\fB2000\ MiB\fP istället. (Värdena \fB0\fP och \fBmax\fP pÃ¥verkas inte av detta. En +liknande funktion finns inte för dekomprimering.) Detta kan hjälpa till när +ett 32\-bitarsprogram har tillgÃ¥ng till 4\ GiB adressrymd (2 GiB pÃ¥ MIPS32) +förhoppningsvis utan att göra nÃ¥gon skada i andra situationer. +.IP "" +Se även avsnittet \fBMinnesanvändning\fP. +.TP +\fB\-\-memlimit\-decompress=\fP\fIgräns\fP +Sätt en gräns för minnesanvnändningen vid dekomprimering. Detta pÃ¥verkar +även läget \fB\-\-list\fP. Om Ã¥tgärden inte är möjlig utan att överskrida +\fIgränsen\fP kommer \fBxz\fP visa ett felmeddelande och dekomprimeringen av filen +kommer misslyckas. Se \fB\-\-memlimit\-compress=\fP\fIgräns\fP för möjliga sätt att +ange \fIgränsen\fP. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fIgräns\fP +Sätt en gräns för minnesanvändningen för multitrÃ¥dad dekomprimering. Detta +kan endast pÃ¥verka antalet trÃ¥dar; det kommer aldrig att fÃ¥ \fBxz\fP att vägra +att dekomprimera en fil. Om \fIgränsen\fP är för lÃ¥g för att tillÃ¥ta nÃ¥gon +multitrÃ¥dning ignoreras \fIgränsen\fP och \fBxz\fP kommer gÃ¥ vidare i enkeltrÃ¥dat +läge. Observera att om även \fB\-\-memlimit\-decompress\fP används kommer det +alltid att gälla bÃ¥de enkeltrÃ¥dat och multitrÃ¥dat läge, och därmed kommer +den gällande \fIgränsen\fP för multitrÃ¥dning aldrig vara högre än gränsen som +sätts med \fB\-\-memlimit\-decompress\fP. +.IP "" +Till skillnad mot de andra flaggorna för gränser för minnesanvändning har +\fB\-\-memlimit\-mt\-decompress=\fP\fIgräns\fP en systemspecifik +standard\fIgräns\fP. \fBxz \-\-info\-memory\fP kan användas för att se det aktuella +värdet. +.IP "" +Denna flagga och dess standardvärde finns för att utan nÃ¥gon gräns skulle +den trÃ¥dade dekomprimeraren kunna allokera en vansinnig mängd minne med +nÃ¥gra indatafiler. Om standard\fIgränsen\fP är för lÃ¥g pÃ¥ ditt system, öka dÃ¥ +gärna \fIgränsen\fP men sätt den aldrig till ett större värde än mängden +användbart RAM eftersom att med passande indatafiler kommer \fBxz\fP försöka +använda den mängden av minne även med ett lÃ¥gt antal trÃ¥dar. Att fÃ¥ slut pÃ¥ +minne ller växling kommer inte förbättra dekomprimeringsprestandan. +.IP "" +Se \fB\-\-memlimit\-compress=\fP\fIgräns\fP för möjliga sätt att ange \fIgränsen\fP. Att +sätta \fIgräns\fP till \fB0\fP Ã¥terställer \fIgränsen\fP till sdet systemspecifika +standardvärdet. +.TP +\fB\-M\fP \fIgräns\fP, \fB\-\-memlimit=\fP\fIgräns\fP, \fB\-\-memory=\fP\fIgräns\fP +Detta är ekvivalent med att ange \fB\-\-memlimit\-compress=\fP\fIgräns\fP +\fB\-\-memlimit\-decompress=\fP\fIgräns\fP \fB\-\-memlimit\-mt\-decompress=\fP\fIgräns\fP. +.TP +\fB\-\-no\-adjust\fP +Visa ett fel och avsluta om gränsen för minnesanvändning inte kan mötas utan +att justera inställnigar som pÃ¥verkar den komprimerade utdatan. Det vill +säga, detta förhindrar att \fBxz\fP byter kodaren frÃ¥n multitrÃ¥dat läge till +enkeltrÃ¥dat läge och frÃ¥n att den reducerar LZMA2\-lexikonets storlek. Även +när denna flagga används kan antalet trÃ¥dar reduceras för att möta gränsen +för minnesanvändning eftersom det inte kommer pÃ¥verka den komprimerade +utdatan. +.IP "" +Automatisk justering är alltid avaktiverat när rÃ¥a strömmar skapas +(\fB\-\-format=raw\fP). +.TP +\fB\-T\fP \fItrÃ¥dar\fP, \fB\-\-threads=\fP\fItrÃ¥dar\fP +Ange antalet arbetstrÃ¥dar som skall användas. Att sätta \fItrÃ¥dar\fP till ett +specialvärde \fB0\fP gör att \fBxz\fP använder sÃ¥ mÃ¥nga trÃ¥dar som processorerna +pÃ¥ systemet stödjer. Det aktuella antalet trÃ¥dar kan vara färre än \fItrÃ¥dar\fP +om indatafilen inte är stor nog för trÃ¥dning med de givna inställningarna +eller om användning av fler trÃ¥dar skulle överkrida gränsen för +minnesanvändning. +.IP "" +De enkeltrÃ¥dade och multitrÃ¥dade komprimerarna producerar olika utdata. Den +enkeltrÃ¥dade komprimeraren kommer ge den minsta filstorleken men endast +utdata frÃ¥n den multitrÃ¥dade komprimeraren kan dekomprimeras med flera +trÃ¥dar. Att sätta \fItrÃ¥dar\fP till \fB1\fP kommer använda enkeltrÃ¥dat läge. Att +sätta \fItrÃ¥dar\fP till nÃ¥got annat värde, inklusive \fB0\fP, kommer använda den +multitrÃ¥dade komprimeraren även om systemet endast stödjer en hÃ¥rdvarutrÃ¥d. +(\fBxz\fP 5.2.x använde enkeltrÃ¥dat läge i denna situation.) +.IP "" +För att använda multitrÃ¥dat läge med endast en trÃ¥d, sätt \fItrÃ¥dar\fP till +\fB+1\fP. Prefixet \fB+\fP har ingen pÃ¥vrekan för andra värden än \fB1\fP. En gräns +för minnesanvändning kan fortfarande göra att \fBxz\fP byter till enkeltrÃ¥dat +läge sÃ¥vida inte \fB\-\-no\-adjust\fP används. Stöd för prefixet \fB+\fP lades till i +\fBxz\fP 5.4.0. +.IP "" +Om ett automatiskt antal trÃ¥dar har begärts och ingen gräns för +minnesanvändning har angivits, dÃ¥ kommer en systemspecifik mjuk +standardgräns användas för att möjligen begränsa antalet trÃ¥dar. Det är en +mjuk gräns i den meningen att den ignoreras om antalet trÃ¥dar blir en, +alltsÃ¥ kommer en mjuk gräns aldrig hindra \fBxz\fP frÃ¥n att komprimera eller +dekomprimera. Denna mjuka standardgräns kommer inte göra att \fBxz\fP byter +frÃ¥n multitrÃ¥dat läge till enkeltrÃ¥dat läge. De aktiva gränserna kan ses med +\fBxz \-\-info\-memory\fP. +.IP "" +För närvarande är den enda trÃ¥dningsmetoden att dela indata i block och +komprimera dem oberoende av varandra. Standardstorleken pÃ¥ block beror pÃ¥ +komprimeringsnivÃ¥n och kan Ã¥sidosättas med flaggan +\fB\-\-block\-size=\fP\fIstorlek\fP. +.IP "" +TrÃ¥dad dekomprimering fungerar bara pÃ¥ filer som innehÃ¥ller flera block med +storleksinformation i blockhuvuden. Alla tillräckligt stora filer +komprimeras i multitrÃ¥dat läge för att uppfylla detta villkor, men filer +komprimerade i enkeltrÃ¥dat läge gör det inte ens om +\fB\-\-block\-size=\fP\fIstorlek\fP har använts. +.IP "" +Standardvärdet pÃ¥ \fItrÃ¥dar\fP är \fB0\fP. I \fBxz\fP 5.4.x och tidigare är +standardvärdet \fB1\fP. +. +.SS "Anpassade komprimerarfilterkedjor" +Med en anpassad filterkedja kan man specificera kompressionsinställningarna +i detalj istället för att lita pÃ¥ inställningarna som hör till +förinställningarna. När en anpassad filterkedja anges glöms +förinställningsflaggor (\fB\-0\fP \&…\& \fB\-9\fP och \fB\-\-extreme\fP) tidigare pÃ¥ +kommandoraden. Om en förinställningsflagga anges efter en eller flera +flaggor för anpassade filterkedjor gäller den nya förinställningen och de +flaggor för anpassade filterkedjor som angivits tidigare glöms. +.PP +En filterkedja är jämförbar med att skapa rör pÃ¥ kommando. Vid komprimering +skickas den okomprimerade indatan till det första filtret, vars utdata +skickas till nästa filter (om nÃ¥got). Utdatan frÃ¥n det sista filtret blir +skrivet till den komprimerade filen. Det maximala antalet filter i kedjan är +fyra, men typiskt har en filterkedja bara ett ellet tvÃ¥ filter. +.PP +MÃ¥nga filter har begränsningar pÃ¥ var de kan finnas i filterkedjan: nÃ¥gra +filter kan bara fungera som det sista filtret i kedjan, nÃ¥gra bara om de +inte är det sista filtret, och nÃ¥gra fungerar i godtycklig position i +kedjan. Beroende pÃ¥ filtret är denna begränsning antingen en egenskap hos +filterdesignen eller finns för att förhindra säkerhetsproblem. +.PP +En anpassad filterkedja kan anges pÃ¥ tvÃ¥ olika sätt. Med flaggorna +\fB\-\-filters=\fP\fIfilter\fP och \fB\-\-filters1=\fP\fIfilter\fP \&…\& +\fB\-\-filters9=\fP\fIfilter\fP kan man ange en hel filterkedja med en flagga genom +att använda syntaxen för liblzma\-filtersträngar. Alternativt kan en +filterkedja anges genom att använda en eller flera individuella +filterflaggor i den ordning de önskas i filterkedjan. Det vill säga, +ordningen pÃ¥ de individuella filterflaggorna är signifikant! Vid avkodning +av rÃ¥a strömmar (\fB\-\-format=raw\fP) mÃ¥ste filterkedjan anges i samma ordning +som den specificerades vid komprimeringen. Eventuella individuella filter\- +eller förinstiällningsflaggor angivna före den fullständiga +filterkedjeflaggan (\fB\-\-filters=\fP\fIfilter\fP) kommer glömmas. Individuella +filter som anges efter den flaggan för en full kedja kommer Ã¥terställa +filterkedjan. +.PP +BÃ¥de den fullständiga och de individuella filterflaggorna tar +filterspecifika \fIflaggor\fP som en kommaseparerad lista. Extra komman +\fIflaggor\fP ignoreras. Varje flagga har ett standardvärde, sÃ¥ ange dem du +vill ändra. +.PP +För att se hela filterkedjan och \fIflaggor\fP, använd \fBxz \-vv\fP (det vill +säga, använd \fB\-\-verbose\fP tvÃ¥ gÃ¥nger). Detta fungerar även för att se +flaggorna för filterkedjor som används av förinställningar. +.TP +\fB\-\-filters=\fP\fIfilter\fP +Ange den fullständiga filterkedan eller en förinställning en en enda +flagga. Varje filter kan separeras med blanktecken eller tvÃ¥ bindestreck +(\fB\-\-\fP). \fIfilter\fP kan behöva citeras pÃ¥ skalets kommandorad sÃ¥ att det +tolkas som en enda flagga. För att beteckna \fIflaggor\fP, använd \fB:\fP eller +\fB=\fP. En förinställning kan föregÃ¥s med ett \fB\-\fP och följas av noll eller +flera flaggor. Den enda flaggan som stödjs är \fBe\fP för att tillämpa samma +flaggor som \fB\-\-extreme\fP. +.TP +\fB\-\-filters1\fP=\fIfilter\fP … \fB\-\-filters9\fP=\fIfilter\fP +Ange upp till nio ytterligare filterkedjor som kan användas med +\fB\-\-block\-list\fP. +.IP "" +Till exempel, vid komprimering av ett arkiv med körbara filer följt av +textfiler skulle den körbara delen kunna använda en filterkedja med ett +BCJ\-filter och endast textdelen med LZMA2\-filtret. +.TP +\fB\-\-filters\-help\fP +Visa ett hjälpmeddelande som beskriver hur man anger förinställningar och +anpassade filterkedjor i flaggorna \fB\-\-filters\fP och \fB\-\-filters1=\fP\fIfilter\fP +\&…\& \fB\-\-filters9=\fP\fIfilter\fP, och avsluta rent. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fIflaggor\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fIflaggor\fP] +.PD +Lägg till LZMA1\- eller LZMA2\-filter till filterkedjan. Dessa filter kan +endast användas som det sista filtret i kedjan. +.IP "" +LZMA1 är ett förÃ¥ldrat filter, vilket stödjs nästan enbart pÃ¥ grund av det +förÃ¥ldrade filformatet \fB.lzma\fP, vilket bara stödjer LZMA1. LZMA2 är en +uppdaterad version av LZMA1 för att lösa nÃ¥gra praktiska problem med +LZMA1. Formatet \fB.xz\fP använder LZMA2 och stödjer inte LZMA1 +alls. Komprimeringshastigheten och förhÃ¥llandena för LZMA1 är LZMA2 är +praktiskt taget desamma. +.IP "" +LZMA1 och LZMA2 delar samma uppättning \fIflaggor\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fIförinställning\fP +Ã…terställ alla LZMA1\- eller LZMA2\-\fIflaggor\fP till +\fIförinställning\fP. \fIFörinställning\fP bestÃ¥r av ett heltal, vilket kan följas +av enskilda bokstäver som modifierar förinställningen. Heltalet kan vara +frÃ¥n \fB0\fP till \fB9\fP, motsvarande kommandoradsflaggorna \fB\-0\fP \&…\& +\fB\-9\fP. Den enda modifierare som stödjs för närvarande är \fBe\fP, vilket +motsvarar \fB\-\-extreme\fP. Om ingen \fBpreset\fP anges tas standardvärden pÃ¥ +LZMA1\- eller LZMA2\-\fIflaggor\fP frÃ¥n förinställningen \fB6\fP. +.TP +\fBdict=\fP\fIstorlek\fP +Ett lexikons (historiebufferts) \fIstorlek\fP indikerar hur mÃ¥nga byte med +nyligen bearbetad okomprimerad data som hÃ¥lls i minnet. Algoritmen försöker +hitta Ã¥terkommande bytesekvenser (matchningar) i den okomprimerade datan, +och ersätta dem med referenser till datan som för närvarande finns i +lexikonet. Ju större lexikon, desto högre är sannolikheten att hitta en +matchning. Att öka lexikonets \fIstorlek\fP förbättrar alltsÃ¥ vanligen +komprimeringsförhÃ¥llandet, men ett lexikon som är större än den +okomprimerade filen är ett slöseri med minne. +.IP "" +En typisk \fIstorlek\fP pÃ¥ lexikon är frÃ¥n 64\ KiB till 64\ MiB. Minimum är 4\ KiB. Det maximala för komprimering är för närvarande 1,5\ GiB (1536\ MiB). Dekomprimeraren stödjer redan lexikon upp till en byte mindre än 4\ GiB, vilket är det maximala för strömformaten LZMA1 och LZMA2. +.IP "" +Lexikon\fIstorlek\fP och matchhittaren (\fImf\fP) avgör tillsammans +minnesanvändningen för LZMA1\- eller LZMA2\-kodaren. Ett lika \fIstort\fP (eller +större) lexikon behövs för dekomprimering som det som användes vid +komprimeringen, minnesanvändningen för avkodaren avgörs alltsÃ¥ av +lexikonstorleken vid komprimering. Huvudena i \fB.xz\fP innehÃ¥ller lexikonets +\fIstorlek\fP antingen som 2^\fIn\fP eller 2^\fIn\fP + 2^(\fIn\fP\-1), sÃ¥ dessa +\fIstorlekar\fP är lite att föredra för komprimering. Andra \fIstorlekar\fP kommer +avrundas uppÃ¥t när de lagras i huvuden i \fB.xz\fP. +.TP +\fBlc=\fP\fIlk\fP +Ange antalet literala kontextbitar. Minimum är 0 och maximum är 4; +standardvärdet är 3. Dessutom fÃ¥r inte summan av \fIlk\fP och \fIlp\fP överskrida +4. +.IP "" +Alla byte som inte kan kodas som matchningar kodas som literaler. Det vill +säga, literaler är helt enkelt 8\-bits byte som kodas en Ã¥t gÃ¥ngen. +.IP "" +Den literala kodningen gör antagandet att de högsta \fIlk\fP bitarna av den +föregÃ¥ende okomprimerade byten korrelerar med nästa byte. Till exempel, i +typisk engelsk text följs ofta en versal bokstav av en gemen bokstav, och en +gemen bokstav följs vanligen av en annan gemen bokstav. I +teckenuppsättningen US\-ASCII är de högsta tre bitarna 010 för versala +bokstäver och 011 för gemena bokstäver. När \fIlk\fP är Ã¥tminstone 3 kan den +literala kodningen dra nytta av denna egenskap i den okomprimerade datan. +.IP "" +Standardvärdet (3) är normalt bra. Om man vill ha maximal komprimering, +prova \fBlc=4\fP. Ibland hjälper det lite, och ibland gör det komprimeringen +sämre. Om det gör den sämre, testa ocksÃ¥ \fBlc=2\fP. +.TP +\fBlp=\fP\fIlp\fP +Ange antalet literala positionsbitar. Minimum är 0 och maximum är 4; +standardvärdet är 0. +.IP "" +\fILp\fP pÃ¥verkar vilken sorts justering i den okomprimerade datan som antas +vid kodning av literaler. Se \fIpb\fP nedan för mer information om justering. +.TP +\fBpb=\fP\fIpb\fP +Ange antalet positionsbitar. Minimum är 0 och maximum är 4; standardvärdet +är 2. +.IP "" +\fIPb\fP pÃ¥verkar vilken sort justering i den okomprimerade datan som antas i +allmänhet. Standardvärdet betyder fyrbytejustering (2^\fIpb\fP=2^2=4), vilket +ofta är ett bra val när det inte finns nÃ¥gon bättre gissning. +.IP "" +När justeringen är känd kan en inställning av \fIpb\fP därefter reducera +filstorleken nÃ¥got. Till exempel, med textfiler som har en\-byte\-justering +(US\-ASCII, ISO\-8859\-*, UTF\-8) kan att sätta \fBpb=0\fP förbättra komprimeringen +nÃ¥got. För UTF\-16\-text är \fBpb=1\fP ett bra val. Om justeringen är ett udda +tal som 3 byte kan \fBpb=0\fP vara det bästa valet. +.IP "" +Även om den antagna justeringen kan anpassas med \fIpb\fP och \fIlp\fP föredrar +LZMA1 och LZMA2 ändÃ¥ nÃ¥got 16\-byte\-justering. Det kan vara värt att ta med i +beräkningen vid design av filformat som sannolikt ofta kan komma att +komprimeras med LZMA1 eller LZMA2. +.TP +\fBmf=\fP\fIms\fP +Matchsökaren har en stor poverkan pÃ¥ kodarens hastighet, minnesanvändning +och komprimeringsförhÃ¥llande. Vanligen är Hashkedje\-matchsökare snabbare än +Binärträdsmatchsökare. Standardvärdet beror pÃ¥ \fIföinställningen\fP: 0 +använder \fBhc3\fP, 1\(en3 använder \fBhc4\fP, och resten använder \fBbt4\fP. +.IP "" +Följande matchsökare stödjs. Formlerna för minnesanvändning nedan är grova +uppskattningar, vilka är närmast sanningen när \fIdict\fP är en tvÃ¥potens. +.RS +.TP +\fBhc3\fP +Hashkedja med 2\- och 3\-bytehashning +.br +Minsta värde pÃ¥ \fInice\fP: 3 +.br +Minnesanvändning: +.br +\fIdict\fP · 7.5 (om \fIdict\fP ≤ 16 MiB); +.br +\fIdict\fP · 5,5 + 64 MiB (om \fIdict\fP > 16 MiB) +.TP +\fBhc4\fP +Hashkedja med 2\-, 3\- och 4\-bytehashning +.br +Minsta värde pÃ¥ \fInice\fP: 4 +.br +Minnesanvändning: +.br +\fIdict\fP · 7,5 (om \fIdict\fP ≤ 32 MiB); +.br +\fIdict\fP · 6,5 (om \fIdict\fP > 32 MiB) +.TP +\fBbt2\fP +Binärträd med 2\-bytehashning +.br +Minsta värde pÃ¥ \fInice\fP: 2 +.br +Minnesanvändning: \fIdict\fP · 9,5 +.TP +\fBbt3\fP +Binärträd med 2\- och 3\-bytehashning +.br +Minsta värde pÃ¥ \fInice\fP: 3 +.br +Minnesanvändning: +.br +\fIdict\fP · 11,5 (om \fIdict\fP ≤ 16 MiB); +.br +\fIdict\fP · 9,5 + 64 MiB (om \fIdict\fP > 16 MiB) +.TP +\fBbt4\fP +Binärträd med 2\-, 3\- och 4\-bytehashning +.br +Minsta värde pÃ¥ \fInice\fP: 4 +.br +Minnesanvändning: +.br +\fIdict\fP · 11,5 (om \fIdict\fP ≤ 32 MiB); +.br +\fIdict\fP · 10,5 (om \fIdict\fP > 32 MiB) +.RE +.TP +\fBmode=\fP\fIläge\fP +Komprimerings\fIläget\fP anger metoden som används för att analysera data +skapade av matchsökaren. De \fIlägen\fP som stödjs är \fBfast\fP och +\fBnormal\fP. Standardvärdet är \fBfast\fP för \fIförinställningarna\fP 0\(en3 och +\fBnormal\fP för \fIförinställningarna\fP 4\(en9 +.IP "" +Vanligen används \fBfast\fP med Hashkedjematchsökare och \fBnormal\fP med +Binärträdsmatchsökare. Detta är även vad \fIförinställningarna\fP gör. +.TP +\fBnice=\fP\fIlagom\fP +Ange vad som anses vara en lagom längt pÃ¥ en matchning. När en matchning pÃ¥ +Ã¥tminstone \fIlagom\fP byte hittats slutar algoritmen söka efter möjliga bättre +matchningar. +.IP "" +\fILagom\fP kan vara 2\(en273 byte. Högre värden tenderar att ge bättre +komprimeringsförhÃ¥llande pÃ¥ bekostnad av tid. Standardvärdet beror pÃ¥ +\fIförinställningen\fP. +.TP +\fBdepth=\fP\fIdjup\fP +Ange det maximala sökdjupet i matchsökaren. Standardvärdet är specialvärdet +0, vilket fÃ¥r komprimeraren att avgöra ett lämpligt \fIdjup\fP frÃ¥n \fImf\fP och +\fInice\fP. +.IP "" +Lämpligt \fIdjup\fP för Hashkedjor är 4\(en100 och 16\(en1000 för +Binärträd. Att använda väldigt höga värden pÃ¥ \fIdjup\fP kan göra kodaren +extremt lÃ¥ngsam för vissa filer. Undvik att sätta \fIdjup\fP över 1000 sÃ¥vida +du inte är beredd att avbryta komprimeringen om den tar för lÃ¥ng tid. +.RE +.IP "" +Vid avkodning av rÃ¥a strömmar (\fB\-\-format=raw\fP) behöver LZMA2 endast +lexikonets \fIstorlek\fP. LZMA1 behöver även \fIlc\fP, \fIlp\fP och \fIpb\fP. +.TP +\fB\-\-x86\fP[\fB=\fP\fIflaggor\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fIflaggor\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fIflaggor\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fIflaggor\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fIflaggor\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fIflaggor\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fIflaggor\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIflaggor\fP] +.PD +Lägg till gren/anrop/hopp\-filter (branch/call/jump, BCJ) till +filterkedjan. Dessa filter kan inte användas som det sista filtret i +filterkedjan. +.IP "" +Ett BCJ\-filter konverterar relativa adresser i maskinkod till deras absoluta +motsvarigheter. Detta ändrar inte storleken pÃ¥ datan men det ökar +redundansen, vilket kan hjälpa LZMA2 att skapa 0\(en15\ % mindre +\&\fB.xz\fP\-filer. BCJ\-filtren är alltid reversibla, sÃ¥ att använda ett +BCJ\-filter för fel sorts data orsakar inte nÃ¥gon dataförlust, men det kan +göra komprimeringsförhÃ¥llandet nÃ¥got sämre. BCJ\-filtren är mycket snabba +och använder en obetydling mängd minne. +.IP "" +Dessa BCJ\-filter har kända problem kopplade till komprimeringsförhÃ¥llandet: +.RS +.IP \(bu 3 +NÃ¥gr sortes filer som innehÃ¥ller körbar kod (till exempel, objektfiler, +statiska bibliotek och Linux kärnmoduler) har adresserna i instruktionerna +fyllda med utfyllnadsvärden. Dessa BCJ\-filter kommer ändÃ¥ göra +adresskonverteringen, vilket kommer göra komprimeringen sämre för dessa +filer. +.IP \(bu 3 +Om ett BCJ\-filter används pÃ¥ ett arkiv är det möjligt att det gör +komprimeringsförhÃ¥llandet sämre än att inte använda nÃ¥got BCJ\-filter. Till +exempel, om det finns liknande eller till och med identiska körbara kommer +filtreringen sannolikt göra filerna mindre lika och därmed blir +kompressionen sämre. InnehÃ¥llet i icke körbara filer i samma arkiv kan ocksÃ¥ +spela en roll. I praktiken mÃ¥ste man prova med och utan ett BCJ\-filter för +att se vilket som är det bästa i varje situation. +.RE +.IP "" +Olika instruktionsuppsättningar har olika justering: den körbara filen mÃ¥ste +vara justerad till en multipel av detta värde i indata för att filtret skall +fungera. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +Filter;Justering;Kommentarer +x86;1;32\-bitars eller 64\-bitars x86 +ARM;4; +ARM\-Thumb;2; +ARM64;4;4096\-bytesjustering är bäst +PowerPC;4;Endast rak byteordning +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +Eftersom BCJ\-filtrerad data vanligen komprimeras med LZMA2 kan +komprimeringsförhÃ¥llandet förbättras nÃ¥got om LZMA2\-flaggorna sätts till att +matcha justeringen hos det valda BCJ\-filtret. Exempel: +.RS +.IP \(bu 3 +IA\-64\-filter har 16\-bytejustering sÃ¥ \fBpb=4,lp=4,lc=0\fP är bra med LZMA2 +(2â´=16). +.IP \(bu 3 +RISC\-V\-kod har 2\-byte\- eller 4\-bytejustering beroende pÃ¥ huruvida filen +innehÃ¥ller 16\-bitars komprimerade instruktioner (utvidgningen C). När +16\-bitarsinstruktioner används är \fBpb=2,lp=1,lc=3\fP eller \fBpb=1,lp=1,lc=3\fP +bra. När det inte finns nÃ¥gra 16\-bitsinstruktioner är \fBpb=2,lp=2,lc=2\fP +bäst. \fBreadelf \-h\fP kan användas för att kontrollera om â€RVC†förekommer pÃ¥ +raden â€Flaggorâ€. +.IP \(bu 3 +ARM64 är alltid 4\-bytejusterad sÃ¥ \fBpb=2,lp=2,lc=2\fP är bäst. +.IP \(bu 3 +Filtret x86 är ett undantag. Det är normalt bra att hÃ¥lla sig till LZMA2:s +standardvärden (\fBpb=2,lp=0,lc=3\fP) när körbar x86 komprimeras. +.RE +.IP "" +Alla BCJ\-filter stödjer samma \fIflaggor\fP: +.RS +.TP +\fBstart=\fP\fIavstÃ¥nd\fP +Ange start\fIavstÃ¥ndet\fP som används vid konvertering mellan relativa och +absoluta adresser. \fIAvstÃ¥ndet\fP mÃ¥ste vara en multipel av filtrets justering +(se tabellen ovan). Standardvärdet är noll. I praktiken är standardvärdet +bra; det är nästan aldrig användbart att ange ett anpassat \fIavstÃ¥nd\fP. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fIflaggor\fP] +Lägg till Deltafiltret till filterkedjan. Deltafiltret kan inte användas som +det sista filtret i filterkedjan. +.IP "" +För närvarande stödjs bara enkel byte\-vis deltaberäkning. Det kan vara +användbart vid komprimering, till exempel av okomprimerade +bitavbildningsbilder eller okomprimerad PCM\-audio. Dock kan algoritmer för +särskilda ändamÃ¥l ge betydligt bättre resultat än Delta + LZMA2. Detta är +särskilt sant med audio, vilket komprimerar snabbare och bättre med till +exempel \fBflac\fP(1). +.IP "" +Stödda \fIflaggor\fP: +.RS +.TP +\fBdist=\fP\fIavstÃ¥nd\fP +Ange \fIavstÃ¥ndet\fP för deltaberäkningen i byte. \fIAvstÃ¥nd\fP mÃ¥ste varea +1\(en256. Standardvärdet är 1. +.IP "" +Till exempel, med \fBdist=2\fP och Ã¥tta byte indata A1 B1 A2 B3 A3 B5 A4 B7, +kommer utdata vara A1 B1 01 02 01 02 01 02. +.RE +. +.SS "Andra flaggor" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Utelämna varningar och noteringar. Ange detta tvÃ¥ gÃ¥nger för att även +utelämna felmeddelandet. Denna flagga har ingen pÃ¥verkan pÃ¥ +slutstatusen. Det vill säga, även om en varning utelämnades kommer +slutstatusen fortfarandeindikera att en varning gavs. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +Var utförlig. Om standard fel är kopplat till en terminal kommer \fBxz\fP visa +en förloppsmätare. Att ange \fB\-\-verbose\fP tvÃ¥ gÃ¥nger kommer ge än mer +utförlig utmatning. +.IP "" +Förloppsmätaren visar följande information: +.RS +.IP \(bu 3 +Procent färdigt visas om storleken pÃ¥ indatafilen är känd. Det vill säga, +procentsatsen kan inte visas i rör. +.IP \(bu 3 +Mängd komprimerad data som producerats (komprimering) eller konsumerats +(dekomprimering). +.IP \(bu 3 +Mängd okomprimerad data som konsumerats (komprimering) eller producerats +(dekomprimering). +.IP \(bu 3 +KomprimeringsförhÃ¥llande, vilket beräknas genom att dividera mängden +komprimerad data bearbetad sÃ¥ lÃ¥ng med mängde okomprimerad data bearbetad sÃ¥ +lÃ¥ngt. +.IP \(bu 3 +Kompressions eller dekompressionshastighet. Detta mäts som mängden +okomprimerad data konsumerad (komprimering) eller producerad +(dekomprimering) per sekund. Det visas efter att nÃ¥gra sekunder har gÃ¥t +efter att \fBxz\fP började bearbeta filen. +.IP \(bu 3 +Förfluten tid pÃ¥ formatet MM:SS eller H:MM:SS. +.IP \(bu 3 +Beräknad Ã¥terstÃ¥ende tid visas endast när storleken pÃ¥ indatafilen är känd +och nÃ¥gra sekunder redan gÃ¥tt efter att \fBxz\fP började bearbeta filen. Tiden +visas i ett mindre precist format vilket aldrig har nÃ¥gra kolon, till +exempel, 2 min 30 s. +.RE +.IP "" +När standard fel inte är en terminal kommer \fB\-\-verbose\fP göra att \fBxz\fP +skriver filnamnet, komprimerad storlek, okomprimerad storlek, +komprimeringsförhÃ¥llande och möjligen även hastigheten och den förlupna +tiden pÃ¥ en enda rad till standard fel efter att ha komprimerat eller +dekomprimerat filen. Hastigheten och den förlupna tiden inkluderas endast +när Ã¥tgärden tog Ã¥tminstone nÃ¥gra sekunder. Om Ã¥tgärden inte slutfördes, +till exempel för att användaren avbröt, skrivs även den fullbordade +procentsatsen om storleken pÃ¥ indatafilen är känd. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Sätt inte slutstatus till 2 även om ett tillstÃ¥nd som är värt en varning +upptäcktes. Denna flagga pÃ¥verkar inte utförlighetsnivÃ¥n, allts mÃ¥ste bÃ¥de +\fB\-\-quiet\fP och \fB\-\-no\-warn\fP användas för att inte visa varningar och för att +inte ändra slutstatusen. +.TP +\fB\-\-robot\fP +Skriv meddelanden i maskinläsbart form. Detta är avsett att förenkla att +skriva framändar som vill använda \fBxz\fP istället för liblzma, vilken kan +vara fallet i olika skript. Utdatan med denna flagga aktiverad är avsedd att +vara stabil mellan utgÃ¥vor av \fBxz\fP. Se avsnitett \fBROBOTLÄGE\fP för detaljer. +.TP +\fB\-\-info\-memory\fP +Visa, pÃ¥ mänskligt läsbar form, hur mycket fysiskt minne (RAM) och hur mÃ¥nga +processortrÃ¥dar \fBxz\fP tror att systemet har och gränserna för +minnesanvändning vid komprimering och dekomprimering, och avsluta. +.TP +\fB\-h\fP, \fB\-\-help\fP +Visa ett hjälpmeddelande som beskriver de vanligast använda flaggorna, och +avsluta. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +Visa ett hjälpmeddelande som beskriver alla funktioner i \fBxz\fP, och avsluta +.TP +\fB\-V\fP, \fB\-\-version\fP +Visa versionsnumret för \fBxz\fP och liblzma i mänskligt läsbar form. För att +fÃ¥ maskinläsbar utdata, ange \fB\-\-robot\fP före \fB\-\-version\fP. +. +.SH ROBOTLÄGE +Robotläget aktiveras med flaggan \fB\-\-robot\fP. Det gör att utdata frÃ¥n \fBxz\fP +är enklare att tolka av andra program. För närvarande stödjs \fB\-\-robot\fP +endast tillsammans med \fB\-\-list\fP, \fB\-\-filters\-help\fP, \fB\-\-info\-memory\fP och +\fB\-\-version\fP. Den kommer att stödjas för komprimering och dekomprimering i +framtiden. +. +.SS Listläge +\fBxz \-\-robot \-\-list\fP använder tab\-separerad utmatning. Första kolumnen av +varje rad har en sträng som indikerar typen av informationen som finns pÃ¥ +den raden: +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP +Detta är alltid första raden när en fil börjar listas. Den andra kolumen pÃ¥ +raden är filnamnet. +.TP +\fBfile\fP +Denna rad innehÃ¥ller övergripande information om \fB.xz\fP\-filen. Denna rad +skrivs alltid efter raden \fBname\fP. +.TP +\fBstream\fP +Denna radtyp används endast när \fB\-\-verbose\fP angetts. Det finns lika mÃ¥nga +\fBstream\fP\-rader som det finns strömmar i \fB.xz\fP\-filen. +.TP +\fBblock\fP +Denna radtyp används bara när \fB\-\-verbose\fP angetts. Det finns lika mÃ¥nga +\fBblock\fP\-rader som det finns block i \fB.xz\fP\-filen. \fBblock\fP\-rader visas +efter alla \fBstream\fP\-raderna; olika radtyper blandas inte. +.TP +\fBsummary\fP +Denna radtyp används bara när \fB\-\-verbose\fP angetts tvÃ¥ gÃ¥nger. Denna rad +skrivs eefter alla \fBblock\fP\-rader. Liksom raden \fBfile\fP inenhÃ¥ller raden +\fBsummary\fP övergripande information om \fB.xz\fP\-filen. +.TP +\fBtotals\fP +Denna rad är alltid den allra sista raden i listutmatningen. Den visar det +totala antalen och storlekarna. +.PP +Kolumnerna pÃ¥ \fBfile\fP\-raderna: +.PD 0 +.RS +.IP 2. 4 +Antalet strömmar i filen +.IP 3. 4 +Totalt antal block i strömmarna +.IP 4. 4 +Komprimerad storlek pÃ¥ filen +.IP 5. 4 +Okomprimerad storlek pÃ¥ filen +.IP 6. 4 +KomprimeringsförhÃ¥llande, till exempel \fB0.123\fP. Om förhÃ¥llandet är över +9.999 visas tre bindestreck (\fB\-\-\-\fP) istället för förhÃ¥llandet. +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +Kommaseparerad lista med integritetskontrollnamn. Följande strängar används +för de kända kontrolltyperna: \fBNone\fP, \fBCRC32\fP, \fBCRC64\fP och +\fBSHA\-256\fP. För okända kontrolltyper används \fBUnknown\-\fP\fIN\fP, där \fIN\fP är +kontroll\-ID:t som ett decimalt nummer (en eller tvÃ¥ siffror). +.IP 8. 4 +Total storlek pÃ¥ strömutfyllnad i filen +.RE +.PD +.PP +Kolumnerna pÃ¥ \fBstream\fP\-raderna: +.PD 0 +.RS +.IP 2. 4 +Strömnummer (den första strömmen är 1) +.IP 3. 4 +Antal block i strömmen +.IP 4. 4 +Komprimerat startavstÃ¥nd +.IP 5. 4 +Okomprimerat startavstÃ¥nd +.IP 6. 4 +Komprimerad storlek (inkluderar inte strömutfyllnad) +.IP 7. 4 +Okomprimerad storlek +.IP 8. 4 +KomprimeringsförhÃ¥llande +.IP 9. 4 +Namnet pÃ¥ integritetskontrollen +.IP 10. 4 +Storleken pÃ¥ strömutfyllnad +.RE +.PD +.PP +Kolumnerna pÃ¥ \fBblock\fP\-raderna: +.PD 0 +.RS +.IP 2. 4 +Numret pÃ¥ strömmen som innehÃ¥ller detta block +.IP 3. 4 +Blocknummer relativt början pÃ¥ strömmen (det första blocket är 1) +.IP 4. 4 +Blocknummer relativt början pÃ¥ filen +.IP 5. 4 +Komprimerat startavstÃ¥nd relativt början av filen +.IP 6. 4 +Okomprimerat startavstÃ¥nd relativt början av filen +.IP 7. 4 +Total komprimerad storlek pÃ¥ blocket (inkluderar huvuden) +.IP 8. 4 +Okomprimerad storlek +.IP 9. 4 +KomprimeringsförhÃ¥llande +.IP 10. 4 +Namnet pÃ¥ integritetskontrollen +.RE +.PD +.PP +Om \fB\-\-verbose\fP angavs tvÃ¥ gÃ¥nger inkluderas ytterligare kolumner pÃ¥ +\fBblock\fP\-raderna. Dessa visas inte med bara ett \fB\-\-verbose\fP, eftersom det +för att fÃ¥ fram denna information krävs mÃ¥nga sökningar och kan därmed vara +lÃ¥ngsamt: +.PD 0 +.RS +.IP 11. 4 +Värdet pÃ¥ integritetskontrollen hexadecimalt +.IP 12. 4 +Blockhuvudstorlek +.IP 13. 4 +Blockflaggor: \fBc\fP indikerar att komprimerad storlek finns, och \fBu\fP +indikerar att okomprimerad storlek finns. Om flaggan inte är satt visas ett +bindestreck (\fB\-\fP) istället för att hÃ¥lla stränglängden fast. Nya flaggor +kan läggas till i slutet av strängen i frmtiden. +.IP 14. 4 +Storlek pÃ¥ den faktiska komprimerade datan i blocket (detta utelämnar +blockhuvud, blockutfyllnad och kontrollfält) +.IP 15. 4 +Mängd minne (i byte) som behövs för att dekomprimera detta block med denna +version av \fBxz\fP +.IP 16. 4 +Filterkedja. Observera att de flesta av flaggorna som användes vid +komprimeringstillfället inte kan vara kända, eftersom endat de flaggor som +behövs för dekomprimering lagras i \fB.xz\fP\-huvudet. +.RE +.PD +.PP +Kolumnerna pÃ¥ \fBsummary\fP\-raderna: +.PD 0 +.RS +.IP 2. 4 +Mängd minne (i byte) som behövs för att dekomprimera denna fil med denna +version av \fBxz\fP +.IP 3. 4 +\fByes\fP eller \fBno\fP som indikerar om alla blockhuvuden bÃ¥de har komprimerad +storlek och okomprimerad storlek i sig +.PP +\fIFrÃ¥n\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +Minsta version av \fBxz\fP som krävs för att dekomprimera filen +.RE +.PD +.PP +Kolumnerna pÃ¥ \fBtotals\fP\-raden: +.PD 0 +.RS +.IP 2. 4 +Antal strömmar +.IP 3. 4 +Antal block +.IP 4. 4 +Komprimerad storlek +.IP 5. 4 +Okomprimerad storlek +.IP 6. 4 +Genomsnittligt komprimeringsförhÃ¥llande +.IP 7. 4 +Kommaseparerad lista med integritetskontrollnamn som fanns i filerna +.IP 8. 4 +Strömutfyllnadsstorlek +.IP 9. 4 +Antal filer. Denna finns här för att hÃ¥lla ordningen av de tidigare +kolumnerna desamma som pÃ¥ \fBfile\fP\-rader. +.PD +.RE +.PP +Om \fB\-\-verbose\fP angavs tvÃ¥ gÃ¥nger inkluderas ytterligare kolumner pÃ¥ +\fBtotals\fP\-raden: +.PD 0 +.RS +.IP 10. 4 +Maximal mängd minne (i byte) som behövs för att dekomprimera filerna med +denna version av \fBxz\fP +.IP 11. 4 +\fByes\fP eller \fBno\fP som indikerar om alla blockhuvuden bÃ¥de har komprimerad +storlek och okomprimerad storlek i sig +.PP +\fIFrÃ¥n\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +Minsta version av \fBxz\fP som krävs för att dekomprimera filen +.RE +.PD +.PP +Framtida versioner kan lägga till fler radtyper och fler kolumner kan läggas +til pÃ¥ de befintliga radtyperna, men de befintliga kolumnerna kommmer inte +ändras. +. +.SS Filterhjälp +\fBxz \-\-robot \-\-filters\-help\fP skriver ut de filter som stödjs i följande +format: +.PP +\fIfilter\fP\fB:\fP\fIflagga\fP\fB=<\fP\fIvärde\fP\fB>,\fP\fIflagga\fP\fB=<\fP\fIvärde\fP\fB>\fP… +.TP +\fIfilter\fP +Namn pÃ¥ filtret +.TP +\fIflagga\fP +Namn pÃ¥ en filterspecifik flagga +.TP +\fIvärde\fP +Numeriska \fIvärde\fPintervall ser ut som +\fB<\fP\fImin\fP\fB\-\fP\fImax\fP\fB>\fP. Sträng\fIvärdes\fP val visas inom \fB< >\fP och separerade med ett \fB|\fP\-tecken. +.PP +Varje filter skrivs pÃ¥ en egen rad. +. +.SS Minnesgränsinformation +\fBxz \-\-robot \-\-info\-memory\fP skriver en rad med flera tab\-separerade +kolumner: +.IP 1. 4 +Total mängd med fysiskt minne (RAM) i byte. +.IP 2. 4 +Minnesanvändningsgräns för komprimering i byte (\fB\-\-memlimit\-compress\fP). Ett +specialvärde \fB0\fP indikerar standardinställningen vilken för enkeltrÃ¥dat +läge är detsamma som ingen gräns. +.IP 3. 4 +Minnesanvändningsgräns för dekomprimering i byte +(\fB\-\-memlimit\-decompress\fP). Ett specialvärde \fB0\fP indikerar +standdartinställningen vilken för enkeltrÃ¥dat läge är detsamma som ingen +gräns. +.IP 4. 4 +FrÃ¥n \fBxz\fP 5.3.4alpha: Minnesanvändningen för multitrÃ¥dad dekomprimering i +byte (\fB\-\-memlimit\-mt\-decompress\fP). Detta är aldrig noll eftersom ett +systemspecifikt standardvärde som visas i kolumn 5 används om ingen gräns +har angivits uttryckligen. Detta är heller aldrig större än värdet i kolumn +3 även om ett större värde har angivits med \fB\-\-memlimit\-mt\-decompress\fP. +.IP 5. 4 +FrÃ¥n \fBxz\fP 5.3.4alpha: Ett systemspecifikt standardgräns för +minnesanvändning som används för att begränsa antalet trÃ¥dar vid +komprimering med ett automatiskt antal trÃ¥dar (\fB\-\-threads=0\fP) och ingen +gräns för minnesanvändning har angivits (\fB\-\-memlimit\-compress\fP). Detta +används även som standardvärdet pÃ¥ \fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +FrÃ¥n \fBxz\fP 5.3.4alpha: antal tillgängliga processortrÃ¥dar. +.PP +I framtiden kan utdata frÃ¥n \fBxz \-\-robot \-\-info\-memory\fP ha fler kolumner, +men aldrig mer än en rad. +. +.SS Version +\fBxz \-\-robot \-\-version\fP skriver versionsnumret pÃ¥ \fBxz\fP och liblzma i +följande format: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +Huvudversion. +.TP +\fIYYY\fP +Underversion. Jämna nummer är stabila. Udda nummer är alfa\- eller +betaversioner. +.TP +\fIZZZ\fP +RättningsnivÃ¥ för stabila utgÃ¥vor eller bara en räknare för +utvecklingsutgÃ¥vor. +.TP +\fIS\fP +Stabilitet. 0 är alfa, 1 beta beta och 2 är stabil. \fIS\fP skall alltid vara +2 när \fIYYY\fP är jämnt. +.PP +\fIXYYYZZZS\fP är samma pÃ¥ bÃ¥da raderna om \fBxz\fP och liblzma kommer frÃ¥n samma +utgÃ¥va av XZ Utils. +.PP +Exempel: 4.999.9beta är \fB49990091\fP och 5.0.0 är \fB50000002\fP. +. +.SH SLUTSTATUS +.TP +\fB0\fP +Allt är bra. +.TP +\fB1\fP +Ett fel uppstod. +.TP +\fB2\fP +NÃ¥got värt en varning uppstod, men inga faktiska fel uppstod. +.PP +Noteringar (inte varningar eller fel) som skrivs pÃ¥ standard fel pÃ¥verkar +inte slutstatusen. +. +.SH MILJÖ +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP tolkar mellanrumsseparerade listor av flaggor frÃ¥n miljövariablerna +\fBXZ_DEFAULTS\fP och \fBXZ_OPT\fP, i den ordningen, före flaggorna pÃ¥ +kommandoraden. Observera att endast flaggor tolkas frÃ¥n miljövariablerna; +alla andra argument än flaggor ignoreras tyst. Tolkningen görs med +\fBgetopt_long\fP(3) vilket även används för kommandoradsargumenten. +.PP +\fBVarning:\fP genom att sätta dessa miljövariabler ändrar man i praktiken +program och skript som kör \fBxz\fP. för det mesta är set säkert att sätta +begränsningar pÃ¥ minnesanvändning, antal trÃ¥dar och komprimeringsflaggor via +miljövariablerna. NÃ¥gra flaggor kan dock göra att skript gÃ¥r sönder. Ett +uppenbart exempel är \fB\-\-help\fP vilket gör att \fBxz\fP visar en hjälptext +istället för att komprimera eller dekomprimera en fil. Mer subtila exempel +är \fB\-\-quiet\fP och \fB\-\-verbose\fP. I mÃ¥nga fall fungerar det bra att aktivera +en förloppsindikator med \fB\-\-verbose\fP, men i nÃ¥gra fall skapar de extra +meddelandena problem. UtförlighetsnivÃ¥n pÃ¥verkar även beteendet hos +\fB\-\-list\fP. +.TP +\fBXZ_DEFAULTS\fP +Användarspecifika eller systemspecifika standardflaggor. Typiskt sätts detta +i ett initieringsskript för skal för att aktivera \fBxz\fP:s begränsning av +minnesanvändning som standard eller att ställa in ett standardantal +trÃ¥dar. Med undantag för skalinitieringsskript och liknande specialfall +skall skript aldrig sätta eller ta bort \fBXZ_DEFAULTS\fP. +.TP +\fBXZ_OPT\fP +Detta är för att skicka flaggor till \fBxz\fP när det inte är möjligt att sätta +flaggorna direkt pÃ¥ kommandoraden för \fBxz\fP. Detta är fallet när \fBxz\fP körs +av ett skript eller verktyg, till exempel, GNU \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf apa.tar.xz apa\fR +.fi +.RE +.RE +.IP "" +Skript kan använda \fBXZ_OPT\fP, till exempel, för att sätta skriptspecifika +standardflaggor för komprimering. Det rekommenderas fortfarande att tillÃ¥ta +användaren att Ã¥sidosätta \fBXZ_OPT\fP om det är rimligt. Till exempel, i +\fBsh\fP(1)\-skript kan man använda nÃ¥got i still med detta: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "KOMPATIBILITET MED LZMA UTILS" +Kommandoradssyntaxen för \fBxz\fP är praktiskt taget en utökning av \fBlzma\fP, +\fBunlzma\fP och \fBlzcat\fP sÃ¥ som de kommer frÃ¥n LZMA Utils 4.32.x. I de flesta +fall, är det möjligt att ersätta LZMA Utils med XZ Utils utan att göra +sönder befintliga skript. Det finns dock nÃ¥gra inkompatibiliteter, vilka +ibland kan orsaka problem. +. +.SS "Komprimeringens förinställda nivÃ¥er" +Numreringen av förinställda nivÃ¥er för komprimering är inte identiska i +\fBxz\fP och LZMA Utils. Den viktigaste skillnade är hur lexikonstorlekar +avbildas till olika förinställningar. Lexikonstorleken är i stort sett lika +med dekomprimerarens minnesanvändning. +.RS +.PP +.TS +tab(;); +c c c +c n n. +NivÃ¥;xz;LZMA Utils +\-0;256 KiB;N/A +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +Lexikonstorlekens skillnader pÃ¥verkar komprimerarens minnesanvändning ocksÃ¥, +men det finns nÃ¥gra andra skillnader mellan LZMA Utils och XZ Utils, vilket +gör skillnaden ännu större: +.RS +.PP +.TS +tab(;); +c c c +c n n. +NivÃ¥;xz;LZMA Utils 4.32.x +\-0;3 MiB;N/A +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +StandardförinställningsninvÃ¥n i LZMA Utils är \fB\-7\fP medan i XZ Utils är den +\fB\-6\fP, sÃ¥ bÃ¥da använder ett 8 MiB lexikon som standard. +. +.SS "Strömmade visavi icke strömmade .lzma\-filer" +Den ikomprimerade storleken pÃ¥ filen kan lagras i huvudet i \fB.lzma\fP. LZMA +Utils gör det när den komprimerar normala filer. Alternativet är att markera +att den okomprimerade storleken är okänd och använda en markör för lastslut +för att indikera var dekomprimeraren skall stanna. LZMA Utils använder denna +metod när den okomprimerade storleken inte är känd, vilket är fallet, till +exempel, i rör. +.PP +\fBxz\fP stödjer dekomprimering av \fB.lzma\fP\-filer med eller utan markör för +lastslut, men alla \fB.lzma\fP filer som skapas av \fBxz\fP kommer använda markör +för lastslut och ha den okomprimerade storleken markerad som okänd i +\&\fB.lzma\fP\-huvudet. Detta kan bli ett problem i nÃ¥gra ovanliga fall. Till +exempel kan en \fB.lzma\fP\-dekomprimerare i en inbäddad enhet fungera endast +med filer som har en känd okomprimerad storlek. Om man stöter pÃ¥ detta +problem behöver man använda LZMA Utils eller LZMA SDK för att skapa +\&\fB.lzma\fP\-filer med känd okomprimerad storlek. +. +.SS "Ej stödda .lzma\-filer" +Formatet \fB.lzma\fP tillÃ¥ter värden pÃ¥ \fIlc\fP upp till 8, och värden pÃ¥ \fIlp\fP +upp till 4. LZMA Utils kan dekomprimera filer med godtyckliga \fIlc\fP och +\fIlp\fP, men skapar alltid filer med \fBlc=3\fP och \fBlp=0\fP. Att skapa filer med +andra \fIlc\fP och \fIlp\fP är möjligt med \fBxz\fP och med LZMA SDK. +.PP +Implementationen av LZMA1\-filtret i liblzma kräver att summan av \fIlc\fP och +\fIlp\fP inte överstiger 4. AlltsÃ¥, \fB.lzma\fP\-filer, vilka överstiger denna +gräns, kan inte dekomprimeras med \fBxz\fP. +.PP +LZMA Utils skapar endast \fB.lzma\fP\-filer som har en lexikonstorlek pÃ¥ 2^\fIn\fP +(en potens av 2) men godtar filer med godtycklig lexikonstorlek. liblzma +godtar endast \fB.lzma\fP\-filer som har en lexikonstorlek pÃ¥ 2^\fIn\fP eller +2^\fIn\fP + 2^(\fIn\fP\-1). Detta är för att minska falska positiva vid detektering +av \fB.lzma\fP\-filer. +.PP +Dessa begränsningar bör inte vara ett problem i praktiken, eftersom +praktiskt taget alla \fB.lzma\fP\-filer har komprimerats med inställningar som +liblzma kommer godta. +. +.SS "Avslutande skräp" +Vid dekomprimering ignorerar LZMA Utils tyst allting efter den första +\&\fB.lzma\fP\-strömmen. I de flesta situationer är detta fel. Detta betyder även +att LZMA Utils inte stödjer dekomprimering av konkatenerade \fB.lzma\fP\-filer. +.PP +Om det finns data kvar efter den första \fB.lzma\fP\-strömmen betraktar \fBxz\fP +filen som trasig om inte \fB\-\-single\-stream\fP användes. Detta kan göra sönder +obskyra skript vilka har antagit att avslutande skräp ignoreras. +. +.SH NOTERINGAR +. +.SS "Den komprimerade utdatan kan variera" +Den exakta komprimerade utdatan som produceras frÃ¥n samma okomprimerade +indatafil kan variera mellan versioner av XZ Utils även om +komprimeringsflaggorna är identiska. Detta beror pÃ¥ att kodaren kan +förbättras (snabbare eller bättre komprimering) utan att pÃ¥verka +filformatet. Utdatan kan variera även mellan olika byggen av samma version +av XZ Utils, om olika byggflaggor används. +.PP +OvanstÃ¥ende betyder att när väl \fB\-\-rsyncable\fP har implementerats kommer +inte nödvändigtvis de resulterande filerna vara rsync\-bara om inte bÃ¥de +gamla och nya filer har komprimerats med samma version av xz. Detta problem +kan lösas om en del av kodarimplementeringen fryses för att hÃ¥lla rsync\-bar +utdata stabil mellan xz\-versioner. +. +.SS "Inbäddade .xz\-dekomprimerare" +Inbäddade implementationer av \fB.xz\fP\-dekomprimerare som XZ Embedded stödjer +inte nödvändigtvis filer som skapas med andra typer av +integritets\fIkontroll\fP än \fBnone\fP och \fBcrc32\fP. Eftersom standardvärdet är +\fB\-\-check=crc64\fP mÃ¥ste man använda \fB\-\-check=none\fP eller \fB\-\-check=crc32\fP +när filer skapas för inbäddade system. +.PP +Utanför inbäddade system stödjer alla dekomprimerare av \fB.xz\fP\-format alla +typerna av \fIkontroller\fP, eller Ã¥tminstone kan de dekomprimera filern utan +att verifiera integritetskontrollen om den specifika \fIkontrollen\fP inte +stödjs. +.PP +XZ Embedded stödjer BCJ\-filter, men endast med standard startavstÃ¥nd. +. +.SH EXEMPEL +. +.SS Grundläggande +Komprimera filen \fIapa\fP till \fIapa.xz\fP med standardkomprimeringsnivÃ¥n +(\fB\-6\fP), och ta bort \fIapa\fP om komprimeringen lyckas: +.RS +.PP +.nf +\f(CRxz apa\fR +.fi +.RE +.PP +Dekomprimera \fIbepa.xz\fP till \fIbepa\fP och ta inte bort \fIbepa.xz\fP även om +dekomprimeringen lyckas: +.RS +.PP +.nf +\f(CRxz \-dk bepa.xz\fR +.fi +.RE +.PP +Skapa \fIcepa.tar.xz\fP med förinställningen \fB\-4e\fP (\fB\-4 \-\-extreme\fP), vilket +är lÃ¥ngsammare än standardvärdet \fB\-6\fP, men behöver mindre minne till +komprimering och dekomprimering (48\ MiB respektive 5\ MiB): +.RS +.PP +.nf +\f(CRtar cf \- cepa | xz \-4e > cepa.tar.xz\fR +.fi +.RE +.PP +En blandning av komprimerade och okomprimerade filer kan dekomprimeras till +standard ut med ett enda kommando: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "Parallell komprimering av mÃ¥nga filer" +PÃ¥ GNU och *BSD kan \fBfind\fP(1) och \fBxargs\fP(1) användas för att +parallellisera komprimeringen av mÃ¥nga filer: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +Flaggan \fB\-P\fP till \fBxargs\fP(1) anger antalet parallella \fBxz\fP\-processer. Det +bästa värdet till flaggan \fB\-n\fP beror pÃ¥ hur mÃ¥nga filer det finns som skapp +komprimeras. Om det bara finns nÃ¥gra stycken filer bör värdet förmodigen +vara 1; med tiotusentals filer kan 100 eller mer vara lämpligt för att +reducera antalet \fBxz\fP\-processer som \fBxargs\fP(1) kommer att skapa. +.PP +Flaggan \fB\-T1\fP till \fBxz\fP finns för att tvinga den till enkeltrÃ¥dsläge, +eftersom \fBxargs\fP(1) används för att styra mängden parallellisering. +. +.SS Robotläge +Beräkna hur mÃ¥nga byt som har sparats totalt efter komprimering av flera +filer: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +Ett skript kan vilja veta att det använder en tillräckligt ny +\fBxz\fP. Följande \fBsh\fP(1)\-skript kontrollerar att versionsnumret för +verktyget \fBxz\fP är Ã¥tminstone 5.0.0. Denna metod är kompatibel med gamla +betaversioner, vilka inte stödde flaggan \fB\-\-robot\fP: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Din xz är för gammal." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +Ange en gräns för minnesanvändning för dekomprimering med \fBXZ_OPT\fP, men om +en gräns redan har satts, öka den inte: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "Anpassade komprimerarfilterkedjor" +Den enklaste användningen av anpassade filterkedjor är att anpassa en +LZMA2\-förinställning. Detta kan vara användbart eftersom förinställningarna +endast täcker en delmängd av de potentiellt användbara kombinationerna av +komprimeringsinställningar. +.PP +Kolumnerna CompCPU i tabellerna frÃ¥n beskrivningen av flaggorna options +\fB\-0\fP ... \fB\-9\fP och \fB\-\-extreme\fP är användbara vid anpassning av +LZMA2\-förinställningar. Här är de relevanta delarna samlade frÃ¥n dessa tvÃ¥ +tabeller: +.RS +.PP +.TS +tab(;); +c c +n n. +Förinställning;KompCPU +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +Om man vet att en fil behöver ett rätt stort lexikon (till exempel, 32\ MiB) +för att komprimeras bra, men man vill komprimera den snabbare än \fBxz \-8\fP +skulle gjort kan en förinställning med ett lÃ¥gt värde pÃ¥ CompCPU (till +exempel, 1) ändras till att använda ett större lexikon: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB apa.tar\fR +.fi +.RE +.PP +Med vissa filer kan ovanstÃ¥ende kommando vara snabbare än \fBxz \-6\fP samtidigt +som det komprimerar betydligt bättre. Dock mÃ¥ste det pÃ¥pekas att endast +nÃ¥gra filer drar fördel av ett stort lexikon samtidigt som värdet CompCPU +hÃ¥lls lÃ¥gt. Den mest uppenbara situationen, är ett stort lexikon kan hälpa +till mycket, är ett arkiv som innehÃ¥ller väldigt snarlika filer pÃ¥ Ã¥tmistone +nÃ¥gra megabyte var. Lexikonstorleken mÃ¥ste vara signifikant större än nÃ¥gon +enskild fil för att lÃ¥ta LZMA2 dra full nytta av likheterna mellan pÃ¥ +varandra följande filer. +.PP +Om det gÃ¥r bra med väldigt hög minnesanvändning i komprimeraren och +dekomprimeraren, och filen som komprimeras är Ã¥tminstone flera hundra +megabyte, kan det vara användbart att använda ännu större lexikon än de 64 +MiB som \fBxz \-9\fP skulle använda: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB stor_apa.tar\fR +.fi +.RE +.PP +Att använda \fB\-vv\fP (\fB\-\-verbose \-\-verbose\fP) som i exemplet ovan kan vara +användbart för att se minnesbehoven för komprimeraren och +dekomprimeraren. Kom ihÃ¥g att använda ett större lexikon än storleken pÃ¥ den +okomprimerade filen är slöseri med minne, sÃ¥ ovanstÃ¥ende kommando är inte +användbart för smÃ¥ filer. +.PP +Ibland spelar inte dekomprimeringstiden nÃ¥gon roll, men dekomprimerarens +minnesanvändning mÃ¥ste hÃ¥llas lÃ¥g, till exempel för att göra det möjligt att +dekomprimera filen pÃ¥ ett inbäddat system. Följande kommando använder \fB\-6e\fP +(\fB\-6 \-\-extreme\fP) som en bas och sätter lexikonstorleken till bara 64\ KiB. Den resulterande filen kan dekomprimeras med XZ Embedded (det är därför +det finns \fB\-\-check=crc32\fP) som använder ungerfär 100\ KiB minne. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB apa\fR +.fi +.RE +.PP +Om man vill krama ur sÃ¥ mÃ¥nga byte som möjligt kan justering av antalet +literala kontextbitar (\fIlc\fP) och antalet positionsbitar (\fIpb\fP) ibland +hjälpa. Justering av antalet literala positionsbitar (\fIlp\fP) kan ocksÃ¥ +hjälpa, men vanligen är \fIlc\fP och \fIpb\fP viktigare. Till exempel innehÃ¥ller +ett källkodsarkiv huvudsakligen US\-ASCII\-text, sÃ¥ nÃ¥got i stil med följande +kan ge aningen (som 0.1\ %) mindre fil än \fBxz \-6e\fP (försök även utan +\fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 källkod.tar\fR +.fi +.RE +.PP +Att använda ett annat filter tillsammans med LZMA2 kan förbättra +komprimeringen med vissa filtyper. Till exempel, för att komprimera ett +delat x86\-32\- eller x86\-64\-bibliotek med filtret x86 BCJ: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libapa.so\fR +.fi +.RE +.PP +Observera att ordningen pÃ¥ filterflaggorna spelar roll. Om \fB\-\-x86\fP anges +efter \fB\-\-lzma2\fP kommer \fBxz\fP avge ett fel, eftersom det inte kan vara nÃ¥got +filter efter LZMA2, och även för att filtret x86 BCJ inte kan användas som +det sista filtret i kedjan. +.PP +Deltafiltret tillsammans med LZMA2 gan ge bra resultat med +bitkartebilder. Det bör vanligen slÃ¥ PNG, som har nÃ¥gra mer avancerade +filter än enkla delta men använder Deflat för den faktiska komprimeringen. +.PP +Bilden mÃ¥ste sparas i okomprimerat format, till exempel som okomprimerad +TIFF. AvstÃ¥ndsparametern i Deltafiltret sätts till att motsvara natalet byte +per bildpunkt i bilden. Till exempel, 24\-bitars RGB bitkarta behöver +\fBdist=3\fP, och det är även bra att skicka \fBpb=0\fP till LZMA2 för att ge +plats för trebytejustering: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 apa.tiff\fR +.fi +.RE +.PP +Om flera bilder har lagts in i ett gemensamt arkiv (till exempel, \fB.tar\fP) +kommer Deltafiltret fungera pÃ¥ det ocksÃ¥ sÃ¥ länge alla bilder har samma +antal byte per bildpunkt. +. +.SH "SE ÄVEN" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ Utils: +.br +XZ Embedded: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sv/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzdec.1 new file mode 100644 index 000000000..63612b0c4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzdec.1 @@ -0,0 +1,87 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Swedish translation of xz-man +.\" Göran Uddeborg , 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 2024\-04\-08 Tukaani "XZ Utils" +.SH NAMN +xzdec, lzmadec \- SmÃ¥ .xz\- och .lzma\-dekomprimerare +.SH SYNOPSIS +\fBxzdec\fP [\fIflagga…\fP] [\fIfil…\fP] +.br +\fBlzmadec\fP [\fIflagga…\fP] [\fIfil…\fP] +.SH BESKRIVNING +\fBxzdec\fP är ett liblzma\-baserat verktyg endast för dekomprimering för \fB.xz\fP +(och endast \fB.xz\fP) filer. \fBxzdec\fP är avsett att fungera som en drop +in\-ersättning för \fBxz\fP(1) i de vanligaste situationerna där ett skript har +skrivits för att använda \fBxz \-\-decompress \-\-stdout\fP (och möjligen nÃ¥gra +andra vanliga flaggor) för att dekomprimera \fB.xz\fP\-filer. \fBlzmadec\fP är +identisk med \fBxzdec\fP förutom att \fBlzmadec\fP stödjer \fB.lzma\fP\-filer istället +för \fB.xz\fP\-filer. +.PP +För att reducera storleken pÃ¥ det körbara programmet stödjer inte \fBxzdec\fP +multitrÃ¥dning eller lokalisering, och läser inte flaggor frÃ¥n +miljövariablerna \fBXZ_DEFAULTS\fP eller \fBXZ_OPT\fP. \fBxzdec\fP stödjer inte att +visa mellanliggande förloppsinformation: att skicka \fBSIGINFO\fP till \fBxzdec\fP +gör ingenting, med att skicka \fBSIGUSR1\fP avslutar processen istället för att +visa förloppsinformation. +.SH FLAGGOR +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +Ignoreras för kompatibilitet med \fBxz\fP(1). \fBxzdec\fP stödjer endast +dekomprimering. +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ignoreras för kompatibilitet med \fBxz\fP(1). \fBxzdec\fP skapar aldrig eller tar +aldrig bort nÃ¥gra filer. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Ignoreras för kompatibilitet med \fBxz\fP(1). \fBxzdec\fP skriver alltid +dekomprimerad data till standard ut. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Att ange detta en gÃ¥ng gör inget eftersom \fBxzdec\fP aldrig visar nÃ¥gra +varningar eller noteringar. Att ange detta tvÃ¥ gÃ¥nger utelämnar +felmeddelanden. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Ignoreras för kompatibilitet med \fBxz\fP(1). \fBxzdec\fP använder aldrig +slutstatus 2. +.TP +\fB\-h\fP, \fB\-\-help\fP +Visa ett hjälpmeddelande och avsluta. +.TP +\fB\-V\fP, \fB\-\-version\fP +Visa versionsnumret pÃ¥ \fBxzdec\fP och liblzma. +.SH SLUTSTATUS +.TP +\fB0\fP +Allt gick bra. +.TP +\fB1\fP +Ett fel uppstod. +.PP +\fBxzdec\fP har inte nÃ¥gra varningsmeddelanden sÃ¥ som \fBxz\fP(1) har, och därför +används aldrig slutstatusen 2 av \fBxzdec\fP. +.SH NOTERINGAR +Använd \fBxz\fP(1) istället för \fBxzdec\fP eller \fBlzmadec\fP för dagligt +bruk. \fBxzdec\fP och \fBlzmadec\fP är bara avsedda för situationer där det är +viktigt att ha en mindre dekomprimerare än den fullständiga \fBxz\fP(1). +.PP +\fBxzdec\fP och \fBlzmadec\fP är egentligen inte riktigt sÃ¥ smÃ¥. Storleken kan +reduceras ytterligare genom att ta bort funktioner frÃ¥n liblzma vid +kompileringstidpunkten, men det skall normalt inte göras för körbara program +som distribueras i en typisk, inte inbäddad, distribution av +operativsystem. Om man behöver en verkligt liten \fB.xz\fP\-dekomprimerare skall +man överväga XZ Embedded. +.SH "SE ÄVEN" +\fBxz\fP(1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sv/xzdiff.1 b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzdiff.1 new file mode 100644 index 000000000..2d1516dcb --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzdiff.1 @@ -0,0 +1,54 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Swedish translation of xz-man +.\" Göran Uddeborg , 2025. +.\" +.\" (Note that this file is not based on gzip's zdiff.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDIFF 1 2025\-03\-06 Tukaani "XZ Utils" +.SH NAMN +xzcmp, xzdiff, lzcmp, lzdiff — jämför komprimerade filer +. +.SH SYNOPSIS +\fBxzcmp\fP [\fIflagga…\fP] \fIfil1\fP [\fIfil2\fP] +.br +\fBxzdiff\fP \&… +.br +\fBlzcmp\fP \&… (FÖRÃ…LDRAT) +.br +\fBlzdiff\fP \&… (FÖRÃ…LDRAT) +. +.SH BESKRIVNING +\fBxzcmp\fP och \fBxzdiff\fP jämför det okomprimerade innehÃ¥llet i tvÃ¥ +filer. Okomprimerad data skickas till \fBcmp\fP(1) eller \fBdiff\fP(1) sÃ¥vida inte +\fB\-\-help\fP eller \fB\-\-version\fP anges. +.PP +Om bÃ¥de \fIfil1\fP och \fIfil2\fP anges kan de vara okomprimerade filer eller +filer i format som \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1) +eller \fBlz4\fP(1) kan dekomprimera. De nödvändiga dekomprimeringskommandona +avgörs frÃ¥n filnamnsändelsen pÃ¥ \fIfil1\fP och \fIfil2\fP. En fil med en okänd +ändelse antas antingen vara okomprimerad eller i ett format som \fBxz\fP(1) kan +dekomprimera. +.PP +Om endast ett filnamn anges mÃ¥ste \fIfil1\fP ha en ändelse med ett av de stödda +komprimeringsformaten och namnet pÃ¥ \fIfil2\fP antas vara \fIfil1\fP med +komprimeringsformatsändelsen borttagen. +.PP +Kommandona \fBlzcmp\fP och \fBlzdiff\fP finns för bakÃ¥tkompatibilitet med LZMA +Utils. De rekommenderas inte och kommer tas bort i en framtida version. +. +.SH SLUTSTATUS +Om ett dekomprimeringsfel uppstÃ¥r är slutstatus \fB2\fP. Annars används +slutstatusen frÃ¥n \fBcmp\fP(1) respektive \fBdiff\fP(1). +. +.SH "SE ÄVEN" +\fBcmp\fP(1), \fBdiff\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), +\fBzstd\fP(1), \fBlz4\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sv/xzgrep.1 b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzgrep.1 new file mode 100644 index 000000000..bf4653d6c --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzgrep.1 @@ -0,0 +1,92 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Swedish translation of xz-man +.\" Göran Uddeborg , 2025. +.\" +.\" (Note that this file is not based on gzip's zgrep.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZGREP 1 2025\-03\-06 Tukaani "XZ Utils" +.SH NAMN +xzgrep — sök i eventuellt komprimerade filer efter mönster +. +.SH SYNOPSIS +\fBxzgrep\fP [\fIflagga…\fP] [\fImönsterlista\fP] [\fIfil…\fP] +.br +\fBxzegrep\fP \&… +.br +\fBxzfgrep\fP \&… +.br +\fBlzgrep\fP \&… (FÖRÃ…LDRAT) +.br +\fBlzegrep\fP \&… (FÖRÃ…LDRAT) +.br +\fBlzfgrep\fP \&… (FÖRÃ…LDRAT) +. +.SH BESKRIVNING +\fBxzgrep\fP anropar \fBgrep\fP(1) pÃ¥ det okomprimerade innehÃ¥llet i +filerna. Formaten pÃ¥ \fIfilerna\fP bestäms utgÃ¥ende frÃ¥n filnamnsändelsen. En +\fIfil\fP med en ändelse som stödjs av \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), +\fBlzop\fP(1), \fBzstd\fP(1) eller \fBlz4\fP(1) kommer att dekomprimeras; alla andra +filer antas vara okomprimerade. +.PP +Om inga \fIfiler\fP anges eller om \fIfil\fP är \fB\-\fP lästes standard in. När +standard in läses är de enda filerna som dekomprimeras de som stödjs av +\fBxz\fP(1). Andra filer antas redan vara i okomprimerad form. +.PP +De flesta \fIflaggor\fP till \fBgrep\fP(1) stödjs. Dock stödjs inte följande +flaggor: +.IP "" 4 +\fB\-r\fP, \fB\-\-recursive\fP +.IP "" 4 +\fB\-R\fP, \fB\-\-dereference\-recursive\fP +.IP "" 4 +\fB\-d\fP, \fB\-\-directories=\fP\fIÃ¥tgärd\fP +.IP "" 4 +\fB\-Z\fP, \fB\-\-null\fP +.IP "" 4 +\fB\-z\fP, \fB\-\-null\-data\fP +.IP "" 4 +\fB\-\-include=\fP\fIglob\fP +.IP "" 4 +\fB\-\-exclude=\fP\fIglob\fP +.IP "" 4 +\fB\-\-exclude\-from=\fP\fIfil\fP +.IP "" 4 +\fB\-\-exclude\-dir=\fP\fIglob\fP +.PP +\fBxzegrep\fP är ett alias för \fBxzgrep \-E\fP. \fBxzfgrep\fP är ett alias för +\fBxzgrep \-F\fP. +.PP +Kommandona \fBlzgrep\fP, \fBlzegrep\fP och \fBlzfgrep\fP finns för +bakÃ¥tkompatibilitet med LZMA Utils. De rekommenderas inte och kommer tas +bort i en framtida version. +. +.SH SLUTSTATUS +.TP +0 +Ã…tminstone en matchning hittades frÃ¥n Ã¥tminstone en av infilerna. Inga fel +uppstod. +.TP +1 +Inga matchningar hittades i nÃ¥gon av infilerna. Inga fel uppstod. +.TP +>1 +Ett eller flera fel uppstod. Det är okänt om nÃ¥gra matchningar hittades. +. +.SH MILJÖ +.TP +\fBGREP\fP +Om \fBGREP\fP är satt till nÃ¥got icketomt värde används det istället för +\fBgrep\fP, \fBgrep \-E\fP respektive \fBgrep \-F\fP. +. +.SH "SE ÄVEN" +\fBgrep\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), +\fBlz4\fP(1), \fBzgrep\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sv/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzless.1 new file mode 100644 index 000000000..52b702820 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzless.1 @@ -0,0 +1,47 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Swedish translation of xz-man +.\" Göran Uddeborg , 2025. +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 2025\-03\-06 Tukaani "XZ Utils" +.SH NAMN +xzless, lzless — visa xz\- eller lzma\-komprimerade (text)filer +.SH SYNOPSIS +\fBxzless\fP [\fIfil\fP…] +.br +\fBlzless\fP [\fIfil\fP…] (FÖRÃ…LDRAT) +.SH BESKRIVNING +\fBxzless\fP är ett filter som visar text frÃ¥n komprimerade filer i en +terminal. Filer som stödjs av \fBxz\fP(1) dekomprimeras; andra filer antas +redan vara i okomprimerad form. Om inga \fIfiler\fP ges läser \fBxzless\fP frÃ¥n +standard in. +.PP +\fBxzless\fP använder \fBless\fP(1) för att visa sin utdata. Till skillnad mot +\fBxzmore\fP kan inte dess val av bläddrare ändras genom att sätta en +miljövariabel. Kommandon är baserade pÃ¥ bÃ¥de \fBmore\fP(1) och \fBvi\fP(1) och +tillÃ¥ter förflytting fram och tillbaka samt sökning. Se manualen \fBless\fP(1) +för mer information. +.PP +Kommandot som heter \fBlzless\fP finns för bakÃ¥tkompatibilitet med LZMA +Utils. Det rekommenderas inte och kommer tas bort i en framtida version. +.SH MILJÖ +.TP +\fBLESSMETACHARS\fP +En lista pÃ¥ tecken som är speciella för skalet. Sätts av \fBxzless\fP om den +inte redan är satt i miljön. +.TP +\fBLESSOPEN\fP +Satt till en kommandorad för att köra dekomprimeraren \fBxz\fP(1) för +förbehandling av infiler till \fBless\fP(1). +.SH "SE ÄVEN" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/sv/xzmore.1 b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzmore.1 new file mode 100644 index 000000000..b5bb68d4d --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/sv/xzmore.1 @@ -0,0 +1,48 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Swedish translation of xz-man +.\" Göran Uddeborg , 2025. +.\" +.\" (Note that this file is based on xzless.1 instead of gzip's zmore.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZMORE 1 2025\-03\-06 Tukaani "XZ Utils" +.SH NAMN +xzmore, lzmore — visa xz\- eller lzma\-komprimerade (text)filer +. +.SH SYNOPSIS +\fBxzmore\fP [\fIfil\fP…] +.br +\fBlzmore\fP [\fIfil\fP…] (FÖRÃ…LDRAT) +. +.SH BESKRIVNING +\fBxzmore\fP visar text frÃ¥n komprimerade filer i en terminal med användning av +\fBmore\fP(1). Filer som stödjs av \fBxz\fP(1) dekomprimeras; andra filer antas +redan vara i okomprimerad form. Om inga \fIfiler\fP ges läser \fBxzmore\fP frÃ¥n +standard in. Se manualen för \fBmore\fP(1) för tangentbordskommandona. +.PP +Observera att det kanske inte är möjligt att rulla baklänges, beroende pÃ¥ +implementationen av \fBmore\fP(1). Detta är för att \fBxzmore\fP använder ett rör +för att skicka dekomprimerad data till \fBmore\fP(1). \fBxzless\fP(1) använder +\fBless\fP(1) vilken ger mer avancerade funktioner. +.PP +Kommandot \fBlzmore\fP finns för bakÃ¥tkompatibilitet med LZMA Utils. Det +rekommenderas inte och kommer tas bort i en framtida version. +. +.SH MILJÖ +.TP +.\" TRANSLATORS: Don't translate the uppercase PAGER. +.\" It is a name of an environment variable. +\fBPAGER\fP +Om \fBPAGER\fP är satt används dess värde som bläddrare istället för +\fBmore\fP(1). +. +.SH "SE ÄVEN" +\fBmore\fP(1), \fBxz\fP(1), \fBxzless\fP(1), \fBzmore\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/uk/lzmainfo.1 b/cpp/third_party/xz-5.8.3/po4a/man/uk/lzmainfo.1 new file mode 100644 index 000000000..fea640b06 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/uk/lzmainfo.1 @@ -0,0 +1,45 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Ukrainian translation for xz-man. +.\" Yuri Chornoivan , 2019, 2022, 2023, 2024, 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH LZMAINFO 1 "30 Ñ‡ÐµÑ€Ð²Ð½Ñ 2013 року" Tukaani "XZ Utils" +.SH ÐÐЗВР+lzmainfo — показ відомоÑтей, Ñкі зберігаютьÑÑ Ñƒ заголовку файла .lzma +.SH "КОРОТКИЙ ОПИС" +\fBlzmainfo\fP [\fB\-\-help\fP] [\fB\-\-version\fP] [\fIфайл...\fP] +.SH ОПИС +\fBlzmainfo\fP показує дані, що зберігаютьÑÑ Ñƒ заголовку файла \fB.lzma\fP. Вона +читає перші 13 байтів із вказаного \fIфайла\fP, розкодовує заголовок Ñ– виводить +його до Ñтандартного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñƒ зручному Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñ–. Якщо не +вказано жодного \fIфайла\fP або заміÑть \fIфайла\fP вказано \fB\-\fP, дані буде +прочитано зі Ñтандартного вхідного джерела даних. +.PP +Зазвичай, найцікавішою інформацією Ñ” розпакований розмір та розмір +Ñловника. Розпакований розмір може бути показано, лише Ñкщо файл запиÑано у +непотоковому варіанті формату \fB.lzma\fP. Об'єм пам'Ñті, потрібний Ð´Ð»Ñ +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð°, Ñкладає декілька деÑÑтків кілобайтів Ð¿Ð»ÑŽÑ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€ +Ñловника. +.PP +\fBlzmainfo\fP включено до XZ Utils в оÑновному Ð´Ð»Ñ Ð·Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¾Ñ— ÑуміÑноÑті із +LZMA Utils. +.SH "СТÐРВИХОДУ" +.TP +\fB0\fP +УÑе добре. +.TP +\fB1\fP +СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. +.SH Ð’ÐДИ +\fBlzmainfo\fP викориÑтовує \fBMB\fP, хоча правильним ÑуфікÑом мав би бути \fBMiB\fP +(2^20 байтів). Так зроблено, щоб зберегти ÑуміÑніÑть виведених даних із LZMA +Utils. +.SH "ДИВ. ТÐКОЖ" +\fBxz\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/uk/xz.1 b/cpp/third_party/xz-5.8.3/po4a/man/uk/xz.1 new file mode 100644 index 000000000..bff0472c4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/uk/xz.1 @@ -0,0 +1,2039 @@ +'\" t +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Ukrainian translation for xz-man. +.\" Yuri Chornoivan , 2019, 2022, 2023, 2024, 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZ 1 "8 Ð±ÐµÑ€ÐµÐ·Ð½Ñ 2025 року" Tukaani "XZ Utils" +. +.SH ÐÐЗВР+xz, unxz, xzcat, lzma, unlzma, lzcat — ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚Ð° Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² +\&.xz Ñ– .lzma +. +.SH "КОРОТКИЙ ОПИС" +\fBxz\fP [\fIпараметр...\fP] [\fIфайл...\fP] +. +.SH "СКОРОЧЕÐÐЯ КОМÐÐД" +\fBunxz\fP Ñ” рівноцінним до \fBxz \-\-decompress\fP. +.br +\fBxzcat\fP Ñ” рівноцінним до \fBxz \-\-decompress \-\-stdout\fP. +.br +\fBlzma\fP Ñ” рівноцінним до \fBxz \-\-format=lzma\fP. +.br +\fBunlzma\fP Ñ” рівноцінним до \fBxz \-\-format=lzma \-\-decompress\fP. +.br +\fBlzcat\fP Ñ” рівноцінним до \fBxz \-\-format=lzma \-\-decompress \-\-stdout\fP. +.PP +При напиÑанні Ñкриптів, де потрібно розпаковувати файли, рекомендуємо завжди +викориÑтовувати \fBxz\fP із відповідними аргументами (\fBxz \-d\fP або \fBxz \-dc\fP), +заміÑть \fBunxz\fP Ñ– \fBxzcat\fP. +. +.SH ОПИС +\fBxz\fP інÑтрумент загального Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… із ÑинтакÑиÑом +командного Ñ€Ñдка, подібним Ð´Ð»Ñ \fBgzip\fP(1) Ñ– \fBbzip2\fP(1). ВлаÑним форматом +файлів Ñ” \fB.xz\fP, але передбачено підтримку заÑтарілого формату \fB.lzma\fP, +Ñкий було викориÑтано у LZMA Utils, та необроблених потоків ÑтиÑнених даних +без заголовків формату контейнера. Крім того, передбачено підтримку +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñƒ \fB.lz\fP, Ñкий викориÑтано у \fBlzip\fP. +.PP +\fBxz\fP ÑтиÑкає або розпаковує кожен \fIфайл\fP відповідно до вибраного режиму +дій. Якщо \fIфайли\fP не задано або Ñкщо \fIфайлом\fP Ñ” \fB\-\fP, \fBxz\fP читатиме дані +зі Ñтандартного джерела вхідних даних Ñ– запиÑуватиме оброблені дані до +Ñтандартного виведеннÑ. \fBxz\fP відмовить (покаже Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку Ñ– +пропуÑтить \fIфайл\fP) у запиÑів ÑтиÑнених даних до Ñтандартного виведеннÑ, +Ñкщо це термінал. Так Ñамо, \fBxz\fP відмовить у читанні ÑтиÑнених даних зі +Ñтандартного джерела вхідних даних, Ñкщо це термінал. +.PP +Якщо не вказано \fB\-\-stdout\fP, \fIфайли\fP, відмінні від \fB\-\fP, буде запиÑано до +нового файла, чию назву буде визначено з назви початкового \fIфайла\fP: +.IP \(bu 3 +При ÑтиÑканні ÑÑƒÑ„Ñ–ÐºÑ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñƒ файла Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (\fB.xz\fP або \fB.lzma\fP) буде +допиÑано до назви початкового файла Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ файла призначеннÑ. +.IP \(bu 3 +При розпаковуванні ÑÑƒÑ„Ñ–ÐºÑ \fB.xz\fP, \fB.lzma\fP або \fB.lz\fP буде вилучено з назви +файла Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ файла призначеннÑ. Крім того, \fBxz\fP розпізнає +ÑуфікÑи \fB.txz\fP Ñ– \fB.tlz\fP Ñ– замінює Ñ—Ñ… на ÑÑƒÑ„Ñ–ÐºÑ \fB.tar\fP. +.PP +Якщо файл Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð¶Ðµ Ñ–Ñнує, буде показано Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку, а +\fIфайл\fP буде пропущено. +.PP +Окрім випадку запиÑу до Ñтандартного виведеннÑ, \fBxz\fP покаже Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ñ– +пропуÑтить обробку \fIфайла\fP, Ñкщо буде виконано будь\-Ñку з таких умов: +.IP \(bu 3 +\fIФайл\fP не Ñ” звичайним файлом. Програма не переходитиме за Ñимволічними +поÑиланнÑми, а отже, не вважатиме Ñ—Ñ… звичайними файлами. +.IP \(bu 3 +Ðа \fIфайл\fP Ñ–Ñнує декілька жорÑтких поÑилань. +.IP \(bu 3 +Ð”Ð»Ñ \fIфайла\fP вÑтановлено setuid, setgid або «липкий» біт. +.IP \(bu 3 +Режим дій вÑтановлено у Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«ÑтиÑканнÑ», Ñ– \fIфайл\fP вже має ÑÑƒÑ„Ñ–ÐºÑ Ð½Ð°Ð·Ð²Ð¸ +формату файла Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (\fB.xz\fP або \fB.txz\fP при ÑтиÑканні до формату +\&\fB.xz\fP, Ñ– \fB.lzma\fP або \fB.tlz\fP при ÑтиÑканні до формату \fB.lzma\fP). +.IP \(bu 3 +Режим дій вÑтановлено у Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ», Ñ– \fIфайл\fP не має ÑуфікÑа +назви жодного з підтримуваних форматів (\fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP +або \fB.lz\fP). +.PP +ПіÑÐ»Ñ ÑƒÑпішного ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ \fIфайла\fP, \fBxz\fP копіює дані +щодо влаÑника, групи, прав доÑтупу, чаÑу доÑтупу та моменту внеÑÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½ з +початкового \fIфайла\fP до файла призначеннÑ. Якщо ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… щодо групи +зазнає невдачі, права доÑтупу буде змінено так, що файл Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñтане +недоÑтупним Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів, Ñкі не мають права доÑтупу до початкового +\fIфайла\fP. Ð’ \fBxz\fP ще не передбачено підтримки ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ–Ð½ÑˆÐ¸Ñ… метаданих, +зокрема ÑпиÑків ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ñтупом або розширених атрибутів. +.PP +Щойно файл Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ уÑпішно закрито, початковий \fIфайл\fP буде +вилучено, Ñкщо не вказано параметра \fB\-\-keep\fP. Початковий \fIфайл\fP ніколи не +буде вилучено, Ñкщо виведені дані буде запиÑано до Ñтандартного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ +або Ñкщо ÑтанетьÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. +.PP +ÐадÑÐ¸Ð»Ð°Ð½Ð½Ñ \fBSIGINFO\fP або \fBSIGUSR1\fP до процеÑу \fBxz\fP призводить до +Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… щодо поÑтупу до Ñтандартного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº. Це має лише +обмежене викориÑтаннÑ, оÑкільки Ñкщо Ñтандартним виведеннÑм помилок Ñ” +термінал, викориÑÑ‚Ð°Ð½Ð½Ñ \fB\-\-verbose\fP призведе до показу автоматично +оновлюваного індикатора поÑтупу. +. +.SS "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті" +ВикориÑÑ‚Ð°Ð½Ð½Ñ \fBxz\fP пам'Ñті може бути різним: від декількох Ñотень кілобайтів +до декількох гігабайтів, залежно від параметрів ÑтиÑканнÑ. Параметри, Ñкі +викориÑтано при ÑтиÑканні файла, визначають вимоги до об'єму пам'Ñті при +розпакуванні. Типово, заÑобу Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€Ñ–Ð±Ð½Ð¾ від 5\ % до 20\ % +об'єму пам'Ñті, Ñкого заÑіб ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” при Ñтворенні +файла. Ðаприклад, Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð°, Ñкий Ñтворено з викориÑтаннÑм \fBxz \-9\fP, у поточній верÑÑ–Ñ— потребує 65\ МіБ пам'Ñті. Втім, можливе ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ +файлів \fB.xz\fP, Ñкі потребуватимуть Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð´ÐµÐºÑ–Ð»ÑŒÐºÐ¾Ñ… гігабайтів +пам'Ñті. +.PP +ЙмовірніÑть виÑокого Ñ€Ñ–Ð²Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті може бути оÑобливо +дошкульною Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів заÑтарілих комп'ютерів. Щоб запобігти прикрим +неÑподіванкам, у \fBxz\fP передбачено вбудований обмежувач пам'Ñті, Ñкий типово +вимкнено. Хоча у деÑких операційних ÑиÑтемах передбачено ÑпоÑіб обмежити +викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті процеÑами, ÑÐ¿Ð¾Ð´Ñ–Ð²Ð°Ð½Ð½Ñ Ð½Ð° його ефективніÑть не Ñ” аж +надто гнучким (наприклад, викориÑÑ‚Ð°Ð½Ð½Ñ \fBulimit\fP(1) Ð´Ð»Ñ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ +віртуальної пам'Ñті призводить до Ð²Ð¸ÐºÑ€Ð¸Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… \fBmmap\fP(2)). +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +.\" It's a name of an environment variable. +Обмежувач пам'Ñті можна увімкнути за допомогою параметра командного Ñ€Ñдка +\fB\-\-memlimit=\fP\fIобмеженнÑ\fP. ЧаÑто, зручніше увімкнути обмежувач на типовому +рівні, вÑтановивши Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ— Ñередовища \fBXZ_DEFAULTS\fP, +наприклад, \fBXZ_DEFAULTS=\-\-memlimit=150MiB\fP. Можна вÑтановити Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ +окремо Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ– Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° допомогою +\fB\-\-memlimit\-compress=\fP\fIlimit\fP and +\fB\-\-memlimit\-decompress=\fP\fIобмеженнÑ\fP. ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñ†Ð¸Ñ… двох параметрів поза +\fBXZ_DEFAULTS\fP не таке вже Ñ– кориÑне, оÑкільки одноразовий запуÑк \fBxz\fP не +може одночаÑно призводити до ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚Ð° розпаковуваннÑ, а набрати у +командному Ñ€Ñдку \fB\-\-memlimit=\fP\fIобмеженнÑ\fP (або \fB\-M\fP \fIобмеженнÑ\fP) +набагато швидше. +.PP +Якщо під Ñ‡Ð°Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐºÐ°Ð·Ð°Ð½Ðµ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ перевищено, \fBxz\fP покаже +Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку, а Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° зазнає невдачі. Якщо +Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ перевищено при ÑтиÑканні, \fBxz\fP Ñпробує маÑштабувати +параметри так, щоб не перевищувати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ (окрім випадків викориÑÑ‚Ð°Ð½Ð½Ñ +\fB\-\-format=raw\fP або \fB\-\-no\-adjust\fP). Отже, дію буде виконано, Ñкщо Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ +не Ñ” надто жорÑтким. МаÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð² буде виконано кроками, Ñкі не +збігаютьÑÑ Ñ–Ð· рівнÑми шаблонів ÑтиÑканнÑ. Ðаприклад, Ñкщо Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð»Ð¸ÑˆÐµ +трохи не вкладаєтьÑÑ Ñƒ об'єм потрібний Ð´Ð»Ñ \fBxz \-9\fP, параметри буде змінено +лише трохи, не до Ñ€Ñ–Ð²Ð½Ñ \fBxz \-8\fP. +. +.SS "ÐŸÐ¾Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ– Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð· файлами .xz" +Можна поєднати файли \fB.xz\fP без додаткової обробки. \fBxz\fP розпакує такі +файли так, наче вони Ñ” єдиним файлом \fB.xz\fP. +.PP +Можна додати Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¼Ñ–Ð¶ з'єднаними чаÑтинами або піÑÐ»Ñ Ð¾Ñтанньої +чаÑтини. Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¼Ð°Ñ” ÑкладатиÑÑ Ñ–Ð· нульових байтів Ñ– мати розмір, Ñкий Ñ” +кратним до чотирьох байтів. Це може бути кориÑним, наприклад, Ñкщо файл +\&\fB.xz\fP зберігаєтьÑÑ Ð½Ð° ноÑÑ–Ñ— даних, де розміри файла вимірюютьÑÑ Ñƒ +512\-байтових блоках. +.PP +ÐŸÐ¾Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ‚Ð° Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð½Ðµ можна викориÑтовувати Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² \fB.lzma\fP або +потоків необроблених даних. +. +.SH ПÐРÐМЕТРИ +. +.SS "ЦілочиÑельні ÑуфікÑи Ñ– Ñпеціальні значеннÑ" +У більшоÑті міÑць, де потрібен цілочиÑельний аргумент, передбачено підтримку +необов'Ñзкового ÑуфікÑа Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñтого Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²ÐµÐ»Ð¸ÐºÐ¸Ñ… цілих чиÑел. Між +цілим чиÑлом Ñ– ÑуфікÑом не повинно бути пробілів. +.TP +\fBKiB\fP +Помножити ціле чиÑло на 1024 (2^10). Синонімами \fBKiB\fP Ñ” \fBKi\fP, \fBk\fP, \fBkB\fP, +\fBK\fP та \fBKB\fP. +.TP +\fBMiB\fP +Помножити ціле чиÑло на 1048576 (2^20). Синонімами \fBMiB\fP Ñ” B, \fBMi\fP, \fBm\fP, +\fBM\fP та \fBMB\fP. +.TP +\fBGiB\fP +Помножити ціле чиÑло на 1073741824 (2^30). Синонімами \fBGiB\fP Ñ” B, \fBGi\fP, +\fBg\fP, \fBG\fP та \fBGB\fP. +.PP +Можна ÑкориÑтатиÑÑ Ð¾Ñобливим значеннÑм \fBmax\fP Ð´Ð»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¼Ð°ÐºÑимального +цілого значеннÑ, підтримку Ñкого передбачено Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°. +. +.SS "Режим операції" +Якщо вказано декілька параметрів режиму дій, буде викориÑтано лише оÑтанній +з них. +.TP +\fB\-z\fP, \fB\-\-compress\fP +СтиÑнути. Це типовий режим дій, Ñкщо не вказано параметр режиму дій, а назва +команди неÑвним чином не визначає іншого режиму дій (наприклад, \fBunxz\fP +неÑвно визначає \fB\-\-decompress\fP). +.IP "" +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +ПіÑÐ»Ñ ÑƒÑпішного Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÐ¾Ð²Ð¸Ð¹ файл буде вилучено, Ñкщо Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð½Ðµ +відбуваєтьÑÑ Ð´Ð¾ Ñтандартного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ не вказано параметра \fB\-\-keep\fP. +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +.\" The DESCRIPTION section already says this but it's good to repeat it +.\" here because the default behavior is a bit dangerous and new users +.\" in a hurry may skip reading the DESCRIPTION section. +Розпакувати. ПіÑÐ»Ñ ÑƒÑпішного Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÐ¾Ð²Ð¸Ð¹ файл буде вилучено, +Ñкщо Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð½Ðµ відбуваєтьÑÑ Ð´Ð¾ Ñтандартного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ не вказано +параметра \fB\-\-keep\fP. +.TP +\fB\-t\fP, \fB\-\-test\fP +Перевірити ціліÑніÑть ÑтиÑнених файлів \fIфайли\fP. Цей параметр еквівалентний +до \fB\-\-decompress \-\-stdout\fP, але розпаковані дані буде відкинуто, заміÑть +запиÑу до Ñтандартного виведеннÑ. Жодних файлів не буде Ñтворено або +вилучено. +.TP +\fB\-l\fP, \fB\-\-list\fP +ВивеÑти відомоÑті щодо ÑтиÑнених файлів \fIфайли\fP. Ð Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… не +виконуватиметьÑÑ, жодних файлів не буде Ñтворено або вилучено. У режимі +ÑпиÑку програма не може читати дані зі Ñтандартного Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ з інших +джерел, де неможливе позиціюваннÑ. +.IP "" +У типовому ÑпиÑку буде показано базові відомоÑті щодо файлів \fIфайли\fP, по +одному файлу на Ñ€Ñдок. Щоб отримати докладніші відомоÑті, ÑкориÑтайтеÑÑ +параметром \fB\-\-verbose\fP. Щоб розширити Ñпектр відомоÑтей, ÑкориÑтайтеÑÑ +параметром \fB\-\-verbose\fP двічі, але зауважте, що це може призвеÑти до +значного ÑƒÐ¿Ð¾Ð²Ñ–Ð»ÑŒÐ½ÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸, оÑкільки Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¸Ñ… відомоÑтей +потребує великої кількоÑті позиціювань. Ширина облаÑті докладного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ +даних перевищує 80 Ñимволів, тому Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ð¾Ð¼ виведених даних, +наприклад, до \fBless\ \-S\fP, може бути зручним ÑпоÑобом переглÑду даних, Ñкщо +термінал недоÑтатньо широкий. +.IP "" +Виведені дані залежать від верÑÑ–Ñ— \fBxz\fP та викориÑтаної локалі. Ð”Ð»Ñ +Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…, Ñкі будуть придатні до обробки комп'ютером, Ñлід +ÑкориÑтатиÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ \fB\-\-robot \-\-list\fP. +. +.SS "Модифікатори режиму роботи" +.TP +\fB\-k\fP, \fB\-\-keep\fP +Ðе вилучати вхідні файли. +.IP "" +Починаючи з верÑÑ–Ñ— \fBxz\fP 5.2.6, викориÑÑ‚Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ параметра також наказує +\fBxz\fP виконувати ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ розпаковуваннÑ, навіть Ñкщо вхідними даними Ñ” +Ñимволічне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° звичайний файл, файл, Ñкий має декілька жорÑтких +поÑилань, або файл, Ð´Ð»Ñ Ñкого вÑтановлено setuid, setgid або липкий +біт. setuid, setgid та липкий біт не буде Ñкопійовано до файла\-результату. У +попередніх верÑÑ–ÑÑ…, ці дії виконувалиÑÑ, лише Ñкщо було викориÑтано параметр +\fB\-\-force\fP. +.TP +\fB\-f\fP, \fB\-\-force\fP +Результатів викориÑÑ‚Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ параметра буде декілька: +.RS +.IP \(bu 3 +Якщо файл\-результат вже Ñ–Ñнує, вилучити його до ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ +розпаковуваннÑ. +.IP \(bu 3 +Виконувати ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ розпаковуваннÑ, навіть Ñкщо вхідними даними Ñ” +Ñимволічне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° звичайний файл, файл, Ñкий має декілька жорÑтких +поÑилань, або файл, Ð´Ð»Ñ Ñкого вÑтановлено setuid, setgid або липкий біт +setuid, setgid та липкий біт не буде Ñкопійовано до файла\-результату. +.IP \(bu 3 +Якщо викориÑтано разом із \fB\-\-decompress\fP, \fB\-\-stdout\fP, Ñ– \fBxz\fP не зможе +розпізнати тип початкового файла, копіювати початковий файл без змін до +Ñтандартного виведеннÑ. Це надає змогу кориÑтуватиÑÑ \fBxzcat\fP \fB\-\-force\fP +подібно до \fBcat\fP(1) Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð², Ñкі не було ÑтиÑнено за допомогою +\fBxz\fP. Зауважте, що у майбутньому у \fBxz\fP може бути реалізовано підтримку +нових форматів ÑтиÑнених файлів, заміÑть ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ—Ñ… без змін до +Ñтандартного виведеннÑ. Можна ÑкориÑтатиÑÑ \fB\-\-format=\fP\fIформат\fP Ð´Ð»Ñ +Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ñƒ \fBxz\fP єдиним форматом файлів. +.RE +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +ЗапиÑати ÑтиÑнені або розпаковані дані до Ñтандартного виведеннÑ, а не до +файла. ÐеÑвним чином вÑтановлює \fB\-\-keep\fP. +.TP +\fB\-\-single\-stream\fP +Розпакувати лише перший потік даних \fB.xz\fP Ñ– без повідомлень проігнорувати +решту вхідних даних, Ñкі Ñлідують за цим потоком. Зазвичай, такі зайві дані +наприкінці файла призводÑть до показу \fBxz\fP Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку. +.IP "" +\fBxz\fP ніколи не виконуватиме Ñпроби видобути декілька потоків даних з файлів +\&\fB.lzma\fP або необроблених потоків даних, але викориÑÑ‚Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ параметра +вÑе одно наказує \fBxz\fP ігнорувати можливі кінцеві дані піÑÐ»Ñ Ñ„Ð°Ð¹Ð»Ð° \fB.lzma\fP +або необробленого потоку даних. +.IP "" +Цей параметр нічого не змінює, Ñкщо режимом дій не Ñ” \fB\-\-decompress\fP або +\fB\-\-test\fP. +.IP "" +З \fBxz\fP 5.7.1alpha, \fB\-\-single\-stream\fP неÑвно визначає \fB\-\-keep\fP. +.TP +\fB\-\-no\-sparse\fP +Вимкнути ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ñ€Ñ–Ð´Ð¶ÐµÐ½Ð¸Ñ… файлів. Типово, Ñкщо Ð²Ð¸Ð´Ð¾Ð±ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÑ”Ñ‚ÑŒÑÑ +до звичайного файла, \fBxz\fP намагаєтьÑÑ Ñтворити розріджений файл, Ñкщо +розпаковані дані міÑÑ‚Ñть довгі поÑлідовноÑті двійкових нулів. Це також +працює, коли виконуєтьÑÑ Ð·Ð°Ð¿Ð¸Ñ Ð´Ð¾ Ñтандартного виведеннÑ, доки Ñтандартне +Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð·'єднано зі звичайним файлом Ñ– виконуютьÑÑ Ð¿ÐµÐ²Ð½Ñ– додаткові умови, +Ñкі убезпечують роботу. Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ñ€Ñ–Ð´Ð¶ÐµÐ½Ð¸Ñ… файлів може заощадити міÑце на +диÑку Ñ– пришвидшити Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑˆÐ»Ñхом Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾Ñті дій Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ +та Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… на диÑку. +.TP +\fB\-S\fP \fI.suf\fP, \fB\-\-suffix=\fP\fI.suf\fP +При ÑтиÑканні викориÑтати ÑÑƒÑ„Ñ–ÐºÑ \fI.suf\fP Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² призначеннÑ, заміÑть +ÑуфікÑа \fB.xz\fP або \fB.lzma\fP. Якщо запиÑÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÑ”Ñ‚ÑŒÑÑ Ð½Ðµ до Ñтандартного +Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñ– початковий файл вже має ÑÑƒÑ„Ñ–ÐºÑ Ð½Ð°Ð·Ð²Ð¸ \fI.suf\fP, буде показано +попередженнÑ, а файл буде пропущено під Ñ‡Ð°Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸. +.IP "" +При розпаковуванні розпізнавати файли із ÑуфікÑом назви \fI.suf\fP, окрім +файлів із ÑуфікÑами назв \fB.xz\fP, \fB.txz\fP, \fB.lzma\fP, \fB.tlz\fP або \fB.lz\fP. Якщо +початковий файл мав ÑÑƒÑ„Ñ–ÐºÑ Ð½Ð°Ð·Ð²Ð¸ \fI.suf\fP, Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ файла +Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ†ÐµÐ¹ ÑÑƒÑ„Ñ–ÐºÑ Ð±ÑƒÐ´Ðµ вилучено. +.IP "" +При ÑтиÑканні або розпакуванні необроблених потоків даних (\fB\-\-format=raw\fP) +ÑÑƒÑ„Ñ–ÐºÑ Ñлід вказувати завжди, Ñкщо Ð·Ð°Ð¿Ð¸Ñ Ð½Ðµ виконуєтьÑÑ Ð´Ð¾ Ñтандартного +виведеннÑ, оÑкільки типового ÑуфікÑа назви Ð´Ð»Ñ Ð½ÐµÐ¾Ð±Ñ€Ð¾Ð±Ð»ÐµÐ½Ð¸Ñ… потоків даних не +передбачено. +.TP +\fB\-\-files\fP[\fB=\fP\fIфайл\fP] +Прочитати назви файлів Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ з файла \fIфайл\fP; Ñкщо \fIfile\fP не вказано, +назви файлів буде прочитано зі Ñтандартного потоку вхідних даних. Ðазви +файлів має бути відокремлено Ñимволом нового Ñ€Ñдка. Символ дефіÑа (\fB\-\fP) +буде оброблено Ñк звичайну назву файла; він не позначатиме Ñтандартного +джерела вхідних даних. Якщо також буде вказано назви файлів у аргументах +Ñ€Ñдка команди, файли з цими назвами буде оброблено до обробки файлів, назви +Ñких було прочитано з файла \fIфайл\fP. +.TP +\fB\-\-files0\fP[\fB=\fP\fIфайл\fP] +Те Ñаме, що Ñ– \fB\-\-files\fP[\fB=\fP\fIфайл\fP], але файли у ÑпиÑку має бути +відокремлено нульовим Ñимволом. +. +.SS "Параметри базового формату файлів та ÑтиÑканнÑ" +.TP +\fB\-F\fP \fIformat\fP, \fB\-\-format=\fP\fIформат\fP +Вказати файл \fIформат\fP Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ розпакуваннÑ: +.RS +.TP +.\" TRANSLATORS: Don't translate bold string B. +\fBauto\fP +Типовий варіант. При ÑтиÑканні \fBauto\fP Ñ” еквівалентом \fBxz\fP. При +розпакуванні формат файла вхідних даних буде виÑвлено автоматично. Зауважте, +що автоматичне виÑÐ²Ð»ÐµÐ½Ð½Ñ Ð½ÐµÐ¾Ð±Ñ€Ð¾Ð±Ð»ÐµÐ½Ð¸Ñ… потоків даних (Ñтворених за допомогою +\fB\-\-format=raw\fP) неможливе. +.TP +\fBxz\fP +СтиÑнути до формату \fB.xz\fP або приймати лише файли \fB.xz\fP при +розпаковуванні. +.TP +\fBlzma\fP, \fBalone\fP +СтиÑнути дані до заÑтарілого формату файлів \fB.lzma\fP або приймати лише файли +\&\fB.lzma\fP при розпаковуванні. Ðльтернативну назву \fBalone\fP може бути +викориÑтано Ð´Ð»Ñ Ð·Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¾Ñ— ÑуміÑноÑті із LZMA Utils. +.TP +\fBlzip\fP +Приймати лише файли \fB.lz\fP при розпакуванні. Підтримки ÑтиÑÐºÐ°Ð½Ð½Ñ Ð½Ðµ +передбачено. +.IP "" +Передбачено підтримку верÑÑ–Ñ— формату \fB.lz\fP 0 та 1. Файли верÑÑ–Ñ— 0 було +Ñтворено \fBlzip\fP 1.3 та Ñтарішими верÑÑ–Ñми. Такі файли не Ñ” поширеними, але +Ñ—Ñ… можна знайти у файлових архівах, оÑкільки певну незначну кількіÑть +пакунків із початковим кодом було випущено у цьому форматі. Також можуть +Ñ–Ñнувати оÑобиÑті файли у цьому форматі. Підтримку Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ +формату верÑÑ–Ñ— 0 було вилучено у \fBlzip\fP 1.18. ВерÑÑ–Ñ \fBlzip\fP 1.4 Ñ– новіші +верÑÑ–Ñ— Ñтворюють файли у форматі верÑÑ–Ñ— 1. +.TP +\fBraw\fP +СтиÑнути або розпакувати потік необроблених даних (лез заголовків). Цей +параметр призначено лише Ð´Ð»Ñ Ð´Ð¾Ñвідчених кориÑтувачів. Ð”Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ +необроблених потоків даних Ñлід кориÑтуватиÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ \fB\-\-format=raw\fP Ñ– +Ñвно вказати ланцюжок фільтруваннÑ, Ñкий за звичайних умов мало б бути +збережено у заголовках контейнера. +.RE +.TP +\fB\-C\fP \fIперевірка\fP, \fB\-\-check=\fP\fIперевірка\fP +Вказати тип перевірки ціліÑноÑті. Контрольну Ñуму буде обчиÑлено на оÑнові +неÑтиÑнених даних Ñ– збережено у файлі \fB.xz\fP. Цей параметр працюватиме, лише +Ñкщо дані ÑтиÑнено до файла у форматі \fB.xz\fP; Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñƒ файлів \fB.lzma\fP +підтримки перевірки ціліÑноÑті не передбачено. Перевірку контрольної Ñуми +(Ñкщо така Ñ”) буде виконано під Ñ‡Ð°Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° \fB.xz\fP. +.IP "" +Підтримувані типи \fIперевірок\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, and B. The command line option --check accepts +.\" only the untranslated strings. +\fBnone\fP +Ðе обчиÑлювати контрольну Ñуму взагалі. Зазвичай, не варто цього робити. Цим +варіантом Ñлід ÑкориÑтатиÑÑ, Ñкщо ціліÑніÑть даних буде перевірено в інший +ÑпоÑіб. +.TP +\fBcrc32\fP +ОбчиÑлити CRC32 за допомогою полінома з IEEE\-802.3 (Ethernet). +.TP +\fBcrc64\fP +ОбчиÑлити CRC64 за допомогою полінома з ECMA\-182. Це типовий варіант, +оÑкільки він дещо кращий за CRC32 при виÑвленні пошкоджених файлів, а +Ñ€Ñ–Ð·Ð½Ð¸Ñ†Ñ Ñƒ швидкоÑті Ñ” незрачною. +.TP +\fBsha256\fP +ОбчиÑлити SHA\-256. Цей варіант дещо повільніший за CRC32 Ñ– CRC64. +.RE +.IP "" +ЦіліÑніÑть заголовків \fB.xz\fP завжди перевірÑють за допомогою CRC32. Таку +перевірку не можна змінити або ÑкаÑувати. +.TP +\fB\-\-ignore\-check\fP +Ðе перевірÑти ціліÑніÑть ÑтиÑнених даних при розпаковуванні. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ CRC32 +у заголовках \fB.xz\fP буде у звичайний ÑпоÑіб перевірено попри цей параметр. +.IP "" +\fBÐе кориÑтуйтеÑÑ Ñ†Ð¸Ð¼ параметром, Ñкщо ви не уÑвідомлюєте наÑлідків ваших дій.\fP Можливі причини ÑкориÑтатиÑÑ Ñ†Ð¸Ð¼ параметром: +.RS +.IP \(bu 3 +Спроба Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… з пошкодженого файла .xz. +.IP \(bu 3 +ÐŸÑ€Ð¸ÑˆÐ²Ð¸Ð´ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ. Це, здебільшого, ÑтоÑуєтьÑÑ SHA\-256 або файлів із +надзвичайно виÑоким рівнем пакуваннÑ. Ðе рекомендуємо кориÑтуватиÑÑ Ñ†Ð¸Ð¼ +параметром з цією метою, Ñкщо ціліÑніÑть файлів не буде перевірено у ÑкийÑÑŒ +інший ÑпоÑіб. +.RE +.TP +\fB\-0\fP ... \fB\-9\fP +Вибрати рівень ÑтиÑканнÑ. Типовим Ñ” \fB\-6\fP. Якщо буде вказано декілька рівнів +ÑтиÑканнÑ, програма викориÑтає оÑтанній вказаний. Якщо вже було вказано +нетиповий ланцюжок фільтрів, вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€Ñ–Ð²Ð½Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¿Ñ€Ð¸Ð·Ð²ÐµÐ´Ðµ до +Ð½ÐµÑ…Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†Ð¸Ð¼ нетиповим ланцюжком фільтрів. +.IP "" +Ð Ñ–Ð·Ð½Ð¸Ñ†Ñ Ð¼Ñ–Ð¶ рівнÑми Ñ” Ñуттєвішою, ніж у \fBgzip\fP(1) Ñ– \fBbzip2\fP(1). Вибрані +параметри ÑтиÑÐºÐ°Ð½Ð½Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð°ÑŽÑ‚ÑŒ вимоги до пам'Ñті під Ñ‡Ð°Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ, +отже викориÑÑ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð´Ñ‚Ð¾ виÑокого Ñ€Ñ–Ð²Ð½Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¼Ð¾Ð¶Ðµ призвеÑти до проблем +під Ñ‡Ð°Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° на заÑтарілих комп'ютерах із невеликим обÑÑгом +оперативної пам'Ñті. Зокрема, \fBне варто викориÑтовувати \-9 Ð´Ð»Ñ ÑƒÑього\fP, Ñк +це чаÑто буває Ð´Ð»Ñ \fBgzip\fP(1) Ñ– \fBbzip2\fP(1). +.RS +.TP +\fB\-0\fP ... \fB\-3\fP +Це дещо швидші набори налаштувань. \fB\-0\fP іноді Ñ” швидшим за \fBgzip \-9\fP, +забезпечуючи набагато більший коефіцієнт ÑтиÑканнÑ. Вищі рівні чаÑто мають +швидкіÑть, Ñку можна порівнÑти з \fBbzip2\fP(1) із подібним або кращим +коефіцієнтом ÑтиÑканнÑ, хоча результати значно залежать від типу даних, Ñкі +ÑтиÑкають. +.TP +\fB\-4\fP ... \fB\-6\fP +СтиÑÐºÐ°Ð½Ð½Ñ Ð²Ñ–Ð´ доброго до дуже доброго Ñ€Ñ–Ð²Ð½Ñ Ñ–Ð· одночаÑним підтриманнÑм +помірного Ñ€Ñ–Ð²Ð½Ñ ÑÐ¿Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті заÑобом розпаковуваннÑ, навіть Ð´Ð»Ñ +заÑтарілих ÑиÑтеми. Типовим Ñ” Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB\-6\fP, Ñке Ñ” добрим варіантом Ð´Ð»Ñ +Ð¿Ð¾ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð², Ñкі мають бути придатними до Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð°Ð²Ñ–Ñ‚ÑŒ у +ÑиÑтемах із лише 16\ МіБ оперативної пам'Ñті. (Також можна розглÑнути +варіанти \fB\-5e\fP Ñ– \fB\-6e\fP. Див. \fB\-\-extreme\fP.) +.TP +\fB\-7 ... \-9\fP +Ці варіанти подібні до \fB\-6\fP, але із вищими вимогами щодо пам'Ñті Ð´Ð»Ñ +ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ– розпаковуваннÑ. Можуть бути кориÑними лише Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² +з розміром, що перевищує 8\ МіБ, 16\ МіБ та 32\ МіБ, відповідно. +.RE +.IP "" +Ðа однаковому обладнанні швидкіÑть Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñ” приблизно Ñталою кількіÑтю +байтів ÑтиÑнених даних за Ñекунду. Іншими Ñловами, чим кращим Ñ” ÑтиÑканнÑ, +тим швидшим буде, зазвичай, розпаковуваннÑ. Це також означає, що об'єм +розпакованих виведених даних, Ñкі видає програма за Ñекунду, може коливатиÑÑ +у широкому діапазоні. +.IP "" +У наведеній нижче таблиці підÑумовано можливоÑті шаблонів: +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Шаблон;DictSize;CompCPU;CompMem;DecMem +\-0;256 КіБ;0;3 МіБ;1 МіБ +\-1;1 МіБ;1;9 МіБ;2 МіБ +\-2;2 МіБ;2;17 МіБ;3 МіБ +\-3;4 МіБ;3;32 МіБ;5 МіБ +\-4;4 МіБ;4;48 МіБ;5 МіБ +\-5;8 МіБ;5;94 МіБ;9 МіБ +\-6;8 МіБ;6;94 МіБ;9 МіБ +\-7;16 МіБ;6;186 МіБ;17 МіБ +\-8;32 МіБ;6;370 МіБ;33 МіБ +\-9;64 МіБ;6;674 МіБ;65 МіБ +.TE +.RE +.RE +.IP "" +ОпиÑи Ñтовпчиків: +.RS +.IP \(bu 3 +DictSize Ñ” розміром Ñловника LZMA2. ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñловника, розмір Ñкого +перевищує розмір неÑтиÑненого файла, — проÑта витрата пам'Ñті. ОÑÑŒ чому не +варто викориÑтовувати шаблони \fB\-7\fP ... \fB\-9\fP, Ñкщо у них немає реальної +потреби. Ð”Ð»Ñ \fB\-6\fP та нижчих рівнів об'єм витраченої пам'Ñті, зазвичай, +такий низький, що цей фактор ні на що не впливає. +.IP \(bu 3 +CompCPU Ñ” Ñпрощеним предÑтавленнÑм параметрів LZMA2, Ñкі впливають на +швидкіÑть ÑтиÑканнÑ. Розмір Ñловника також впливає на швидкіÑть, тому, хоча +Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ CompCPU Ñ” однаковим Ð´Ð»Ñ Ñ€Ñ–Ð²Ð½Ñ–Ð² \fB\-6\fP ... \fB\-9\fP, обробка на вищих +рівнÑÑ… вÑе одно Ñ” трошки повільнішою. Що отримати повільніше Ñ–, ймовірно, +краще ÑтиÑканнÑ, див. \fB\-\-extreme\fP. +.IP \(bu 3 +CompMem міÑтить вимоги до пам'Ñті заÑобу ÑтиÑÐºÐ°Ð½Ð½Ñ Ñƒ однопотоковому +режимі. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶ÑƒÑ‚ÑŒ бути дещо різними Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¸Ñ… верÑій \fBxz\fP. +.IP \(bu 3 +У DecMem міÑÑ‚ÑтьÑÑ Ð²Ð¸Ð¼Ð¾Ð³Ð¸ до пам'Ñті при розпаковуванні. Тобто параметри +заÑобу ÑтиÑÐºÐ°Ð½Ð½Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð°ÑŽÑ‚ÑŒ вимоги до пам'Ñті при розпаковуванні. Точний +об'єм пам'Ñті, Ñка потрібна Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ, дещо перевищує розмір +Ñловника LZMA2, але Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ таблиці було округлено до наÑтупного цілого +Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐœÑ–Ð‘. +.RE +.IP "" +Вимоги до пам'Ñті у багатопотоковому режимі Ñ” значно вищими, ніж у +однопотоковому. З типовим значеннÑм \fB\-\-block\-size\fP Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ потоку треба +3*3*DictSize Ð¿Ð»ÑŽÑ CompMem або DecMem. Ðаприклад, Ð´Ð»Ñ Ñ‡Ð¾Ñ‚Ð¸Ñ€ÑŒÐ¾Ñ… потоків з +шаблоном \fB\-6\fP потрібно 660\(en670\ МіБ пам'Ñті. +.TP +\fB\-e\fP, \fB\-\-extreme\fP +ВикориÑтати повільніший варіант вибраного Ñ€Ñ–Ð²Ð½Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ (\fB\-0\fP ... \fB\-9\fP) +у Ñподіванні отримати трохи кращий коефіцієнт ÑтиÑканнÑ, але, Ñкщо не +поталанить, можна його Ñ– погіршити. Ðе впливає на викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті при +розпаковуванні, але викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті при ÑтиÑканні дещо збільшитьÑÑ Ð½Ð° +рівнÑÑ… \fB\-0\fP ... \fB\-3\fP. +.IP "" +ОÑкільки Ñ–Ñнує два набори налаштувань із розмірами Ñловників 4\ МіБ та 8\ МіБ, у наборах \fB\-3e\fP Ñ– \fB\-5e\fP викориÑтано трошки швидші параметри (нижче +CompCPU), ніж у наборах \fB\-4e\fP Ñ– \fB\-6e\fP, відповідно. Тому двох однакових +наборів у ÑпиÑку немає. +.RS +.RS +.PP +.TS +tab(;); +c c c c c +n n n n n. +Шаблон;DictSize;CompCPU;CompMem;DecMem +\-0e;256 КіБ;8;4 МіБ;1 МіБ +\-1e;1 МіБ;8;13 МіБ;2 МіБ +\-2e;2 МіБ;8;25 МіБ;3 МіБ +\-3e;4 МіБ;7;48 МіБ;5 МіБ +\-4e;4 МіБ;8;48 МіБ;5 МіБ +\-5e;8 МіБ;7;94 МіБ;9 МіБ +\-6e;8 МіБ;8;94 МіБ;9 МіБ +\-7e;16 МіБ;8;186 МіБ;17 МіБ +\-8e;32 МіБ;8;370 МіБ;33 МіБ +\-9e;64 МіБ;8;674 МіБ;65 МіБ +.TE +.RE +.RE +.IP "" +Ðаприклад, передбачено загалом чотири набори налаштувань із викориÑтаннÑм +Ñловника у 8\ МіБ, порÑдок Ñких від найшвидшого до найповільнішого Ñ” таким: +\fB\-5\fP, \fB\-6\fP, \fB\-5e\fP Ñ– \fB\-6e\fP. +.TP +\fB\-\-fast\fP +.PD 0 +.TP +\fB\-\-best\fP +.PD +Це дещо оманливі альтернативні варіанти Ð´Ð»Ñ \fB\-0\fP Ñ– \fB\-9\fP, +відповідно. Реалізовано лише Ð´Ð»Ñ Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¾Ñ— ÑуміÑноÑті із LZMA +Utils. ÐамагайтеÑÑ Ð½Ðµ кориÑтуватиÑÑ Ñ†Ð¸Ð¼Ð¸ варіантами параметрів. +.TP +\fB\-\-block\-size=\fP\fIрозмір\fP +При ÑтиÑканні до формату \fB.xz\fP поділити вхідні дані на блоки у \fIрозмір\fP +байтів. Ці блоки буде ÑтиÑнуто незалежно один від одного, що допоможе у +багатопотоковій обробці Ñ– зробить можливим обмежене Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð´Ð¾Ñтупу +до будь\-Ñких даних. Цим параметром Ñлід типово кориÑтуватиÑÑ Ð´Ð»Ñ +Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð³Ð¾ розміру блоку у багатопотоковому режимі обробки, але +цим параметром можна також ÑкориÑтатиÑÑ Ð² однопотоковому режимі обробки. +.IP "" +У багатопотоковому режимі Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ потоку буде отримано Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ñ–Ð² +вхідних Ñ– вихідних даних майже утричі більше за \fIрозмір\fP байтів. Типовий +\fIрозмір\fP утричі більший за розмір Ñловника LZMA2 або дорівнює 1 МіБ, буде +вибрано більше значеннÑ. Типовим добрим значеннÑм буде значеннÑ, Ñке у +2\(en4 рази перевищує розмір Ñловника LZMA2 або дорівнює принаймні 1 +МіБ. ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIрозмір\fP, Ñке Ñ” меншим за розмір Ñловника LZMA2, +має наÑлідком марну витрату оперативної пам'Ñті, оÑкільки його викориÑÑ‚Ð°Ð½Ð½Ñ +призводить до того, що буфер Ñловника LZMA2 ніколи не буде викориÑтано +повніÑтю. У багатопотоковому режимі розміри блоків зберігатимутьÑÑ Ñƒ +заголовках блоків. Ці дані потрібні Ð´Ð»Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð³Ð¾ розпаковуваннÑ. +.IP "" +У однопотоковому режимі поділ на блоки типово не +виконуватиметьÑÑ. Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ параметра не впливатиме на +викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті. У заголовках блоків не зберігатимутьÑÑ Ð´Ð°Ð½Ñ– щодо +розміру, отже файли, Ñкі Ñтворено в однопотоковому режимі не будуть +ідентичними до файлів, Ñкі Ñтворено у багатопотоковому режимі. Те, що у +заголовках блоків не зберігатимутьÑÑ Ð´Ð°Ð½Ñ– щодо розміру також означає, що +\fBxz\fP не зможе розпаковувати такі файли у багатопотоковому режимі. +.TP +\fB\-\-block\-list=\fP\fIзапиÑи\fP +При ÑтиÑканні у форматі \fB.xz\fP починати новий блок із необов'Ñзковим +ланцюжком фільтрів піÑÐ»Ñ Ð²ÐºÐ°Ð·Ð°Ð½Ð¾Ñ— кількоÑті інтервалів неÑтиÑнених даних. +.IP "" +\fIзапиÑи\fP Ñ” ÑпиÑком відокремлених комами значень. Кожен Ð·Ð°Ð¿Ð¸Ñ ÑкладаєтьÑÑ Ð· +необов'Ñзкового номера ланцюжка фільтрів від 0 до 9, піÑÐ»Ñ Ñкого йде +двокрапка (\fB:\fP) Ñ– необхідний розмір неÑтиÑнутих даних. ÐŸÑ€Ð¾Ð¿ÑƒÑ‰ÐµÐ½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñу +(дві або більше поÑлідовних ком) Ñ” Ñкороченим варіантом Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +викориÑÑ‚Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€Ñƒ та фільтрів попереднього запиÑу. +.IP "" +Якщо файл вхідних даних Ñ” більшим за розміром за Ñуму розмірів \fIзапиÑів\fP, +оÑтаннє Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ \fIрозмірах\fP буде повторено до ÐºÑ–Ð½Ñ†Ñ Ñ„Ð°Ð¹Ð»Ð°. ОÑобливе +Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB0\fP може бути викориÑтано Ñк оÑтанній розмір, щоб позначити, що +решту файла має бути закодовано Ñк єдиний блок. +.IP "" +Ðльтернативний ланцюжок фільтрів Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ блоку можна вказати в поєднанні +з параметрами \fB\-\-filters1=\fP\fIфільтри\fP \&...\& \fB\-\-filters9=\fP\fIфільтри\fP. Ці +параметри визначають ланцюжки фільтрів з ідентифікатором у діапазоні +1\(en9. Ланцюжок фільтрів 0 можна викориÑтовувати Ð´Ð»Ñ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° типовий +ланцюжок фільтрів — це те Ñаме, що не вказувати ланцюжок +фільтрів. Ідентифікатор ланцюжка фільтрів можна викориÑтовувати перед +неÑтиÑненим розміром, піÑÐ»Ñ Ñкого йде двокрапка (\fB:\fP). Ðаприклад, Ñкщо +вказати \fB\-\-block\-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB\fP, блоки будуть +Ñтворені так: +.RS +.IP \(bu 3 +Ланцюжок фільтрів задано \fB\-\-filters1\fP із вхідними даними у 2 МіБ +.IP \(bu 3 +Ланцюжок фільтрів задано \fB\-\-filters3\fP із вхідними даними у 2 МіБ +.IP \(bu 3 +Ланцюжок фільтрів задано \fB\-\-filters2\fP із вхідними даними у 4 МіБ +.IP \(bu 3 +Ланцюжок фільтрів задано \fB\-\-filters2\fP із вхідними даними у 4 МіБ +.IP \(bu 3 +Типовий ланцюжок даних Ñ– вхідні дані у 2 МіБ +.IP \(bu 3 +Типовий ланцюжок фільтрів та вхідні дані у 4 МіБ Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ блоку до ÐºÑ–Ð½Ñ†Ñ +вхідних даних. +.RE +.IP "" +Якщо вказати розмір, Ñкий перевищує розмір блоку кодувальника (або типове +Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ режимі із потоками обробки, або значеннÑ, Ñке вÑтановлено за +допомогою \fB\-\-block\-size=\fP\fIрозмір\fP), заÑіб ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ñтворить додаткові +блоки, зберігаючи межі, Ñкі вказано у \fIзапиÑах\fP. Ðаприклад, Ñкщо вказати +\fB\-\-block\-size=10MiB\fP \fB\-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB\fP, а файл +вхідних даних має розмір 80 МіБ, буде отримано такі 11 блоків: 5, 10, 8, 10, +2, 10, 10, 4, 10, 10 Ñ– 1 МіБ. +.IP "" +У багатопотоковому режимі розмір блоків буде збережено у заголовках +блоків. Програма не зберігатиме ці дані у однопотоковому режимі, отже +закодований результат не буде ідентичним до отриманого у багатопотоковому +режимі. +.TP +\fB\-\-flush\-timeout=\fP\fIчаÑ_очікуваннÑ\fP +При ÑтиÑканнÑ, Ñкщо з моменту попереднього Ð²Ð¸Ñ‚Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¼Ð¸Ð½Ðµ понад +\fIчаÑ_очікуваннÑ\fP міліÑекунд (додатне ціле значеннÑ) Ñ– Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¸Ñ… +даних буде заблоковано, уÑÑ– вхідні дані у черзі обробки буде витерто з +кодувальника Ñ– зроблено доÑтупним у потоці вихідних даних. Це може бути +кориÑним, Ñкщо \fBxz\fP викориÑтовують Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…, Ñкі передають +потоком мережею. Ðевеликі Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñƒ \fIчаÑ_очікуваннÑ\fP зроблÑть дані +доÑтупними на боці Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ–Ð· малою затримкою, а великі Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚ +\fIчаÑ_очікуваннÑ\fP уможливлÑть кращий коефіцієнт ÑтиÑканнÑ. +.IP "" +Типово, цю можливіÑть вимкнено. Якщо цей параметр вказано декілька разів, +буде викориÑтано лише оÑтаннє вказане значеннÑ. ОÑобливим значеннÑм +аргументу \fIчаÑ_очікуваннÑ\fP, рівним \fB0\fP, можна ÑкориÑтатиÑÑ Ð´Ð»Ñ Ð²Ð¸Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ +цієї можливоÑті Ñвним чином. +.IP "" +Ð¦Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ñ–Ñть недоÑтупна у ÑиÑтемах, Ñкі не Ñ” ÑиÑтемами POSIX. +.IP "" +.\" FIXME +\fBÐ¦Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ñ–Ñть уÑе ще Ñ” екÑпериментальною.\fP У поточній верÑÑ–Ñ—, \fBxz\fP не +може розпаковувати потік даних у режимі реального чаÑу через те, у Ñкий +ÑпоÑіб \fBxz\fP виконує буферизацію. +.TP +\fB\-\-no\-sync\fP +Ðе Ñинхронізувати файл Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð° його каталог із приÑтроєм Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ +даних до Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ð³Ð¾ файла. Це може підвищити швидкодію, Ñкщо +виконуєтьÑÑ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð±Ð°Ð³Ð°Ñ‚ÑŒÐ¾Ñ… малих файлів. Втім, Ñкщо +ÑиÑтема аварійно завершує роботу невдовзі піÑÐ»Ñ Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ, можлива ÑитуаціÑ, +коли файл Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ буде запиÑано на приÑтрій Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…, а дію з +Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ запиÑано. У цьому випадку буде знищено дані Ñк початкового +файла, так Ñ– файла призначеннÑ. +.IP "" +Цей параметр матиме хоч Ñкий вплив, лише Ñкщо \fBxz\fP вилучає початковий +файл. Ð’ інших випадках ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð½Ðµ виконуєтьÑÑ. +.IP "" +Синхронізацію Ñ– \fB\-\-no\-sync\fP було додано у верÑÑ–Ñ— \fBxz\fP 5.7.1alpha. +.TP +\fB\-\-memlimit\-compress=\fP\fIобмеженнÑ\fP +Ð’Ñтановити Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті при ÑтиÑканні. Якщо цей +параметр вказано декілька разів, враховано буде лише оÑтаннє вказане +значеннÑ. +.IP "" +Якщо параметри ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰ÑƒÑŽÑ‚ÑŒ \fIобмеженнÑ\fP, \fBxz\fP Ñпробує Ñкоригувати +параметри так, щоб Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ðµ було перевищено, Ñ– покаже Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ +те, що було виконано автоматичне коригуваннÑ. ÐšÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ виконано у +такому порÑдку: Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾Ñті потоків обробки, Ð¿ÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ñƒ +однопотоковий режим, Ñкщо хоч в одному потоці багатопотокового режиму буде +перевищено \fIобмеженнÑ\fP, Ñ– нарешті, Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€Ñƒ Ñловника LZMA2. +.IP "" +При ÑтиÑканні з викориÑтаннÑм \fB\-\-format=raw\fP, або Ñкщо було вказано +\fB\-\-no\-adjust\fP, може бути зменшена лише кількіÑть потоків обробки, оÑкільки +це може бути зроблено без впливу на ÑтиÑнені виведені дані. +.IP "" +Якщо \fIобмеженнÑ\fP не може бути виконано за допомогою коригувань, Ñкі опиÑано +вище, буде показано Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку, а \fBxz\fP завершить роботу зі +Ñтаном виходу 1. +.IP "" +Ðргумент \fIобмеженнÑ\fP можна вказати у декілька ÑпоÑобів: +.RS +.IP \(bu 3 +ЗначеннÑм \fIобмеженнÑ\fP може бути додатне ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ байтах. Можна +ÑкориÑтатиÑÑ Ñ†Ñ–Ð»Ð¾Ñ‡Ð¸Ñельним ÑуфікÑом, подібним до \fBMiB\fP. Приклад: +\fB\-\-memlimit\-compress=80MiB\fP +.IP \(bu 3 +Ðргумент \fIобмеженнÑ\fP може бути задано у відÑотках від загальної фізичної +пам'Ñті ÑиÑтеми (RAM). Це може бути кориÑним оÑобливо при вÑтановленні +змінної Ñередовища \fBXZ_DEFAULTS\fP у Ñкрипті ініціалізації ÑиÑтеми, Ñкий Ñ” +Ñпільним Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¸Ñ… комп'ютерів. У такий ÑпоÑіб можна вказати вищий рівень +Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑиÑтем із більшим об'ємом пам'Ñті. Приклад: +\fB\-\-memlimit\-compress=70%\fP +.IP \(bu 3 +Ðргументу \fIобмеженнÑ\fP може бути повернуто типове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²ÑтановленнÑм +Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB0\fP. У поточній верÑÑ–Ñ— це еквівалентно до вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +аргументу \fIобмеженнÑ\fP \fBmax\fP (без Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті). +.RE +.IP "" +Ð”Ð»Ñ 32\-бітової верÑÑ–Ñ— \fBxz\fP передбачено оÑобливий випадок: Ñкщо \fIобмеженнÑ\fP +перевищуватиме \fB4020\ МіБ\fP, Ð´Ð»Ñ \fIобмеженнÑ\fP буде вÑтановлено Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +\fB4020\ MiB\fP. Ðа MIPS32 заміÑть цього буде викориÑтано \fB2000\ MiB\fP. (Це не +ÑтоÑуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½ÑŒ \fB0\fP Ñ– \fBmax\fP. Подібної можливоÑті Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ +Ñ–Ñнує.) Це може бути кориÑним, коли 32\-бітовий виконуваний файл має доÑтуп +до проÑтору Ð°Ð´Ñ€ÐµÑ Ñƒ 4\ ГіБ (2 GiB на MIPS32), хоча, ÑподіваємоÑÑ, не +зашкодить Ñ– в інших випадках. +.IP "" +Див. також розділ \fBВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті\fP. +.TP +\fB\-\-memlimit\-decompress=\fP\fIобмеженнÑ\fP +Ð’Ñтановити Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð°Ð¼'Ñті на розпаковуваннÑ. це також вплине на режим +\fB\-\-list\fP. Якщо Ð´Ñ–Ñ Ñ” неможливою без Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰ÐµÐ½Ð½Ñ \fIобмеженнÑ\fP, \fBxz\fP покаже +Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку Ñ– Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° не +відбудетьÑÑ. Див. \fB\-\-memlimit\-compress=\fP\fIобмеженнÑ\fP, щоб дізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ +про те, Ñк можна задати \fIобмеженнÑ\fP. +.TP +\fB\-\-memlimit\-mt\-decompress=\fP\fIобмеженнÑ\fP +Ð’Ñтановити Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð³Ð¾ +розпаковуваннÑ. Це може вплинути лише на кількіÑть потоків обробки; це +ніколи не призводитиме до відмови \fBxz\fP у розпаковуванні файла. Якщо +\fIÐ¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ñ” надто низьким\fP, щоб уможливити будь\-Ñку багатопотокову +обробку, \fIобмеженнÑ\fP буде проігноровано, Ñ– \fBxz\fP продовжить обробку в +однопотоковому режимі. Зауважте, що Ñкщо викориÑтано також +\fB\-\-memlimit\-decompress\fP, цей параметр буде заÑтоÑовано до обох режимів, +однопотокового та багатопотокового, а отже, задіÑне \fIобмеженнÑ\fP Ð´Ð»Ñ +багатопотокового режиму ніколи не перевищуватиме обмеженнÑ, Ñке вÑтановлено +за допомогою \fB\-\-memlimit\-decompress\fP. +.IP "" +Ðа відміну від інших параметрів Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті, +\fB\-\-memlimit\-mt\-decompress=\fP\fIобмеженнÑ\fP міÑтить Ñпецифічне Ð´Ð»Ñ ÑиÑтеми +типове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIобмеженнÑ\fP. Можна ÑкориÑтатиÑÑ \fBxz \-\-info\-memory\fP Ð´Ð»Ñ +переглÑду поточного значеннÑ. +.IP "" +Цей параметр Ñ– його типове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ–Ñнують, оÑкільки без будь\-Ñких обмежень +заÑіб Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ñ– підтримкою потокової обробки міг би намагатиÑÑ +отримати величезний об'єм пам'Ñті Ð´Ð»Ñ Ð´ÐµÑких файлів вхідних даних. Якщо +типове \fIобмеженнÑ\fP Ñ” надто низьким Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ñ— ÑиÑтеми, не вагайтеÑÑ Ñ– +збільшуйте \fIобмеженнÑ\fP, але ніколи не вÑтановлюйте Ð´Ð»Ñ Ð½ÑŒÐ¾Ð³Ð¾ значеннÑ, Ñке +Ñ” більшим за придатний до кориÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±'єм оперативної пам'Ñті, оÑкільки +за відповідних файлів вхідних даних \fBxz\fP Ñпробує ÑкориÑтатиÑÑ Ñ†Ð¸Ð¼ об'ємом +пам'Ñті, навіть із низькою кількіÑтю потоків обробки. Ð’Ð¸Ñ‡ÐµÑ€Ð¿Ð°Ð½Ð½Ñ Ð¾Ð±'єму +оперативної пам'Ñті або викориÑÑ‚Ð°Ð½Ð½Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ñ— пам'Ñті на диÑку не покращить +швидкодію ÑиÑтеми під Ñ‡Ð°Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ. +.IP "" +Див. \fB\-\-memlimit\-compress=\fP\fIобмеженнÑ\fP, щоб ознайомитиÑÑ Ñ–Ð· можливими +ÑпоÑобами Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIобмеженнÑ\fP. Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ \fIобмеженнÑ\fP Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +\fB0\fP відновлює типове Ñпецифічне Ð´Ð»Ñ ÑиÑтеми Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIобмеженнÑ\fP. +.TP +\fB\-M\fP \fIобмеженнÑ\fP, \fB\-\-memlimit=\fP\fIобмеженнÑ\fP, \fB\-\-memory=\fP\fIобмеженнÑ\fP +Є еквівалентом Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB\-\-memlimit\-compress=\fP\fIобмеженнÑ\fP +\fB\-\-memlimit\-decompress=\fP\fIобмеженнÑ\fP +\fB\-\-memlimit\-mt\-decompress=\fP\fIобмеженнÑ\fP. +.TP +\fB\-\-no\-adjust\fP +Показати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку Ñ– завершити роботу, Ñкщо не вдаÑтьÑÑ +виконати умови щодо Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті без ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ +параметрів, Ñкі впливають на ÑтиÑнених виведених даних. Тобто це заборонÑÑ” +\fBxz\fP перемикати кодувальник з багатопотокового режиму на однопотоковий +режим Ñ– зменшувати розмір Ñловника LZMA2. Ðавіть Ñкщо викориÑтано цей +параметр, кількіÑть потоків може бути зменшено Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° +викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті, оÑкільки це не вплине на результати ÑтиÑканнÑ. +.IP "" +Ðвтоматичне ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð²Ð¶Ð´Ð¸ буде вимкнено при Ñтворенні потоків +необроблених даних (\fB\-\-format=raw\fP). +.TP +\fB\-T\fP \fIпотоки\fP, \fB\-\-threads=\fP\fIпотоки\fP +Вказати кількіÑть потоків обробки, Ñкими Ñлід ÑкориÑтатиÑÑ. Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ +аргументу \fIпотоки\fP оÑобливого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB0\fP наказує \fBxz\fP викориÑтати не +більше потоків обробки, ніж передбачено підтримку у процеÑорах +ÑиÑтеми. Ð¡Ð¿Ñ€Ð°Ð²Ð¶Ð½Ñ ÐºÑ–Ð»ÑŒÐºÑ–Ñть потоків може бути меншою за Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIпотоки\fP, +Ñкщо файл вхідних даних не Ñ” доÑтатньо великим Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ–Ð»Ñƒ на потоки обробки +при заданих параметрах або Ñкщо викориÑÑ‚Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¸Ñ… потоків призведе до +Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті. +.IP "" +ЗаÑоби ÑтиÑÐºÐ°Ð½Ð½Ñ Ð² однопотоковому та багатопотоковому режимі дають різні +результати. Однопотоковий заÑіб ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð°Ñть найменший розмір файла, але +лише результати роботи багатопотокового заÑобу ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¼Ð¾Ð¶Ðµ бути +розпаковано з викориÑтаннÑм декількох потоків. Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñƒ +\fIпотоки\fP Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB1\fP призведе до викориÑÑ‚Ð°Ð½Ð½Ñ Ð¾Ð´Ð½Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð³Ð¾ +режиму. Ð’ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñƒ \fIпотоки\fP будь\-Ñкого іншого значеннÑ, +включно з \fB0\fP, призведе до викориÑÑ‚Ð°Ð½Ð½Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð³Ð¾ заÑобу ÑтиÑканнÑ, +навіть Ñкщо у ÑиÑтемі передбачено підтримки лише одного апаратного потоку +обробки даних. (ВерÑÑ–Ñ \fBxz\fP 5.2.x у цьому випадку викориÑтовувала +однопотоковий режим.) +.IP "" +Щоб ÑкориÑтатиÑÑ Ð±Ð°Ð³Ð°Ñ‚Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¸Ð¼ режимом із лише одним потоком обробки, +вÑтановіть Ð´Ð»Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñƒ \fIпотоки\fP Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB+1\fP. ÐŸÑ€ÐµÑ„Ñ–ÐºÑ \fB+\fP не впливає +на значеннÑ, окрім \fB1\fP. ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті можуть перемкнути +\fBxz\fP в однопотоковий режим, Ñкщо не викориÑтано параметр +\fB\-\-no\-adjust\fP. Підтримку \fB+\fP prefix було додано у верÑÑ–Ñ— \fBxz\fP 5.4.0. +.IP "" +Якщо було вказано автоматичне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾Ñті потоків Ñ– не вказано +Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті, буде викориÑтано Ñпецифічне Ð´Ð»Ñ ÑиÑтеми +типове м'Ñке Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾Ð³Ð¾ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾Ñті потоків обробки. Це +Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ñ” м'Ñким у ÑенÑÑ– того, що його буде проігноровано, Ñкщо кількіÑть +потоків зрівнÑєтьÑÑ Ð· одиницею, а отже, м'Ñке Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ñ–ÐºÐ¾Ð»Ð¸ не +запобігатиму у \fBxz\fP ÑтиÑканню або розпаковуванню. Це типове м'Ñке Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ +не перемкне \fBxz\fP з багатопотокового режиму на однопотоковий режим. Ðктивні +Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ð½Ð° переглÑнути за допомогою команди \fBxz \-\-info\-memory\fP. +.IP "" +У поточній верÑÑ–Ñ— єдиним ÑпоÑобом поділу на потоки обробки Ñ” поділ вхідних +даних на блоки Ñ– ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ†Ð¸Ñ… блоків незалежно один від одного. Типовий +розмір блоку залежить від Ñ€Ñ–Ð²Ð½Ñ ÑтиÑканнÑ. Його може бути перевизначено за +допомогою параметра \fB\-\-block\-size=\fP\fIрозмір\fP. +.IP "" +Ð Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð· потоками обробки працює лише Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð², Ñкі міÑÑ‚Ñть декілька +блоків із даними щодо розміру у заголовках блоків. Цю умову задовольнÑють +уÑÑ– доÑтатньо великі файли, Ñкі ÑтиÑнено у багатопотоковому режимі, але не +задовольнÑють будь\-Ñкі файли, Ñкі було ÑтиÑнуто у однопотоковому режимі, +навіть Ñкщо було викориÑтано параметр \fB\-\-block\-size=\fP\fIрозмір\fP. +.IP "" +Типовим значеннÑм Ð´Ð»Ñ \fIпотоків\fP Ñ” \fB0\fP. У \fBxz\fP 5.4.x та Ñтаріших верÑÑ–ÑÑ… +типовим значеннÑм Ñ” \fB1\fP. +. +.SS "Ðетипові ланцюжки фільтрів заÑобу ÑтиÑканнÑ" +Ðетиповий ланцюжок Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð»ÑŽÑ” докладне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð² +ÑтиÑÐºÐ°Ð½Ð½Ñ Ð·Ð°Ð¼Ñ–Ñть викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð², Ñкі пов'Ñзано із наперед +визначеними рівнÑми ÑтиÑканнÑ. Якщо вказано нетиповий ланцюжок фільтрів, +параметри рівнів ÑтиÑÐºÐ°Ð½Ð½Ñ (\fB\-0\fP \&...\& \fB\-9\fP Ñ– \fB\-\-extreme\fP), Ñкі +передують їм у Ñ€Ñдку команди, буде знехтувано. Якщо параметр Ñ€Ñ–Ð²Ð½Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ +вказано піÑÐ»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ або декількох параметрів нетипового ланцюжка фільтрів, +буде викориÑтано рівень ÑтиÑканнÑ, а попередніми параметрами ланцюжка +Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ знехтувано. +.PP +Ланцюжок фільтрів можна порівнÑти із конвеєром у командному Ñ€Ñдку. При +ÑтиÑканні неÑтиÑнені вхідні дані потраплÑють до першого фільтра, виведені +ним дані йдуть до наÑтупного фільтра (Ñкщо такий Ñ”). Виведені оÑтаннім +фільтром дані буде запиÑано до ÑтиÑненого файла. МакÑимальна кількіÑть +фільтрів у ланцюжку дорівнює чотирьом, але у типовому ланцюжку фільтрів +викориÑтовують один або два фільтри. +.PP +У багатьох фільтрів Ñ” Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° міÑце Ð¿ÐµÑ€ÐµÐ±ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ ланцюжку фільтрів: +деÑкі фільтри можуть працювати, лише Ñкщо вони Ñ” оÑтанніми у ланцюжку, +деÑкі, лише Ñкщо не оÑтанніми, а деÑкі працюють у будь\-Ñкій позиції +ланцюжка. Залежно від фільтра, це Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ñ” наÑлідком Ñтруктури фільтра +або Ñ–Ñнує Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð±Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ із захиÑтом. +.PP +Ðетиповий ланцюжок фільтрів можна вказати двома різними ÑпоÑобами. Параметри +\fB\-\-filters=\fP\fIфільтри\fP Ñ– \fB\-\-filters1=\fP\fIфільтри\fP \&...\& +\fB\-\-filters9=\fP\fIфільтри\fP надають змогу вказати цілий ланцюжок фільтрів в +одному варіанті з викориÑтаннÑм ÑинтакÑиÑу Ñ€Ñдків фільтрів liblzma. Крім +того, ланцюжок фільтрів можна вказати за допомогою одного або кількох +окремих параметрів Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ тому порÑдку, в Ñкому Ñ—Ñ… Ñлід викориÑтати +у ланцюжку фільтрів. Тобто порÑдок окремих параметрів фільтра Ñ” важливим! +Під Ñ‡Ð°Ñ Ð´ÐµÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ¾Ð±Ñ€Ð¾Ð±Ð»ÐµÐ½Ð¸Ñ… потоків (\fB\-\-format=raw\fP) ланцюжок фільтрів +має бути вказано у тому ж порÑдку, що й під Ñ‡Ð°Ñ ÑтиÑненнÑ. Будь\-Ñкий окремий +фільтр або параметри попереднього налаштуваннÑ, вказані перед параметром +повного ланцюжка (\fB\-\-filters=\fP\fIфільтри\fP), буде відкинуто. Окремі фільтри, +указані піÑÐ»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° повного ланцюжка, відновлÑть типовий ланцюжок +фільтрів. +.PP +І параметр повного Ñ– параметр окремого фільтра приймають Ñпецифічні Ð´Ð»Ñ +фільтрів \fIпараметри\fP у форматі ÑпиÑку значень, Ñкі відокремлено +комами. Зайві коми у \fIпараметрах\fP буде проігноровано. У кожного параметра Ñ” +типове значеннÑ, отже, вам Ñлід вказати ті параметри, Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñких ви +хочете змінити. +.PP +Щоб переглÑнути увеÑÑŒ ланцюжок фільтрів та \fIпараметри\fP, ÑкориÑтайтеÑÑ +командою \fBxz \-vv\fP (тобто, ÑкориÑтайтеÑÑ \fB\-\-verbose\fP двічі). Це працює +також Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду параметрів ланцюжка фільтрів, Ñкий викориÑтано у рівнÑÑ… +ÑтиÑканнÑ. +.TP +\fB\-\-filters=\fP\fIфільтри\fP +Визначає повний ланцюжок фільтрів або шаблон у форматі одного +параметра. Кожен фільтр можна відокремити від інших пробілами або двома +дефіÑами (\fB\-\-\fP). Можливо, \fIфільтри\fP доведетьÑÑ Ð²Ð·Ñти в лапки в командному +Ñ€Ñдку оболонки, щоб Ñ—Ñ… було оброблено Ñк один параметр. Ð”Ð»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +\fIпараметрів\fP ÑкориÑтайтеÑÑ \fB:\fP або \fB=\fP. До шаблона можна додати Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ +\fB\-\fP Ñ– завершити без прапорців або декількома прапорцÑми. Єдиним +підтримуваним прапорцем Ñ” \fBe\fP Ð´Ð»Ñ Ð·Ð°ÑтоÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð¸Ñ… Ñамих параметрів, що й +\fB\-\-extreme\fP. +.TP +\fB\-\-filters1\fP=\fIфільтри\fP ... \fB\-\-filters9\fP=\fIфільтри\fP +Вказати до дев'Ñти додаткових ланцюжків фільтрів, Ñкими можна ÑкориÑтатиÑÑ +за допомогою \fB\-\-block\-list\fP. +.IP "" +Ðаприклад, Ñкщо виконуєтьÑÑ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ñ€Ñ…Ñ–Ð²Ñƒ із виконуваними файлами, за +Ñкими йдуть текÑтові файли, Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÐ²Ð°Ð½Ð¾Ñ— чаÑтини може бути викориÑтано +ланцюжок фільтрів з фільтром BCJ, а Ð´Ð»Ñ Ñ‚ÐµÐºÑтової чаÑтини — лише фільтр +LZMA2. +.TP +\fB\-\-filters\-help\fP +ВивеÑти довідкове Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· опиÑом того, Ñк вказати шаблони та нетипові +ланцюжки фільтрів у параметри \fB\-\-filters\fP Ñ– \fB\-\-filters1=\fP\fIфільтри\fP +\&...\& \fB\-\-filters9=\fP\fIфільтри\fP Ñ– завершити роботу із кодом уÑпіху. +.TP +\fB\-\-lzma1\fP[\fB=\fP\fIпараметри\fP] +.PD 0 +.TP +\fB\-\-lzma2\fP[\fB=\fP\fIпараметри\fP] +.PD +Додати фільтр LZMA1 або LZMA2 до ланцюжка фільтрів. Ці фільтри може бути +викориÑтано лише Ñк оÑтанній фільтр у ланцюжку. +.IP "" +LZMA1 Ñ” заÑтарілим фільтром, підтримку Ñкого збережено майже лише через +викориÑÑ‚Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñƒ файлів \fB.lzma\fP, у Ñких передбачено підтримку лише +LZMA1. LZMA2 Ñ” оновленою верÑією LZMA1, у Ñкій виправлено деÑкі практичні +вади LZMA1. У форматі \fB.xz\fP викориÑтано LZMA2 Ñ– взагалі не передбачено +підтримки LZMA1. ШвидкіÑть ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚Ð° коефіцієнт ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð»Ñ LZMA1 Ñ– +LZMA2 Ñ” практично однаковими. +.IP "" +LZMA1 Ñ– LZMA2 Ñпільно викориÑтовують той Ñамий набір \fIпараметрів\fP: +.RS +.TP +.\" TRANSLATORS: Don't translate bold strings like B, B, +.\" B, B, B, or B because those are command line +.\" options. On the other hand, do translate the italic strings like +.\" I, I, and I, because such italic strings are +.\" placeholders which a user replaces with an actual value. +\fBpreset=\fP\fIшаблон\fP +Скинути уÑÑ– \fIпараметри\fP LZMA1 або LZMA2 до параметрів \fIшаблона\fP. Ðргумент +\fIшаблон\fP ÑкладаєтьÑÑ Ð· цілого чиÑла, піÑÐ»Ñ Ñкого може бути однолітерний +модифікатор шаблона. Ціле чиÑло може належати лише діапазону від \fB0\fP до +\fB9\fP, що відповідає параметрам командного Ñ€Ñдка \fB\-0\fP \&...\& \fB\-9\fP. Єдиним +підтримуваним модифікатором у поточній верÑÑ–Ñ— Ñ” \fBe\fP, щоб відповідає +параметру \fB\-\-extreme\fP. Якщо аргумент \fBшаблон\fP не вказано, типові Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +\fIпараметрів\fP LZMA1 або LZMA2 буде взÑто із шаблона \fB6\fP. +.TP +\fBdict=\fP\fIрозмір\fP +Параметр \fIрозміру\fP Ñловника (буфера журналу) визначає, Ñкільки байтів +нещодавно оброблених неÑтиÑнених даних Ñлід зберігати у пам'Ñті. Ðлгоритм +намагаєтьÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ повторювані поÑлідовноÑті байтів (відповідники) у +неÑтиÑнених даних Ñ– замінити Ñ—Ñ… на поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° дані зі Ñловника. Чим +більшим Ñ” Ñловник, тим вищою Ñ” ймовірніÑть відшукати відповідник. Отже, +Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ \fIрозміру\fP Ñловника, зазвичай, покращує коефіцієнт ÑтиÑканнÑ, але +викориÑÑ‚Ð°Ð½Ð½Ñ Ñловника, розмір Ñкого перевищу Ñ” розмір неÑтиÑненого файла Ñ” +проÑтоюю витратою пам'Ñті. +.IP "" +\fIРозмір\fP типового Ñловника Ñкладає від 64\ КіБ до 64\ МіБ. Мінімальним Ñ” +розмір 4\ КіБ. МакÑимальним розміром Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ñƒ поточній верÑÑ–Ñ— 1.5\ ГіБ (1536\ МіБ). У заÑобі Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¶Ðµ передбачено підтримку Ñловників +на один байт менших за 4\ ГіБ, що Ñ” макÑимальним значеннÑм Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñ–Ð² +потоків даних LZMA1 Ñ– LZMA2. +.IP "" +Ðргумент \fIрозміру\fP Ñловника Ñ– заÑіб пошуку відповідників (\fImf\fP) разом +визначають параметри викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ ÐºÐ¾Ð´ÑƒÐ²Ð°Ð»ÑŒÐ½Ð¸ÐºÐ° LZMA1 або +LZMA2. Ð”Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€Ñ–Ð±ÐµÐ½ такий Ñамий (або більший) \fIрозмір\fP +Ñловника, що Ñ– Ð´Ð»Ñ ÑтиÑканнÑ, отже, викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ Ð·Ð°Ñобу +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ визначено за розміром Ñловника, Ñкий було викориÑтано +Ð´Ð»Ñ ÑтиÑканнÑ. У заголовках \fB.xz\fP зберігаєтьÑÑ \fIрозмір\fP Ñловника або Ñк +2^\fIn\fP, або Ñк 2^\fIn\fP + 2^(\fIn\fP\-1), отже, ці \fIрозміри\fP Ñ” дещо пріоритетними +Ð´Ð»Ñ ÑтиÑканнÑ. Інші \fIрозміри\fP буде отримано округленнÑм при зберіганні у +заголовках \fB.xz\fP. +.TP +\fBlc=\fP\fIlc\fP +Визначає кількіÑть буквальних контекÑтних бітів. Мінімальною кількіÑтю Ñ” 0, +а макÑимальною — 4. Типовою кількіÑтю Ñ” 3. Крім того, Ñума \fIlc\fP Ñ– \fIlp\fP має +не перевищувати 4. +.IP "" +УÑÑ– байти, Ñкі не може бути закодовано Ñк відповідноÑті, буде закодовано Ñк +літерали. Тобто літерали Ñ” проÑто 8\-бітовими байтами, Ñкі буде закодовано по +одному за раз. +.IP "" +При кодуванні літералів роблÑть припущеннÑ, що найвищі біти \fIlc\fP +попереднього неÑтиÑненого байта корелюють із наÑтупним байтом. Ðаприклад, у +типовому текÑті англійÑькою за літерою у верхньому регіÑтрі йде літера у +нижньому регіÑтрі, а за літерою у нижньому регіÑтрі, зазвичай, йде інша +літера у нижньому регіÑтрі. У наборі Ñимволів US\-ASCII найвищими трьома +бітами Ñ” 010 Ð´Ð»Ñ Ð»Ñ–Ñ‚ÐµÑ€ верхнього регіÑтру Ñ– 011 Ð´Ð»Ñ Ð»Ñ–Ñ‚ÐµÑ€ нижнього +регіÑтру. Якщо \fIlc\fP дорівнює принаймні 3, при кодуванні літералів можна +отримати перевагу вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ†Ñ–Ñ”Ñ— влаÑтивоÑті Ð´Ð»Ñ Ð½ÐµÑтиÑнених даних. +.IP "" +Зазвичай, типового Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (3) доÑтатньо. Якщо вам потрібне макÑимальне +ÑтиÑканнÑ, Ñпробуйте \fBlc=4\fP. Іноді це трохи допомагає, а іноді, робить +ÑтиÑÐºÐ°Ð½Ð½Ñ Ð³Ñ–Ñ€ÑˆÐ¸Ð¼. Якщо ÑтиÑÐºÐ°Ð½Ð½Ñ Ñтане гіршим, Ñпробуйте також \fBlc=2\fP. +.TP +\fBlp=\fP\fIlp\fP +Визначає кількіÑть буквальних позиційних бітів. Мінімальною кількіÑтю Ñ” 0, а +макÑимальною — 4. Типовою кількіÑтю Ñ” 0. +.IP "" +\fILp\fP впливає на те, Ñке Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ñƒ неÑтиÑнених даних Ñлід припуÑкати +при кодуванні літералів. Див. \fIpb\fP нижче, щоб дізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про +вирівнюваннÑ. +.TP +\fBpb=\fP\fIpb\fP +Визначає кількіÑть позиційних бітів. Мінімальною кількіÑтю Ñ” 0, а +макÑимальною — 4. Типовою кількіÑтю Ñ” 2. +.IP "" +\fIPb\fP впливає на те, Ñкий тип Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð³Ð°Ð»Ð¾Ð¼ припуÑкатиметьÑÑ Ð´Ð»Ñ +неÑтиÑнених даних. Типовим Ñ” чотирибайтове Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ (2^\fIpb\fP=2^2=4), +Ñке, зазвичай, Ñ” добрим варіантом, Ñкщо немає кращих припущень. +.IP "" +Якщо Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ñ” відомим, вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¸Ð¼ чином \fIpb\fP може трохи +зменшити розмір файла. Ðаприклад, у текÑтових файлах із однобайтовим +вирівнюваннÑм (US\-ASCII, ISO\-8859\-*, UTF\-8), вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fBpb=0\fP +може трохи поліпшити ÑтиÑканнÑ. Ð”Ð»Ñ Ñ‚ÐµÐºÑту UTF\-16 добрим варіантом Ñ” +\fBpb=1\fP. Якщо Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ñ” непарним чиÑлом, наприклад 3 байти, найкращим +вибором, ймовірно, Ñ” \fBpb=0\fP. +.IP "" +Хоча прогнозоване Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ð¼Ð¾Ð¶Ð½Ð° Ñкоригувати за допомогою \fIpb\fP Ñ– \fIlp\fP, +у LZMA1 Ñ– LZMA2 дещо пріоритетним Ñ” 16\-байтове вирівнюваннÑ. Це, ймовірно, +Ñлід враховувати при компонуванні форматів файлів, Ñкі, ймовірно, чаÑто +будуть ÑтиÑкатиÑÑ Ð· викориÑтаннÑм LZMA1 або LZMA2. +.TP +\fBmf=\fP\fImf\fP +ЗаÑіб пошуку відповідників має значний вплив на швидкіÑть, викориÑÑ‚Ð°Ð½Ð½Ñ +пам'Ñті та коефіцієнт ÑтиÑÐºÐ°Ð½Ð½Ñ ÐºÐ¾Ð´ÑƒÐ²Ð°Ð»ÑŒÐ½Ð¸ÐºÐ°. Зазвичай, заÑоби пошуку +відповідників на оÑнові ланцюжка хешів Ñ” швидшими за заÑоби пошуку +відповідників на оÑнові двійкового дерева. Типовий заÑіб залежить від +\fIшаблона\fP: Ð´Ð»Ñ 0 викориÑтовують \fBhc3\fP, Ð´Ð»Ñ 1\(en3 — \fBhc4\fP, а Ð´Ð»Ñ Ñ€ÐµÑˆÑ‚Ð¸ +викориÑтовують \fBbt4\fP. +.IP "" +Передбачено підтримку вказаних нижче заÑобів пошуку відповідників. Ðаведені +нижче формули обчиÑÐ»ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ñ” грубими наближеннÑми, Ñкі Ñ” +найближчими до реальних значень, Ñкщо значеннÑм \fIÑловник\fP Ñ” Ñтепінь двійки. +.RS +.TP +\fBhc3\fP +Ланцюжок хешів із 2\- та 3\-байтовим хешуваннÑм +.br +Мінімальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIпріоритетноÑті\fP: 3 +.br +ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті: +.br +\fIdict\fP * 7.5 (Ñкщо \fIdict\fP <= 16 МіБ); +.br +\fIdict\fP * 5.5 + 64 МіБ (Ñкщо \fIdict\fP > 16 МіБ) +.TP +\fBhc4\fP +Ланцюжок хешів із 2\-, 3\- та 4\-байтовим хешуваннÑм +.br +Мінімальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIпріоритетноÑті\fP: 4 +.br +ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті: +.br +\fIdict\fP * 7.5 (Ñкщо \fIdict\fP <= 32 МіБ); +.br +\fIdict\fP * 6.5 (Ñкщо \fIdict\fP > 32 МіБ) +.TP +\fBbt2\fP +Двійкове дерево із 2\-байтовим хешуваннÑм +.br +Мінімальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIпріоритетноÑті\fP: 2 +.br +ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті: \fIdict\fP * 9.5 +.TP +\fBbt3\fP +Двійкове дерево із 2\- Ñ– 3\-байтовим хешуваннÑм +.br +Мінімальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIпріоритетноÑті\fP: 3 +.br +ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті: +.br +\fIdict\fP * 11.5 (Ñкщо \fIdict\fP <= 16 МіБ); +.br +\fIdict\fP * 9.5 + 64 МіБ (Ñкщо \fIdict\fP > 16 МіБ) +.TP +\fBbt4\fP +Двійкове дерево із 2\-, 3\- Ñ– 4\-байтовим хешуваннÑм +.br +Мінімальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIпріоритетноÑті\fP: 4 +.br +ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті: +.br +\fIdict\fP * 11.5 (Ñкщо \fIdict\fP <= 32 МіБ); +.br +\fIdict\fP * 10.5 (Ñкщо \fIdict\fP > 32 МіБ) +.RE +.TP +\fBmode=\fP\fIрежим\fP +Параметр \fIрежиму\fP ÑтиÑÐºÐ°Ð½Ð½Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð°Ñ” ÑпоÑіб, Ñкий буде викориÑтано Ð´Ð»Ñ +аналізу даних, Ñкі Ñтворено заÑобом пошуку відповідників. Підтримуваними +\fIрежимами\fP Ñ” \fBfast\fP (швидкий) Ñ– \fBnormal\fP (нормальний). Типовим Ñ” режим +\fBfast\fP Ð´Ð»Ñ \fIшаблонів\fP 0\(en3 Ñ– режим \fBnormal\fP Ð´Ð»Ñ \fIшаблонів\fP 4\(en9. +.IP "" +Зазвичай, із заÑобом пошуку відповідників на оÑнові ланцюжка хешів +викориÑтовують \fBfast\fP, а із заÑобом пошуку відповідників на оÑнові +двійкового дерева викориÑтовують \fBnormal\fP. Так Ñамо налаштовано Ñ– +\fIшаблони\fP. +.TP +\fBnice=\fP\fIпріоритетніÑть\fP +Вказати, Ñка довжина Ñ” пріоритетною Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾Ñті. Щойно буде виÑвлено +відповідніÑть у принаймні \fIпріоритетніÑть\fP байтів, алгоритм зупинÑтиме +пошук можливих кращих відповідників. +.IP "" +\fIПріоритетніÑтю\fP може бути чиÑло до 2\(en273 байтів. Вищі Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð°ÑŽÑ‚ÑŒ +кращий коефіцієнт ÑтиÑÐºÐ°Ð½Ð½Ñ Ð·Ð° рахунок швидкоÑті. Типове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð¸Ñ‚ÑŒ +від \fIшаблона\fP. +.TP +\fBdepth=\fP\fIглибина\fP +Вказати макÑимальну глибину пошуку у заÑобі пошуку відповідноÑті. Типовим Ñ” +оÑобливе Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ 0, Ñке наказує заÑобу ÑтиÑÐºÐ°Ð½Ð½Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ прийнÑтну +\fIглибину\fP на оÑнові \fImf\fP Ñ– \fIпріоритетноÑті\fP. +.IP "" +ПрийнÑтним значеннÑм \fIглибини\fP Ð´Ð»Ñ Ð»Ð°Ð½Ñ†ÑŽÐ¶ÐºÑ–Ð² хешів Ñ” 4\(en100 Ñ– 16\(en1000 +Ð´Ð»Ñ Ð´Ð²Ñ–Ð¹ÐºÐ¾Ð²Ð¸Ñ… дерев. ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð´ÑƒÐ¶Ðµ виÑоких значень Ð´Ð»Ñ \fIглибини\fP може +зробити кодувальник дуже повільним Ð´Ð»Ñ Ð´ÐµÑких файлів. Ðе вÑтановлюйте +Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIглибини\fP, що перевищує 1000, Ñкщо ви не готові перервати +ÑтиÑканнÑ, Ñкщо воно триватиме надто довго. +.RE +.IP "" +При декодуванні необроблених потоків даних (\fB\-\-format=raw\fP), LZMA2 потребує +лише \fIрозміру\fP Ñловника. LZMA1 потребує також \fIlc\fP, \fIlp\fP Ñ– \fIpb\fP. +.TP +\fB\-\-x86\fP[\fB=\fP\fIпараметри\fP] +.PD 0 +.TP +\fB\-\-arm\fP[\fB=\fP\fIпараметри\fP] +.TP +\fB\-\-armthumb\fP[\fB=\fP\fIпараметри\fP] +.TP +\fB\-\-arm64\fP[\fB=\fP\fIпараметри\fP] +.TP +\fB\-\-powerpc\fP[\fB=\fP\fIпараметри\fP] +.TP +\fB\-\-ia64\fP[\fB=\fP\fIпараметри\fP] +.TP +\fB\-\-sparc\fP[\fB=\fP\fIпараметри\fP] +.TP +\fB\-\-riscv\fP[\fB=\fP\fIпараметри\fP] +.PD +Додати фільтр гілок/викликів/переходів (branch/call/jump або BCJ) до +ланцюжка фільтрів. Цими фільтрами можна ÑкориÑтатиÑÑ, лише Ñкщо вони не Ñ” +оÑтаннім фільтром у ланцюжку фільтрів. +.IP "" +Фільтр BCJ перетворює відноÑні адреÑи у машинному коді на їхні абÑолютні +відповідники. Це не змінює розміру даних, але підвищує резервуваннÑ, що може +допомогти LZMA2 Ñтворити файл \fB.xz\fP на 0\(en15\ % менше. Фільтри BCJ завжди +Ñ” придатними до оберненнÑ, тому викориÑÑ‚Ð°Ð½Ð½Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ð° BCJ до помилкового типу +даних не ÑпричинÑтиме втрати даних, хоча може дещо погіршити коефіцієнт +ÑтиÑканнÑ. Фільтри BCJ Ñ” дуже швидкими Ñ– такими, що викориÑтовують незначний +об'єм пам'Ñті. +.IP "" +Ці фільтри BCJ мають відомі проблеми, Ñкі пов'Ñзано із рівнем ÑтиÑканнÑ: +.RS +.IP \(bu 3 +У деÑких типах файлів, де зберігаєтьÑÑ Ð²Ð¸ÐºÐ¾Ð½ÑƒÐ²Ð°Ð½Ð¸Ð¹ код, (наприклад, в +об'єктних файлах, Ñтатичних бібліотеках та модулÑÑ… Ñдра Linux) адреÑи в +інÑтрукціÑÑ… заповнено значеннÑми заповнювача. Ці фільтри BCJ виконуватимуть +Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð°Ð´Ñ€ÐµÑ, Ñке зробить ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð»Ñ Ñ†Ð¸Ñ… файлів гіршим. +.IP \(bu 3 +Якщо фільтр BCJ заÑтоÑовано до архіву, може так ÑтатиÑÑ, що він погіршить +коефіцієнт ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¿Ð¾Ñ€Ñ–Ð²Ð½Ñно із варіантом без фільтра BCJ. Ðаприклад, Ñкщо +Ñ” подібні або навіть однакові виконувані файли, фільтруваннÑ, ймовірно, +зробить ці файли менш подібними, а отже, зробить ÑтиÑÐºÐ°Ð½Ð½Ñ Ð³Ñ–Ñ€ÑˆÐ¸Ð¼. ВміÑÑ‚ +файлів, Ñкі не Ñ” виконуваними, у тому Ñамому архіві також може вплинути на +результат. Ðа практиці, варто Ñпробувати варіанти з фільтром BCJ Ñ– без +нього, щоб визначитиÑÑ Ñ–Ð· тим, що буде кращим у кожній Ñитуації. +.RE +.IP "" +Різні набори інÑтрукцій мають різне вирівнюваннÑ: виконуваний файл має бути +вирівнÑно на кратне до цього Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ вхідних даних, щоб фільтр Ñпрацював. +.RS +.RS +.PP +.TS +tab(;); +l n l +l n l. +Фільтр;ВирівнюваннÑ;Ðотатки +x86;1;32\-бітова або 64\-бітова x86 +ARM;4; +ARM\-Thumb;2; +ARM64;4;Ðайкращим Ñ” Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ð·Ð° +;;4096 байтами +PowerPC;4;Лише зворотний порÑдок байтів +IA\-64;16;Itanium +SPARC;4; +RISC\-V;2; +.TE +.RE +.RE +.IP "" +ОÑкільки фільтровані BCJ дані, зазвичай, ÑтиÑкають за допомогою LZMA2, +коефіцієнт ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¼Ð¾Ð¶Ð½Ð° трохи поліпшити, Ñкщо параметри LZMA2 буде +вÑтановлено так, щоб вони відповідали вирівнюванню вибраного фільтра +BCJ. Приклади: +.RS +.IP \(bu 3 +Фільтр IA\-64 має 16\-байтове вирівнюваннÑ, отже \fBpb=4,lp=4,lc=0\fP даÑть добрі +результати у поєднанні із LZMA2 (2^4=16). +.IP \(bu 3 +Код RISC\-V має 2\-байтове або 4\-байтове Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾ від того, чи +міÑтить файл 16\-бітові ÑтиÑлі інÑтрукції (Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ C). Якщо викориÑтано +16\-бітові інÑтрукції, добрі результати даÑть \fBpb=2,lp=1,lc=3\fP або +\fBpb=1,lp=1,lc=3\fP. Якщо 16\-бітових інÑтрукцій немає, найкращим варіантом Ñ” +\fBpb=2,lp=2,lc=2\fP. Можна ÑкориÑтатиÑÑ \fBreadelf \-h\fP, щоб перевірити, чи Ñ” +"RVC" у Ñ€Ñдку "Flags". +.IP \(bu 3 +ARM64 завжди вирівнÑно на 4 байти, тому найкращим варіантом буде +\fBpb=2,lp=2,lc=2\fP. +.IP \(bu 3 +Фільтр x86 Ñ” виключеннÑм. Зазвичай, добрі результати дають типові Ð´Ð»Ñ LZMA2 +Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (\fBpb=2,lp=0,lc=3\fP), Ñкщо ÑтиÑкають виконувані файли x86. +.RE +.IP "" +У вÑÑ–Ñ… фільтрах BCJ передбачено підтримку тих Ñамих \fIпараметрів\fP: +.RS +.TP +\fBstart=\fP\fIзÑув\fP +Ð’Ñтановити початковий \fIзÑув\fP, Ñкий буде викориÑтано при перетворенні між +відноÑною та абÑолютною адреÑами. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIзÑув\fP має бути кратним до +Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ð° (див. таблицю вище). Типовим зÑувом Ñ” нульовий. Ðа +практиці, типове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ” прийнÑтним; Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½ÐµÑ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +\fIзÑув\fP майже завжди нічого кориÑного не дає. +.RE +.TP +\fB\-\-delta\fP[\fB=\fP\fIпараметри\fP] +Додати дельта\-фільтр до ланцюжка фільтрів. Дельта\-фільтр може бути +викориÑтано, лише Ñкщо він не Ñ” оÑтаннім у ланцюжку фільтрів. +.IP "" +У поточній верÑÑ–Ñ— передбачено підтримку обчиÑÐ»ÐµÐ½Ð½Ñ Ð»Ð¸ÑˆÐµ проÑтої побітової +дельти. Це може бути кориÑним при ÑтиÑканні, наприклад, неÑтиÑнутих +раÑтрових зображень або неÑтиÑнутих звукових даних PCM. Втім, Ñпеціалізовані +алгоритми можуть давати значно кращі результати за дельту + LZMA2. Це +правило оÑобливо ÑтоÑуєтьÑÑ Ð·Ð²ÑƒÐºÐ¾Ð²Ð¸Ñ… даних, Ñкі ÑтиÑкає швидше Ñ– краще, +наприклад, \fBflac\fP(1). +.IP "" +Підтримувані \fIпараметри\fP: +.RS +.TP +\fBdist=\fP\fIвідÑтань\fP +Вказати \fIвідÑтань\fP обчиÑлень різниці у байтах. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIвідÑтань\fP має +потраплÑти у діапазон 1\(en256. Типовим значеннÑм Ñ” 1. +.IP "" +Ðаприклад, з \fBdist=2\fP та воÑьмибайтовими вхідними даними A1 B1 A2 B3 A3 B5 +A4 B7, результатом буде A1 B1 01 02 01 02 01 02. +.RE +. +.SS "Інші параметри" +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Придушити Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° ÑповіщеннÑ. Вкажіть цей параметр двічі, щоб +придушити також Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилки. Цей параметр не впливає на Ñтан +виходу з програми. Тобто, навіть Ñкщо було придушено попередженнÑ, Ñтан +виходу вказуватиме на те, що Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¸. +.TP +\fB\-v\fP, \fB\-\-verbose\fP +Докладний режим повідомлень. Якщо Ñтандартне Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº з'єднано із +терміналом, \fBxz\fP показуватиме індикатор поÑтупу. ВикориÑÑ‚Ð°Ð½Ð½Ñ \fB\-\-verbose\fP +двічі призведе до ще докладнішого виведеннÑ. +.IP "" +Індикатор поÑтупу показує такі дані: +.RS +.IP \(bu 3 +ЧаÑтку завершеноÑті буде показано, Ñкщо відомий розмір файла вхідних +даних. Тобто, Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ñ–Ð² даних чаÑтку не може бути показано. +.IP \(bu 3 +Об'єм ÑтиÑнених виведених даних (ÑтиÑканнÑ) або оброблених (розпаковуваннÑ). +.IP \(bu 3 +Об'єм незапакованих даних (ÑтиÑканнÑ) або виведених даних (розпаковуваннÑ). +.IP \(bu 3 +Коефіцієнт ÑтиÑканнÑ, Ñкий обчиÑлено діленнÑм об'єму оброблених ÑтиÑнутих +даних на об'єм оброблених неÑтиÑнутих даних. +.IP \(bu 3 +ШвидкіÑть ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ розпаковуваннÑ. ОбчиÑлюєтьÑÑ Ñк об'єм неÑтиÑнутих +даних (ÑтиÑканнÑ) або виведених даних (розпаковуваннÑ) за Ñекунду. Його буде +показано за декілька Ñекунд з моменту, коли \fBxz\fP почала оброблÑти файл. +.IP \(bu 3 +Витрачений Ñ‡Ð°Ñ Ñƒ форматі Ð¥:СС або Г:ХХ:СС. +.IP \(bu 3 +Оцінку чаÑу, що лишивÑÑ, буде показано, лише Ñкщо розмір файла вхідних даних +Ñ” відомим, Ñ– минуло принаймні декілька Ñекунд з моменту, коли \fBxz\fP почала +оброблÑти файл. Ð§Ð°Ñ Ð±ÑƒÐ´Ðµ показано у менш точному форматі, без двокрапок, +наприклад, 2 хв. 30 Ñ. +.RE +.IP "" +Якщо Ñтандартним виведеннÑм помилок не Ñ” термінал, \fB\-\-verbose\fP призведе до +того, що \fBxz\fP виведе назву файла, ÑтиÑнений розмір, неÑтиÑнений розмір, +коефіцієнт ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚Ð°, можливо, також швидкіÑть та витрачений Ñ‡Ð°Ñ Ñƒ одному +Ñ€Ñдку до Ñтандартного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº піÑÐ»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ +файла. ШвидкіÑть та витрачений Ñ‡Ð°Ñ Ð±ÑƒÐ´Ðµ включено, лише Ñкщо Ð´Ñ–Ñ Ñ‚Ñ€Ð¸Ð²Ð°Ñ” +принаймні декілька Ñекунд. Якщо дію не буде завершено, наприклад, через +Ð²Ñ‚Ñ€ÑƒÑ‡Ð°Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача, буде також виведено чаÑтку виконаннÑ, Ñкщо відомий +розмір файла вхідних даних. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Ðе вÑтановлювати Ñтан виходу 2, навіть Ñкщо було виÑвлено відповідніÑть +умові, Ñка варта попередженнÑ. Цей параметр не впливає на рівень докладноÑті +повідомлень, отже, Ñлід викориÑтати \fB\-\-quiet\fP Ñ– \fB\-\-no\-warn\fP, щоб програма +не показувала попереджень Ñ– не змінювала Ñтан виходу. +.TP +\fB\-\-robot\fP +Виводити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñƒ придатному Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ комп'ютером форматі. Цей +формат призначено Ð´Ð»Ñ Ð¿Ð¾Ð»ÐµÐ³ÑˆÐµÐ½Ð½Ñ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ð½Ñ Ð¾Ð±Ð¾Ð»Ð¾Ð½Ð¾Ðº, Ñкі викориÑтовуватимуть +\fBxz\fP заміÑть liblzma, що може бути зручним Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¾Ð¼Ð°Ð½Ñ–Ñ‚Ð½Ð¸Ñ… +Ñкриптів. Виведені дані з цим параметром має бути Ñтабільним Ð´Ð»Ñ ÑƒÑÑ–Ñ… +випуÑків \fBxz\fP. Докладніший Ð¾Ð¿Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð° знайти у розділі \fBРЕЖИМ РОБОТÐ\fP. +.TP +\fB\-\-info\-memory\fP +ВивеÑти у придатному Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð»ÑŽÐ´Ð¸Ð½Ð¾ÑŽ форматі, Ñкільки фізичної пам'Ñті +(RAM) та Ñкільки потоків процеÑора Ñ” за даними \fBxz\fP у ÑиÑтемі, Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ +Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚Ð° розпаковуваннÑ, а потім уÑпішно завершити роботу. +.TP +\fB\-h\fP, \fB\-\-help\fP +ВивеÑти Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку з опиÑом найбільш типових викориÑтаних +параметрів Ñ– уÑпішно завершити роботу. +.TP +\fB\-H\fP, \fB\-\-long\-help\fP +ВивеÑти довідкове Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· опиÑом уÑÑ–Ñ… можливоÑтей \fBxz\fP Ñ– уÑпішно +завершити роботу +.TP +\fB\-V\fP, \fB\-\-version\fP +ВивеÑти номер верÑÑ–Ñ— \fBxz\fP та liblzma у зручному Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñ–. Щоб +отримати дані, зручні Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ на комп'ютері, вкажіть \fB\-\-robot\fP до +\fB\-\-version\fP. +. +.SH "РЕЖИМ РОБОТÐ" +Режим робота активують за допомогою параметра \fB\-\-robot\fP. Він Ñпрощує +обробку виведених \fBxz\fP даних іншими програмами. У поточній верÑÑ–Ñ— підтримку +\fB\-\-robot\fP передбачено лише разом із \fB\-\-list\fP, \fB\-\-filters\-help\fP, +\fB\-\-info\-memory\fP Ñ– \fB\-\-version\fP. У майбутньому підтримку параметра буде +передбачено Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚Ð° розпаковуваннÑ. +. +.SS "Режим ÑпиÑку" +У \fBxz \-\-robot \-\-list\fP викориÑтано табулÑції Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ–Ð»Ñƒ виведених +даних. Першим Ñтовпчиком у кожному Ñ€Ñдку Ñ” Ñ€Ñдок, що вказує на тип +відомоÑтей, Ñкі можна знайти у цьому Ñ€Ñдку: +.TP +.\" TRANSLATORS: The bold strings B, B, B, B, +.\" B, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +\fBname\fP +Це завжди перший Ñ€Ñдок на початку ÑпиÑку файла. Другим Ñтовпчиком у Ñ€Ñдку Ñ” +назва файла. +.TP +\fBfile\fP +У цьому Ñ€Ñдку міÑÑ‚ÑтьÑÑ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ñ– відомоÑті щодо файла \fB.xz\fP. Цей Ñ€Ñдок +завжди виводÑть піÑÐ»Ñ Ñ€Ñдка \fBname\fP. +.TP +\fBstream\fP +Цей тип Ñ€Ñдка викориÑтовують, лише Ñкщо було вказано \fB\-\-verbose\fP. Буде +Ñтільки Ñ€Ñдків \fBstream\fP, Ñкільки потоків у файлі \fB.xz\fP. +.TP +\fBblock\fP +Цей тип Ñ€Ñдка викориÑтовують, лише Ñкщо було вказано \fB\-\-verbose\fP. Буде +Ñтільки Ñ€Ñдків \fBblock\fP, Ñкільки блоків у файлі \fB.xz\fP. РÑдки \fBblock\fP буде +показано піÑÐ»Ñ ÑƒÑÑ–Ñ… Ñ€Ñдків \fBstream\fP; різні типи Ñ€Ñдків не перемежовуютьÑÑ. +.TP +\fBsummary\fP +Цей тип Ñ€Ñдків викориÑтовують, лише Ñкщо \fB\-\-verbose\fP було вказано +двічі. Цей Ñ€Ñдок буде виведено піÑÐ»Ñ ÑƒÑÑ–Ñ… Ñ€Ñдків \fBblock\fP. Подібно до Ñ€Ñдка +\fBfile\fP, Ñ€Ñдок \fBsummary\fP міÑтить загальні відомоÑті щодо файла \fB.xz\fP. +.TP +\fBtotals\fP +Цей Ñ€Ñдок завжди Ñ” найоÑтаннішим Ñ€Ñдком у виведеному ÑпиÑку. У ньому буде +показано загальні кількоÑті та розміри. +.PP +Стовпчики у Ñ€Ñдках \fBфайла\fP: +.PD 0 +.RS +.IP 2. 4 +КількіÑть потоків у файлі +.IP 3. 4 +Загальна кількіÑть блоків у потоках +.IP 4. 4 +Розмір ÑтиÑненого файла +.IP 5. 4 +Розмір неÑтиÑненого файла +.IP 6. 4 +Коефіцієнт ÑтиÑканнÑ, наприклад, \fB0.123\fP. Якщо коефіцієнт перевищує 9.999, +заміÑть коефіцієнта буде показано дефіÑи (\fB\-\-\-\fP). +.IP 7. 4 +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +СпиÑок відокремлених комами назв перевірок ціліÑноÑті. Ðаведені нижче Ñ€Ñдки +викориÑтовують Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð¼Ð¸Ñ… типів перевірок: \fBNone\fP, \fBCRC32\fP, \fBCRC64\fP Ñ– +\fBSHA\-256\fP. Ð”Ð»Ñ Ð½ÐµÐ²Ñ–Ð´Ð¾Ð¼Ð¸Ñ… типів перевірок буде викориÑтано \fBUnknown\-\fP\fIN\fP, +де \fIN\fP Ñ” ідентифікатором перевірки у форматі деÑÑткового чиÑла (одна або +дві цифри). +.IP 8. 4 +Загальний розмір Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ у файлі +.RE +.PD +.PP +Стовпчики у Ñ€Ñдках \fBstream\fP: +.PD 0 +.RS +.IP 2. 4 +Ðомер потоку (перший потік має номер 1) +.IP 3. 4 +КількіÑть блоків у потоці +.IP 4. 4 +ЗÑув початку ÑтиÑненого +.IP 5. 4 +ЗÑув початку неÑтиÑненого +.IP 6. 4 +СтиÑнений розмір (не включає Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ) +.IP 7. 4 +ÐеÑтиÑнутий розмір +.IP 8. 4 +Рівень ÑтиÑÐºÐ°Ð½Ð½Ñ +.IP 9. 4 +Ðазва перевірки ціліÑноÑті +.IP 10. 4 +Розмір Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ +.RE +.PD +.PP +Стовпчики у Ñ€Ñдках \fBblock\fP: +.PD 0 +.RS +.IP 2. 4 +Ðомер потоку, що міÑтить цей блок +.IP 3. 4 +Ðомер блоку відноÑно початку потоку (перший блок має номер 1) +.IP 4. 4 +Ðомер блоку відноÑно початку файла +.IP 5. 4 +ЗÑув початку ÑтиÑненого відноÑно початку файла +.IP 6. 4 +ЗÑув початку неÑтиÑненого відноÑно початку файла +.IP 7. 4 +Загальний ÑтиÑнений розмір блоку (включено з заголовками) +.IP 8. 4 +ÐеÑтиÑнутий розмір +.IP 9. 4 +Рівень ÑтиÑÐºÐ°Ð½Ð½Ñ +.IP 10. 4 +Ðазва перевірки ціліÑноÑті +.RE +.PD +.PP +Якщо \fB\-\-verbose\fP було вказано двічі, до Ñ€Ñдків \fBblock\fP буде включено +додаткові Ñтовпчики. Ці Ñтовпчики не буде показано, Ñкщо вказано одинарний +параметр \fB\-\-verbose\fP, оÑкільки Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ†Ð¸Ñ… відомоÑтей потребує багатьох +позиціювань, а Ñ†Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° може бути повільною: +.PD 0 +.RS +.IP 11. 4 +Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ ціліÑноÑті у шіÑтнадцÑтковій формі +.IP 12. 4 +Розмір заголовка блоку +.IP 13. 4 +Прапорці блоку: \fBc\fP вказує, що наÑвний ÑтиÑнений розмір, а \fBu\fP вказує, що +наÑвний неÑтиÑнений розмір. Якщо прапорець не вÑтановлено, буде показано +(\fB\-\fP) заміÑть Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ„Ñ–ÐºÑованого розміру Ñ€Ñдка. У майбутньому +наприкінці Ñ€Ñдка може бути додано нові прапорці. +.IP 14. 4 +Розмір Ñправжніх ÑтиÑнених даних у блоці (це включає заголовок блоку, +Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð±Ð»Ð¾ÐºÑƒ та Ð¿Ð¾Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€Ð¾Ðº) +.IP 15. 4 +Об'єм пам'Ñті (у байтах), Ñкий потрібен Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ блоку за +допомогою цієї верÑÑ–Ñ— \fBxz\fP +.IP 16. 4 +Ланцюжок фільтрів. Зауважте, що більшіÑть параметрів, Ñкі викориÑтано під +Ñ‡Ð°Ñ ÑтиÑканнÑ, не Ñ” наперед відомим, оÑкільки у заголовках \fB.xz\fP +зберігаютьÑÑ Ð»Ð¸ÑˆÐµ параметри, Ñкі потрібні Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ. +.RE +.PD +.PP +Стовпчики у Ñ€Ñдках \fBsummary\fP: +.PD 0 +.RS +.IP 2. 4 +Об'єм пам'Ñті (у байтах), Ñкий потрібен Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файла за +допомогою цієї верÑÑ–Ñ— \fBxz\fP +.IP 3. 4 +\fByes\fP або \fBno\fP вказує, Ñкщо уÑÑ– заголовки блоків міÑÑ‚Ñть одразу ÑтиÑнений +розмір та розпакований розмір +.PP +\fIПочинаючи з\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 4. 4 +Мінімальна верÑÑ–Ñ \fBxz\fP, Ñка потрібна Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° +.RE +.PD +.PP +Стовпчики Ñ€Ñдка \fBtotals\fP: +.PD 0 +.RS +.IP 2. 4 +КількіÑть потоків +.IP 3. 4 +КількіÑть блоків +.IP 4. 4 +СтиÑнутий розмір +.IP 5. 4 +ÐеÑтиÑнутий розмір +.IP 6. 4 +Середній коефіцієнт ÑтиÑÐºÐ°Ð½Ð½Ñ +.IP 7. 4 +СпиÑок відокремлених комами назв перевірок ціліÑноÑті, результати Ñких +наÑвні у файлах +.IP 8. 4 +Розмір Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ +.IP 9. 4 +КількіÑть файлів. ÐаÑвний тут Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ñ‚Ð°ÐºÐ¾Ð³Ð¾ Ñамого порÑдку +Ñтовпчиків, що Ñ– у попередніх Ñ€Ñдках \fBfile\fP. +.PD +.RE +.PP +Якщо \fB\-\-verbose\fP було вказано двічі, до Ñ€Ñдка \fBtotals\fP буде включено +додаткові Ñтовпчики: +.PD 0 +.RS +.IP 10. 4 +МакÑимальний об'єм пам'Ñті (у байтах), Ñкий потрібен Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ +файлів за допомогою цієї верÑÑ–Ñ— \fBxz\fP +.IP 11. 4 +\fByes\fP або \fBno\fP вказує, Ñкщо уÑÑ– заголовки блоків міÑÑ‚Ñть одразу ÑтиÑнений +розмір та розпакований розмір +.PP +\fIПочинаючи з\fP \fBxz\fP \fI5.1.2alpha:\fP +.IP 12. 4 +Мінімальна верÑÑ–Ñ \fBxz\fP, Ñка потрібна Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° +.RE +.PD +.PP +У майбутніх верÑÑ–ÑÑ… може бути додано нові типи Ñ€Ñдків Ñ– нові Ñтовпчики до +наÑвних типів Ñ€Ñдків, але наÑвні Ñтовпчики мають лишитиÑÑ Ð½ÐµÐ·Ð¼Ñ–Ð½Ð½Ð¸Ð¼Ð¸. +. +.SS "Довідка з фільтруваннÑ" +\fBxz \-\-robot \-\-filters\-help\fP виведе ÑпиÑок підтримуваних фільтрів у такому +форматі: +.PP +\fIфільтр\fP\fB:\fP\fIпараметр\fP\fB=<\fP\fIзначеннÑ\fP\fB>,\fP\fIпараметр\fP\fB=<\fP\fIзначеннÑ\fP\fB>\fP... +.TP +\fIфільтр\fP +Ðазва фільтра +.TP +\fIпараметр\fP +Ðазва Ñпецифічного Ð´Ð»Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ð° параметра +.TP +\fIзначеннÑ\fP +ЧиÑлові діапазони \fIvalue\fP Ñлід вказати у форматі +\fB<\fP\fIмінімум\fP\fB\-\fP\fIмакÑимум\fP\fB>\fP. Варіанти Ñ€Ñдка \fIзначеннÑ\fP +показано у \fB< >\fP Ñ– відокремлено Ñимволом \fB|\fP. +.PP +Кожен фільтр буде виведено до окремого Ñ€Ñдка. +. +.SS "Дані щодо Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð°Ð¼'Ñті" +\fBxz \-\-robot \-\-info\-memory\fP виводить один Ñ€Ñдок з декількома відокремленими +табулÑціÑми Ñтовпчиками: +.IP 1. 4 +Загальний об'єм фізичної пам'Ñті (RAM) у байтах. +.IP 2. 4 +ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ñƒ байтах +(\fB\-\-memlimit\-compress\fP). ОÑобливе Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB0\fP вказує на типові +налаштуваннÑ, Ñкими Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð³Ð¾ режиму Ñ” Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÐµÐ· Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ +на викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті. +.IP 3. 4 +ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ байтах +(\fB\-\-memlimit\-decompress\fP). ОÑобливе Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fB0\fP вказує на типові +налаштуваннÑ, Ñкими Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð³Ð¾ режиму Ñ” Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÐµÐ· Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ +на викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті. +.IP 4. 4 +Починаючи з \fBxz\fP 5.3.4alpha: викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð³Ð¾ +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ байтах (\fB\-\-memlimit\-mt\-decompress\fP). Ðіколи не дорівнює +нулеві, оÑкільки буде викориÑтано Ñпецифічне Ð´Ð»Ñ ÑиÑтеми типове значеннÑ, +Ñке показано у Ñтовпчику 5, Ñкщо Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ðµ вÑтановлено Ñвним чином. Також +ніколи не перевищуватиме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ Ñтовпчику 3, навіть Ñкщо було вказано +більше Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° допомогою \fB\-\-memlimit\-mt\-decompress\fP. +.IP 5. 4 +Починаючи з \fBxz\fP 5.3.4alpha: Ñпецифічне Ð´Ð»Ñ ÑиÑтеми типове Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° +викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті, Ñке викориÑтовують Ð´Ð»Ñ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾Ñті потоків при +ÑтиÑканні з автоматичною кількіÑтю потоків (\fB\-\-threads=0\fP) Ñ– без Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті (\fB\-\-memlimit\-compress\fP). Це Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +також викориÑтовують Ñк типове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ \fB\-\-memlimit\-mt\-decompress\fP. +.IP 6. 4 +Починаючи з \fBxz\fP 5.3.4alpha: кількіÑть доÑтупних потоків обробки процеÑора. +.PP +У майбутньому у виведенні \fBxz \-\-robot \-\-info\-memory\fP може бути більше +Ñтовпчиків, але у виведеному буде не більше за один Ñ€Ñдок. +. +.SS ВерÑÑ–Ñ +\fBxz \-\-robot \-\-version\fP виведе назву верÑÑ–Ñ— \fBxz\fP Ñ– liblzma у такому +форматі: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +\fBXZ_VERSION=\fP\fIXYYYZZZS\fP +.br +\fBLIBLZMA_VERSION=\fP\fIXYYYZZZS\fP +.TP +\fIX\fP +ОÑновна верÑÑ–Ñ. +.TP +\fIYYY\fP +Проміжна верÑÑ–Ñ. Ðепарні номери буде викориÑтано Ð´Ð»Ñ Ñтабільних +верÑій. Ðепарні номери Ñ” номерами теÑтових верÑій. +.TP +\fIZZZ\fP +Рівень Ð»Ð°Ñ‚Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñтабільних випуÑків або проÑто лічильник Ð´Ð»Ñ Ð²Ð¸Ð¿ÑƒÑків, +Ñкі перебувають у розробці. +.TP +\fIS\fP +СтабільніÑть. 0 — alpha, 1 — beta, а 2 означає «Ñтабільна верÑÑ–Ñ». \fIS\fP має +завжди дорівнювати 2, Ñкщо \fIYYY\fP Ñ” парним. +.PP +\fIXYYYZZZS\fP Ñ” тим Ñамим в обох Ñ€Ñдках, Ñкщо \fBxz\fP Ñ– liblzma належать до +одного випуÑку XZ Utils. +.PP +Приклади: 4.999.9beta — це \fB49990091\fP, а 5.0.0 — це \fB50000002\fP. +. +.SH "СТÐРВИХОДУ" +.TP +\fB0\fP +УÑе добре. +.TP +\fB1\fP +СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. +.TP +\fB2\fP +СталоÑÑ Ñ‰Ð¾ÑÑŒ варте попередженнÑ, але Ñправжніх помилок не ÑталоÑÑ. +.PP +Ð—Ð°ÑƒÐ²Ð°Ð¶ÐµÐ½Ð½Ñ (не Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ помилки), Ñкі виведено до Ñтандартного +Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº, не впливають на Ñтан виходу. +. +.SH СЕРЕДОВИЩЕ +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +\fBxz\fP оброблÑÑ” ÑпиÑки відокремлених пробілами параметрів зі змінних +Ñередовища \fBXZ_DEFAULTS\fP Ñ– \fBXZ_OPT\fP, перш ніж оброблÑти параметри з Ñ€Ñдка +команди. Зауважте, що буде оброблено лише параметри зі змінних Ñередовища; +уÑÑ– непараметричні запиÑи буде без повідомлень проігноровано. Обробку буде +виконано за допомогою функції \fBgetopt_long\fP(3), Ñку також викориÑтовують +Ð´Ð»Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñ–Ð² Ñ€Ñдка команди. +.PP +\fBПопередженнÑ:\fP Ð’Ñтановлюючи ці змінні Ñередовища, ви наÑправді змінюєте +програми та Ñкрипти, Ñкі виконують \fBxz\fP. У більшоÑті випадків без проблем +можна вÑтановлювати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті, кількіÑть потоків Ñ– +параметри ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð·Ð° допомогою змінних Ñередовища. Однак деÑкі параметри +можуть порушити роботу Ñкриптів. Очевидним прикладом Ñ” \fB\-\-help\fP, Ñкий +змушує \fBxz\fP показувати текÑÑ‚ довідки заміÑть ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ +файла. Менш очевидними Ñ” приклади \fB\-\-quiet\fP Ñ– \fB\-\-verbose\fP. У багатьох +випадках уÑе працюватиме добре, Ñкщо увімкнути індикатор поÑтупу за +допомогою \fB\-\-verbose\fP, але у деÑких ÑитуаціÑÑ… додаткові Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ +Ñтворюють проблеми. Рівень докладноÑті також впливає на поведінку \fB\-\-list\fP. +.TP +\fBXZ_DEFAULTS\fP +Специфічні Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача або загальноÑиÑтемні типові параметри. Зазвичай, +Ñ—Ñ… вÑтановлюють у Ñкрипті ініціалізації оболонки Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð³Ð¾ Ð²Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ +Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті у \fBxz\fP або вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ñ— кількоÑті +потоків обробки. Окрім Ñкриптів ініціалізації оболонки Ñ– подібних оÑобливих +випадків, не Ñлід вÑтановлювати або ÑкаÑовувати вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ +\fBXZ_DEFAULTS\fP у Ñкриптах. +.TP +\fBXZ_OPT\fP +Цю змінну призначено Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð² до \fBxz\fP, Ñкщо неможливо +вÑтановити параметри безпоÑередньо у Ñ€Ñдку команди \fBxz\fP. Це траплÑєтьÑÑ, +Ñкщо \fBxz\fP запущено Ñкриптом або інÑтрументом, наприклад, GNU \fBtar\fP(1): +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=\-2v tar caf foo.tar.xz foo\fR +.fi +.RE +.RE +.IP "" +Скрипти можуть викориÑтовувати \fBXZ_OPT\fP, наприклад, Ð´Ð»Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ +Ñпецифічних типових параметрів ÑтиÑканнÑ. Втім, рекомендуємо дозволити +кориÑтувачам перевизначати \fBXZ_OPT\fP, Ñкщо це має ÑкіÑÑŒ причини. Ðаприклад, +у Ñкриптах \fBsh\fP(1) можна ÑкориÑтатиÑÑ Ñ‡Ð¸Ð¼Ð¾ÑÑŒ таким: +.RS +.RS +.PP +.nf +\f(CRXZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT\fR +.fi +.RE +.RE +. +.SH "СУМІСÐІСТЬ ІЗ LZMA UTILS" +СинтакÑÐ¸Ñ Ñ€Ñдка команди \fBxz\fP практично Ñ” надбудовою щодо \fBlzma\fP, \fBunlzma\fP +Ñ– \fBlzcat\fP з LZMA Utils 4.32.x. У більшоÑті випадків можна замінити LZMA +Utils XZ Utils без Ð¿Ð¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ñ†ÐµÐ·Ð´Ð°Ñ‚Ð½Ð¾Ñті наÑвних Ñкриптів. Втім, Ñ–Ñнують +певні неÑуміÑноÑті, Ñкі іноді можуть ÑпричинÑти проблеми. +. +.SS "Рівні шаблонів ÑтиÑканнÑ" +ÐÑƒÐ¼ÐµÑ€Ð°Ñ†Ñ–Ñ Ñƒ шаблонах рівнів ÑтиÑÐºÐ°Ð½Ð½Ñ Ñƒ \fBxz\fP не Ñ” тотожною до нумерації у +LZMA Utils. Ðайважливішою відмінніÑтю Ñ” прив'Ñзка розмірів Ñловника до +різних шаблонів. Розмір Ñловника грубо рівний викориÑтанню пам'Ñті у заÑобі +розпаковуваннÑ. +.RS +.PP +.TS +tab(;); +c c c +c n n. +Рівень;xz;LZMA Utils +\-0;256 КіБ;н/д +\-1;1 МіБ;64 КіБ +\-2;2 МіБ;1 МіБ +\-3;4 МіБ;512 КіБ +\-4;4 МіБ;1 МіБ +\-5;8 МіБ;2 МіБ +\-6;8 МіБ;4 МіБ +\-7;16 МіБ;8 МіБ +\-8;32 МіБ;16 МіБ +\-9;64 МіБ;32 МіБ +.TE +.RE +.PP +ВідмінноÑті у розмірах Ñловників також впливають на викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті +заÑобом ÑтиÑканнÑ, але Ñ” Ñ– інші відмінноÑті між LZMA Utils Ñ– XZ Utils, Ñкі +роблÑть різницю ще помітнішою: +.RS +.PP +.TS +tab(;); +c c c +c n n. +Рівень;xz;LZMA Utils 4.32.x +\-0;3 МіБ;н/д +\-1;9 МіБ;2 МіБ +\-2;17 МіБ;12 МіБ +\-3;32 МіБ;12 МіБ +\-4;48 МіБ;16 МіБ +\-5;94 МіБ;26 МіБ +\-6;94 МіБ;45 МіБ +\-7;186 МіБ;83 МіБ +\-8;370 МіБ;159 МіБ +\-9;674 МіБ;311 МіБ +.TE +.RE +.PP +Типовим рівнем ÑтиÑÐºÐ°Ð½Ð½Ñ Ñƒ LZMA Utils Ñ” \fB\-7\fP, а у XZ Utils — \fB\-6\fP, отже, +обидва комплекти програм типово викориÑтовують Ñловник розміром у 8 МіБ. +. +.SS "Потокові Ñ– непотокові файл .lzma" +Розмір неÑтиÑненого файла може бути збережено у заголовку \fB.lzma\fP. LZMA +Utils зберігають дані при ÑтиÑканні звичайних файлів. Ðльтернативним +підходом Ñ” Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½ÐµÑтиÑненого розміру Ñк невідомого Ñ– викориÑÑ‚Ð°Ð½Ð½Ñ +позначки ÐºÑ–Ð½Ñ†Ñ Ð²Ð¼Ñ–Ñту Ð´Ð»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¼Ñ–ÑцÑ, де заÑіб Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ñ” +зупинитиÑÑ. У LZMA Utils цей ÑпоÑіб викориÑтовують, Ñкщо неÑтиÑнений розмір +Ñ” невідомим, що траплÑєтьÑÑ, наприклад, Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð² обробки даних. +.PP +У \fBxz\fP передбачено підтримку Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² \fB.lzma\fP з позначкою +ÐºÑ–Ð½Ñ†Ñ Ð²Ð¼Ñ–Ñту та без неї, але уÑÑ– файли \fB.lzma\fP, Ñкі Ñтворено за допомогою +\fBxz\fP, викориÑтовують позначку ÐºÑ–Ð½Ñ†Ñ Ð²Ð¼Ñ–Ñту, а неÑтиÑнений розмір у +заголовку \fB.lzma\fP позначають Ñк невідомий. Це може призвеÑти до проблем у +деÑких нетипових ÑитуаціÑÑ…. Ðаприклад, розпакувальник \fB.lzma\fP у вбудованому +приÑтрої може працювати лише з файлами, Ð´Ð»Ñ Ñких відомий неÑтиÑнений +розмір. Якщо ви зіткнулиÑÑ Ð· цією проблемою, вам Ñлід ÑкориÑтатиÑÑ LZMA +Utils або LZMA SDK Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² \fB.lzma\fP із відомим розміром +неÑтиÑнених даних. +. +.SS "Ðепідтримувані файли .lzma" +У форматі \fB.lzma\fP можливі Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIlc\fP аж до 8 Ñ– Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fIlp\fP аж до +4. LZMA Utils можуть розпаковувати файли із будь\-Ñкими значеннÑми \fIlc\fP Ñ– +\fIlp\fP, але завжди Ñтворюють файли з \fBlc=3\fP Ñ– \fBlp=0\fP. Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² з +іншими значеннÑми \fIlc\fP Ñ– \fIlp\fP Ñ” можливим за допомогою \fBxz\fP Ñ– LZMA SDK. +.PP +Ð ÐµÐ°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ð° LZMA1 у liblzma потребує, щоби Ñума \fIlc\fP Ñ– \fIlp\fP не +перевищувала 4. Отже, файли \fB.lzma\fP, у Ñких перевищено обмеженнÑ, не може +бути розпаковано за допомогою \fBxz\fP. +.PP +LZMA Utils Ñтворюють лише файли \fB.lzma\fP, Ñкі мають розмір Ñловника у 2^\fIn\fP +(Ñтепінь 2), але приймають файли із будь\-Ñким розміром Ñловника. liblzma +приймає лише файли \fB.lzma\fP, Ñкі мають розмір Ñловника 2^\fIn\fP або 2^\fIn\fP + +2^(\fIn\fP\-1). Так зроблено Ð´Ð»Ñ Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº при виÑвленні файлів +\&\fB.lzma\fP. +.PP +Ці Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ðµ мають призводити до проблем на практиці, оÑкільки практично +уÑÑ– файли \fB.lzma\fP було ÑтиÑнено з викориÑтаннÑм параметрів, Ñкі приймає +liblzma. +. +.SS "Кінцевий мотлох" +При розпаковуванні LZMA Utils без повідомлень ігнорують уÑÑ– дані піÑÐ»Ñ +першого потоку \fB.lzma\fP. У більшоÑті випадків це пов'Ñзано із вадою у +програмі. Це також означає, що у LZMA Utils не передбачено підтримки +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð·'єднаних файлів \fB.lzma\fP. +.PP +Якщо піÑÐ»Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ потоку \fB.lzma\fP лишилиÑÑ Ð´Ð°Ð½Ñ–, \fBxz\fP вважатиме файл +пошкодженим, Ñкщо не було викориÑтано \fB\-\-single\-stream\fP. Це може зашкодити +роботі Ñкриптів, де зроблено припущеннÑ, що кінцеві зайві дані буде +проігноровано. +. +.SH ПРИМІТКИ +. +.SS "СтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… може бути різним" +Точні ÑтиÑнені дані, Ñкі Ñтворено на оÑнові того Ñамого неÑтиÑненого файла +вхідних даних, можуть бути різними Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¸Ñ… верÑій XZ Utils, навіть Ñкщо +викориÑтано однакові параметри ÑтиÑканнÑ. Причиною цього Ñ” удоÑÐºÐ¾Ð½Ð°Ð»ÐµÐ½Ð½Ñ Ñƒ +кодувальнику (Ð¿Ñ€Ð¸ÑˆÐ²Ð¸Ð´ÑˆÐµÐ½Ð½Ñ Ð°Ð±Ð¾ краще ÑтиÑканнÑ) без зміни формату +файлів. Виведені дані можуть бути різними навіть Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¸Ñ… збірок тієї +Ñамої верÑÑ–Ñ— XZ Utils, Ñкщо викориÑтано різні параметри збираннÑ. +.PP +ÐапиÑане вище означає, що піÑÐ»Ñ Ñ€ÐµÐ°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ— \fB\-\-rsyncable\fP файли\-результати +не обов'Ñзково можна буде Ñинхронізувати за допомогою rsyncable, Ñкщо Ñтарий +Ñ– новий файли було ÑтиÑнено за допомогою тієї Ñамої верÑÑ–Ñ— xz. Цю проблему +можна уÑунути, Ñкщо буде заморожено чаÑтину реалізації кодувальника, щоб +введені Ð´Ð»Ñ rsync дані були Ñтабільними між верÑÑ–Ñми xz. +. +.SS "Вбудовані розпакувальники .xz" +У вбудованих реалізаціÑÑ… розпакувальника \fB.xz\fP, подібних до XZ Embedded, не +обов'Ñзково передбачено підтримку файлів, Ñкі Ñтворено із типами +\fIперевірки\fP ціліÑноÑті, відмінними від \fBnone\fP Ñ– \fBcrc32\fP. ОÑкільки типовим +Ñ” \fB\-\-check=crc64\fP, вам Ñлід викориÑтовувати \fB\-\-check=none\fP або +\fB\-\-check=crc32\fP при Ñтворенні файлів Ð´Ð»Ñ Ð²Ð±ÑƒÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ… ÑиÑтем. +.PP +Поза вбудованими ÑиÑтемами, в уÑÑ–Ñ… заÑобах Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñƒ \fB.xz\fP +передбачено підтримку уÑÑ–Ñ… типів \fIперевірок\fP або принаймні можливіÑть +розпакувати файл без перевірки ціліÑноÑті, Ñкщо підтримки певної +\fIперевірки\fP не передбачено. +.PP +У XZ Embedded передбачено підтримку BCJ, але лише з типовим початковим +зÑувом. +. +.SH ПРИКЛÐДИ +. +.SS ОÑнови +СтиÑнути файл \fIfoo\fP до \fIfoo.xz\fP за допомогою типового Ñ€Ñ–Ð²Ð½Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ +(\fB\-6\fP) Ñ– вилучити \fIfoo\fP, Ñкщо ÑтиÑÐºÐ°Ð½Ð½Ñ Ð²Ñ–Ð´Ð±ÑƒÐ»Ð¾ÑÑ ÑƒÑпішно: +.RS +.PP +.nf +\f(CRxz foo\fR +.fi +.RE +.PP +Розпакувати \fIbar.xz\fP до \fIbar\fP Ñ– не вилучати \fIbar.xz\fP, навіть Ñкщо +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð±ÑƒÐ»Ð¾ÑÑ ÑƒÑпішно: +.RS +.PP +.nf +\f(CRxz \-dk bar.xz\fR +.fi +.RE +.PP +Створити \fIbaz.tar.xz\fP з викориÑтаннÑм шаблона \fB\-4e\fP (\fB\-4 \-\-extreme\fP), +Ñкий Ñ” повільнішими за типовий \fB\-6\fP, але потребує менше пам'Ñті Ð´Ð»Ñ +ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚Ð° Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ (48\ МіБ та 5\ МіБ, відповідно): +.RS +.PP +.nf +\f(CRtar cf \- baz | xz \-4e > baz.tar.xz\fR +.fi +.RE +.PP +Суміш ÑтиÑнених Ñ– неÑтиÑнених файлів можна розпакувати до Ñтандартного +Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð·Ð° допомогою єдиної команди: +.RS +.PP +.nf +\f(CRxz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt\fR +.fi +.RE +. +.SS "Паралельне ÑтиÑÐºÐ°Ð½Ð½Ñ Ð±Ð°Ð³Ð°Ñ‚ÑŒÐ¾Ñ… файлів" +У GNU Ñ– *BSD можна ÑкориÑтатиÑÑ \fBfind\fP(1) Ñ– \fBxargs\fP(1) Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð»ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ +ÑтиÑÐºÐ°Ð½Ð½Ñ Ð±Ð°Ð³Ð°Ñ‚ÑŒÐ¾Ñ… файлів: +.RS +.PP +.nf +\f(CRfind . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1\fR +.fi +.RE +.PP +Параметр \fB\-P\fP \fBxargs\fP(1) вÑтановлює кількіÑть паралельних процеÑів +\fBxz\fP. Ðайкраще Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \fB\-n\fP залежить від того, Ñкільки файлів +має бути ÑтиÑнено. Якщо файлів мало, значеннÑм, ймовірно, має бути 1. Якщо +файлів деÑÑтки тиÑÑч, може знадобитиÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ 100 або навіть більше, щоб +зменшити кількіÑть процеÑів \fBxz\fP, Ñкі врешті Ñтворить \fBxargs\fP(1). +.PP +Параметр \fB\-T1\fP Ð´Ð»Ñ \fBxz\fP тут Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÑƒÑового вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð´Ð½Ð¾Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð³Ð¾ +режиму, оÑкільки Ð´Ð»Ñ ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ñ–Ð²Ð½ÐµÐ¼ паралелізації викориÑтано \fBxargs\fP(1). +. +.SS "Режим робота" +ОбчиÑлити Ñкільки байтів було заощаджено загалом піÑÐ»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´ÐµÐºÑ–Ð»ÑŒÐºÐ¾Ñ… +файлів: +.RS +.PP +.nf +\f(CRxz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}'\fR +.fi +.RE +.PP +Скрипту можуть знадобитиÑÑ Ð´Ð°Ð½Ñ– щодо того, що викориÑтано доÑтатньо нову +верÑÑ–ÑŽ \fBxz\fP. У наведеному нижче Ñкрипті \fBsh\fP(1) виконано перевірку того, +що номер верÑÑ–Ñ— заÑобу \fBxz\fP Ñ” принаймні рівним 5.0.0. Цей ÑпоÑіб Ñ” ÑуміÑним +зі Ñтарими теÑтовими верÑÑ–Ñми, де не передбачено підтримки параметра +\fB\-\-robot\fP: +.RS +.PP +.nf +\f(CRif ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Your xz is too old." +fi +unset XZ_VERSION LIBLZMA_VERSION\fR +.fi +.RE +.PP +Ð’Ñтановити Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° допомогою +\fBXZ_OPT\fP, але Ñкщо Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¶Ðµ було вÑтановлено, не збільшувати його: +.RS +.PP +.nf +\f(CRNEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi\fR +.fi +.RE +. +.SS "Ðетипові ланцюжки фільтрів заÑобу ÑтиÑканнÑ" +ÐайпроÑтішим викориÑтаннÑм ланцюжка фільтрів Ñ” Ð½Ð°Ð»Ð°ÑˆÑ‚Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð° +LZMA2. Це може бути кориÑним, оÑкільки у шаблонах викориÑтано лише +підмножину потенційно кориÑних комбінацій параметрів ÑтиÑканнÑ. +.PP +При налаштовуванні шаблонів LZMA2 кориÑними Ñ” Ñтовпчики CompCPU таблиць з +опиÑів параметрів \fB\-0\fP ... \fB\-9\fP Ñ– \fB\-\-extreme\fP. ОÑÑŒ відповідні чаÑтини з +цих двох таблиць: +.RS +.PP +.TS +tab(;); +c c +n n. +Шаблон;CompCPU +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +Якщо вам відомо, що певний файл потребує дещо більшого Ñловника (наприклад, +32\ МіБ) Ð´Ð»Ñ ÑкіÑного ÑтиÑканнÑ, але ви хочете ÑтиÑнути його швидше за +команду \fBxz \-8\fP, можна внеÑти зміни до шаблона із нижчим значеннÑм CompCPU +(наприклад, 1) Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð±Ñ–Ð»ÑŒÑˆÐ¾Ð³Ð¾ Ñловника: +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=1,dict=32MiB foo.tar\fR +.fi +.RE +.PP +Ð”Ð»Ñ Ð¿ÐµÐ²Ð½Ð¸Ñ… файлів наведена вище команда може працювати швидше за \fBxz \-6\fP Ñ– +ÑтиÑкати дані значно краще. Втім, Ñлід наголоÑити, переваги більшого +Ñловника з одночаÑним низьким значеннÑм CompCPU проÑвлÑютьÑÑ Ð»Ð¸ÑˆÐµ Ð´Ð»Ñ Ð´ÐµÑких +файлів. Ðайочевиднішим випадком, коли великий Ñловник Ñ” кориÑним, Ñ” випадок, +коли архів міÑтить дуже подібні файли розміром у принаймні декілька +мегабайтів. Розмір Ñловника має бути значно більшим за будь\-Ñкий окремий +файл, щоб у LZMA2 було викориÑтано уÑÑ– переваги подібноÑтей між поÑлідовними +файлами. +.PP +Якщо дуже виÑокий рівень викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті у заÑобі ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ Ñ” проблемою, Ñ– файли, Ñкий ÑтиÑкають має об'єм у принаймні +декілька деÑÑтків мегабайтів, може бути кориÑним викориÑÑ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð²Ñ–Ñ‚ÑŒ +більшого за 64 МіБ Ñловника, Ñкий викориÑтано у \fBxz \-9\fP: +.RS +.PP +.nf +\f(CRxz \-vv \-\-lzma2=dict=192MiB big_foo.tar\fR +.fi +.RE +.PP +ВикориÑÑ‚Ð°Ð½Ð½Ñ \fB\-vv\fP (\fB\-\-verbose \-\-verbose\fP), подібно до наведеного вище +прикладу, може бути кориÑним Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду вимог з боку заÑобів ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚Ð° +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ пам'Ñті. Пам'Ñтайте, що викориÑÑ‚Ð°Ð½Ð½Ñ Ñловника, розмір +Ñкого перевищує розмір файла, Ñкий ÑтиÑкають, Ñ” проÑтоюю витратою пам'Ñті, +отже наведену вище команду не варто викориÑтовувати Ð´Ð»Ñ Ð¼Ð°Ð»Ð¸Ñ… файлів. +.PP +Іноді Ñ‡Ð°Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð½Ðµ має значеннÑ, але викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті заÑобом +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ñ” бути низьким Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб, наприклад, уможливити +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° у вбудованій ÑиÑтемі. У наведеній нижче команді +викориÑтано \fB\-6e\fP (\fB\-6 \-\-extreme\fP) Ñк оÑнову Ñ– вÑтановлено розмір Ñловника +лише у 64\ КіБ. Файл\-результат можна розпакувати за допомогою XZ Embedded +(оÑÑŒ чому викориÑтано \fB\-\-check=crc32\fP) з викориÑтаннÑм лише 100\ КіБ +пам'Ñті. +.RS +.PP +.nf +\f(CRxz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo\fR +.fi +.RE +.PP +Якщо вам потрібно витиÑнути зі ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¼Ð°ÐºÑимальну кількіÑть байтів, може +допомогти ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾Ñті бітів контекÑту літералів (\fIlc\fP) та +кількіÑть позиційних бітів (\fIpb\fP). Також може допомогти ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ +кількоÑті бітів позиції літералів (\fIlp\fP), але, зазвичай, важливішими Ñ” +\fIlc\fP Ñ– \fIpb\fP. Ðаприклад, в архівах зі початковим кодом міÑтитьÑÑ +здебільшого текÑÑ‚ US\-ASCII, щоÑÑŒ подібне до наведеного нижче може дещо (на +щоÑÑŒ близьке до 0,1\ %) зменшити файл, порівнÑно із \fBxz \-6e\fP (Ñпробуйте +також без \fBlc=4\fP): +.RS +.PP +.nf +\f(CRxz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar\fR +.fi +.RE +.PP +ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñ–Ð½ÑˆÐ¾Ð³Ð¾ фільтра разом із LZMA2 може покращити ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð»Ñ +певних типів файлів. Ðаприклад, Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ¸ Ñпільного +кориÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ x86\-32 або x86\-64 з викориÑтаннÑм фільтра BCJ x86 ÑкориÑтайтеÑÑ +такою командою: +.RS +.PP +.nf +\f(CRxz \-\-x86 \-\-lzma2 libfoo.so\fR +.fi +.RE +.PP +Зауважте, що порÑдок параметрів Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ñ” значеннÑ. Якщо \fB\-\-x86\fP +вказано піÑÐ»Ñ \fB\-\-lzma2\fP, \fBxz\fP повідомить про помилку, оÑкільки піÑÐ»Ñ LZMA2 +не може бути жодного фільтра, а також оÑкільки фільтр BCJ x86 не можна +викориÑтовувати Ñк оÑтанній фільтр у ланцюжку. +.PP +Фільтр Delta разом із LZMA2 може дати добрі результати Ð´Ð»Ñ Ñ€Ð°Ñтрових +зображень. Зазвичай, результати Ñ” кращими за формат PNG, у Ñкого Ñ” декілька +більш доÑконалих фільтрів, ніж проÑта дельта, але там викориÑтовують Ð´Ð»Ñ +ÑтиÑÐºÐ°Ð½Ð½Ñ Deflate. +.PP +Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñлід берегти у неÑтиÑненому форматі, наприклад, Ñк неÑтиÑнений +TIFF. Параметр відÑтані фільтра Delta вÑтановлюють так, щоб він збігавÑÑ Ñ–Ð· +кількіÑтю байтів на пікÑель у зображенні. Ðаприклад, Ð´Ð»Ñ 24\-бітового +раÑтрового Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ RGB Ñлід вказати \fBdist=3\fP, а також добре передати +\fBpb=0\fP до LZMA2 Ð´Ð»Ñ Ð¿Ñ€Ð¸ÑтоÑÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ трибайтового вирівнюваннÑ: +.RS +.PP +.nf +\f(CRxz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff\fR +.fi +.RE +.PP +Якщо в один архів запаковано декілька зображень (наприклад, в архів +\&\fB.tar\fP), фільтр Delta також даватиме добрі результати, Ñкщо у вÑÑ–Ñ… +зображеннÑÑ… однакова кількіÑть байтів Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ пікÑелÑ. +. +.SH "ДИВ. ТÐКОЖ" +\fBxzdec\fP(1), \fBxzdiff\fP(1), \fBxzgrep\fP(1), \fBxzless\fP(1), \fBxzmore\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fB7z\fP(1) +.PP +XZ Utils: +.br +Вбудовуваний XZ: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/uk/xzdec.1 b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzdec.1 new file mode 100644 index 000000000..85a822159 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzdec.1 @@ -0,0 +1,85 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.\" Ukrainian translation for xz-man. +.\" Yuri Chornoivan , 2019, 2022, 2023, 2024, 2025. +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDEC 1 "8 ÐºÐ²Ñ–Ñ‚Ð½Ñ 2024 року" Tukaani "XZ Utils" +.SH ÐÐЗВР+xzdec, lzmadec — невеличкі розпакувальники .xz Ñ– .lzma +.SH "КОРОТКИЙ ОПИС" +\fBxzdec\fP [\fIпараметр...\fP] [\fIфайл...\fP] +.br +\fBlzmadec\fP [\fIпараметр...\fP] [\fIфайл...\fP] +.SH ОПИС +\fBxzdec\fP Ñ” інÑтрументом на оÑнові liblzma, Ñкий призначено лише Ð´Ð»Ñ +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² \fB.xz\fP (Ñ– лише файлів \fB.xz\fP). \fBxzdec\fP призначено Ð´Ð»Ñ +того, щоб працювати Ñк повноцінний замінник \fBxz\fP(1) у більшоÑті типових +Ñитуацій, де Ñкрипт було напиÑано Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ \fBxz \-\-decompress \-\-stdout\fP (Ñ–, можливо, декількох інших типових параметрів), Ð´Ð»Ñ +Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² \fB.xz\fP. \fBlzmadec\fP Ñ” тотожним до \fBxzdec\fP, але у +\fBlzmadec\fP передбачено підтримку файлів \fB.lzma\fP, заміÑть файлів \fB.xz\fP. +.PP +Щоб зменшити розмір виконуваного файла, у \fBxzdec\fP не передбачено підтримки +багатопотокової обробки та локалізації, а також Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð² зі +змінних Ñередовища \fBXZ_DEFAULTS\fP Ñ– \fBXZ_OPT\fP. У \fBxzdec\fP не передбачено +підтримки показу проміжних даних щодо поÑтупу: надÑÐ¸Ð»Ð°Ð½Ð½Ñ \fBSIGINFO\fP до +\fBxzdec\fP не призводить ні до Ñких наÑлідків, але надÑÐ¸Ð»Ð°Ð½Ð½Ñ \fBSIGUSR1\fP +перериває процеÑ, заміÑть показу даних щодо поÑтупу. +.SH ПÐРÐМЕТРИ +.TP +\fB\-d\fP, \fB\-\-decompress\fP, \fB\-\-uncompress\fP +Буде проігноровано Ð´Ð»Ñ ÑуміÑноÑті з \fBxz\fP(1). У \fBxzdec\fP передбачено +підтримку лише розпаковуваннÑ. +.TP +\fB\-k\fP, \fB\-\-keep\fP +Буде проігноровано. Призначено Ð´Ð»Ñ ÑуміÑноÑті з \fBxz\fP(1). \fBxzdec\fP ніколи не +Ñтворюватиме Ñ– ніколи не вилучатиме ці файли. +.TP +\fB\-c\fP, \fB\-\-stdout\fP, \fB\-\-to\-stdout\fP +Буде проігноровано. Ð”Ð»Ñ ÑуміÑноÑті з \fBxz\fP(1). \fBxzdec\fP завжди запиÑує +розпаковані дані до Ñтандартного виведеннÑ. +.TP +\fB\-q\fP, \fB\-\-quiet\fP +Якщо цей параметр вказано один раз, нічого не ÑтанетьÑÑ, оÑкільки \fBxzdec\fP +ніколи не показуватиме жодних попереджень або нотаток. Вкажіть параметр +двічі, щоб придушити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилки. +.TP +\fB\-Q\fP, \fB\-\-no\-warn\fP +Буде проігноровано Ð´Ð»Ñ ÑуміÑноÑті із \fBxz\fP(1). \fBxzdec\fP ніколи не +викориÑтовує Ñтан виходу 2. +.TP +\fB\-h\fP, \fB\-\-help\fP +ВивеÑти довідкове Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ– уÑпішно завершити роботу. +.TP +\fB\-V\fP, \fB\-\-version\fP +ВивеÑти номер верÑÑ–Ñ— \fBxzdec\fP та liblzma. +.SH "СТÐРВИХОДУ" +.TP +\fB0\fP +УÑе добре. +.TP +\fB1\fP +СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. +.PP +\fBxzdec\fP не має жодних повідомлень із попередженнÑми, на відміну від +\fBxz\fP(1), тому у \fBxzdec\fP Ñтан виходу 2 не викориÑтовуєтьÑÑ. +.SH ПРИМІТКИ +КориÑтуйтеÑÑ \fBxz\fP(1), заміÑть \fBxzdec\fP або \fBlzmadec\fP, Ð´Ð»Ñ Ñ‰Ð¾Ð´ÐµÐ½Ð½Ð¸Ñ… +потреб. \fBxzdec\fP та \fBlzmadec\fP призначено лише Ð´Ð»Ñ Ñ‚Ð¸Ñ… Ñитуацій, коли +важливо мати меншу програму Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ, ніж \fBxz\fP(1). +.PP +\fBxzdec\fP Ñ– \fBlzmadec\fP не такі вже Ñ– малі програми. Їхній розмір можна +зменшити викиданнÑм можливоÑтей з liblzma під Ñ‡Ð°Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ, але цього +зазвичай не роблÑть Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÐ²Ð°Ð½Ð¸Ñ… файлів, Ñкі поширюютьÑÑ Ñƒ типових, не +вбудованих, диÑтрибутивах операційних ÑиÑтем. Якщо вам потрібний дуже мала +програма Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ \fB.xz\fP, варто ÑкориÑтатиÑÑ XZ Embedded. +.SH "ДИВ. ТÐКОЖ" +\fBxz\fP(1) +.PP +Вбудовуваний XZ: diff --git a/cpp/third_party/xz-5.8.3/po4a/man/uk/xzdiff.1 b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzdiff.1 new file mode 100644 index 000000000..0dd388c06 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzdiff.1 @@ -0,0 +1,56 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Ukrainian translation for xz-man. +.\" Yuri Chornoivan , 2019, 2022, 2023, 2024, 2025. +.\" +.\" (Note that this file is not based on gzip's zdiff.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZDIFF 1 "6 Ð±ÐµÑ€ÐµÐ·Ð½Ñ 2025 року" Tukaani "XZ Utils" +.SH ÐÐЗВР+xzcmp, xzdiff, lzcmp, lzdiff — порівнÑÐ½Ð½Ñ ÑтиÑнених файлів +. +.SH "КОРОТКИЙ ОПИС" +\fBxzcmp\fP [\fIпараметр...\fP] \fIфайл1\fP [\fIфайл2\fP] +.br +\fBxzdiff\fP \&... +.br +\fBlzcmp\fP \&... (ЗÐСТÐРІЛО) +.br +\fBlzdiff\fP \&... (ЗÐСТÐРІЛО) +. +.SH ОПИС +\fBxzcmp\fP Ñ– \fBxzdiff\fP порівнюють неÑтиÑнені дані двох файлів. ÐеÑтиÑнені дані +та параметри буде передано \fBcmp\fP(1) або \fBdiff\fP(1), Ñкщо не вказано +\fB\-\-help\fP або \fB\-\-version\fP. +.PP +Якщо вказано одразу \fIфайл1\fP Ñ– \fIфайл2\fP, це можуть бути неÑтиÑнені файли або +файли у форматах, Ñкі може бути розпаковано за допомогою \fBxz\fP(1), +\fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1) або \fBlz4\fP(1). Потрібні +команди Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð°ÑŽÑ‚ÑŒÑÑ Ð· ÑуфікÑів назв файлів \fIфайл1\fP Ñ– +\fIфайл2\fP. Файли із невідомими програмі ÑуфікÑами вважатимутьÑÑ Ð°Ð±Ð¾ +неÑтиÑненими або такими, що мають формат, дані у Ñкому може розпаковувати +\fBxz\fP(1). +.PP +Якщо вказано лише одну назву файла, \fIфайл1\fP повинен мати ÑÑƒÑ„Ñ–ÐºÑ +підтримуваного формату ÑтиÑканнÑ, а назвою \fIфайл2\fP має бути назва \fIфайл1\fP +з вилученим ÑуфікÑом формату ÑтиÑканнÑ. +.PP +ПрацездатніÑть команд \fBlzcmp\fP Ñ– \fBlzdiff\fP забезпечено Ð´Ð»Ñ Ð·Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¾Ñ— +ÑуміÑноÑті із LZMA Utils. Ці команди вважаютьÑÑ Ð·Ð°Ñтарілими, Ñ—Ñ… буде +вилучено у майбутній верÑÑ–Ñ— комплекту програм. +. +.SH "СТÐРВИХОДУ" +Якщо ÑтанетьÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° розпаковуваннÑ, Ñтаном виходу буде \fB2\fP. Інакше, +Ñтаном виходу буде \fBcmp\fP(1) або буде викориÑтано \fBdiff\fP(1). +. +.SH "ДИВ. ТÐКОЖ" +\fBcmp\fP(1), \fBdiff\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), +\fBzstd\fP(1), \fBlz4\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/uk/xzgrep.1 b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzgrep.1 new file mode 100644 index 000000000..e88272918 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzgrep.1 @@ -0,0 +1,96 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Lasse Collin +.\" Jia Tan +.\" +.\" Ukrainian translation for xz-man. +.\" Yuri Chornoivan , 2019, 2022, 2023, 2024, 2025. +.\" +.\" (Note that this file is not based on gzip's zgrep.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZGREP 1 "6 Ð±ÐµÑ€ÐµÐ·Ð½Ñ 2025 року" Tukaani "XZ Utils" +.SH ÐÐЗВР+xzgrep — пошук взірців у ймовірно ÑтиÑнених файлах +. +.SH "КОРОТКИЙ ОПИС" +\fBxzgrep\fP [\fIпараметр...\fP] [\fIÑпиÑок_взірців\fP] [\fIфайл...\fP] +.br +\fBxzegrep\fP \&... +.br +\fBxzfgrep\fP \&... +.br +\fBlzgrep\fP \&... (ЗÐСТÐРІЛО) +.br +\fBlzegrep\fP \&... (ЗÐСТÐРІЛО) +.br +\fBlzfgrep\fP \&... (ЗÐСТÐРІЛО) +. +.SH ОПИС +\fBxzgrep\fP викликає \fBgrep\fP(1) Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²Ð°Ð½Ð¸Ñ… даних файлів. Формати +\fIфайлів\fP визначатимутьÑÑ Ð· ÑуфікÑів назв файлів. Будь\-Ñкий \fIфайл\fP із +ÑуфікÑом назви, підтримку Ñкого передбачено у \fBxz\fP(1), \fBgzip\fP(1), +\fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1) або \fBlz4\fP(1), буде розпаковано; уÑÑ– +інші файли вважатимутьÑÑ Ð½ÐµÑтиÑненими. +.PP +Якщо не вказано аргументу \fIфайли\fP або заміÑть \fIфайл\fP вказано \fB\-\fP, дані +буде прочитано зі Ñтандартного джерела вхідних даних. При читанні зі +Ñтандартного джерела буде розпаковано лише файли, підтримку Ñких передбачено +у \fBxz\fP(1). Інші файли вважатимутьÑÑ Ñ‚Ð°ÐºÐ¸Ð¼Ð¸, що вже перебувають у +неÑтиÑненому форматі. +.PP +Передбачено підтримку більшоÑті \fIпараметрів\fP \fBgrep\fP(1). Втім, підтримки +цих параметрів не передбачено: +.IP "" 4 +\fB\-r\fP, \fB\-\-recursive\fP +.IP "" 4 +\fB\-R\fP, \fB\-\-dereference\-recursive\fP +.IP "" 4 +\fB\-d\fP, \fB\-\-directories=\fP\fIдіÑ\fP +.IP "" 4 +\fB\-Z\fP, \fB\-\-null\fP +.IP "" 4 +\fB\-z\fP, \fB\-\-null\-data\fP +.IP "" 4 +\fB\-\-include=\fP\fIglob\fP +.IP "" 4 +\fB\-\-exclude=\fP\fIglob\fP +.IP "" 4 +\fB\-\-exclude\-from=\fP\fIфайл\fP +.IP "" 4 +\fB\-\-exclude\-dir=\fP\fIglob\fP +.PP +\fBxzegrep\fP Ñ” альтернативним запиÑом \fBxzgrep \-E\fP. \fBxzfgrep\fP Ñ” +альтернативним запиÑом \fBxzgrep \-F\fP. +.PP +ПрацездатніÑть команд \fBlzgrep\fP, \fBlzegrep\fP Ñ– \fBlzfgrep\fP забезпечено Ð´Ð»Ñ +зворотної ÑуміÑноÑті із LZMA Utils. Ці команди вважаютьÑÑ Ð·Ð°Ñтарілими, Ñ—Ñ… +буде вилучено у майбутній верÑÑ–Ñ— комплекту програм. +. +.SH "СТÐРВИХОДУ" +.TP +0 +Ð’ одному з файлів вхідних даних знайдено принаймні одну +відповідніÑть. Помилок не ÑталоÑÑ. +.TP +1 +У жодному з файлів вхідних даних не знайдено відповідника. Ðе ÑталоÑÑ Ð½Ñ–Ñких +помилок. +.TP +>1 +СталаÑÑ Ð¾Ð´Ð½Ð° або декілька помилок. Ðевідомо, чи було знайдено відповідники +критерію пошуку. +. +.SH СЕРЕДОВИЩЕ +.TP +\fBGREP\fP +Якщо Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ— Ñередовища \fBGREP\fP вÑтановлено непорожнє значеннÑ, його +буде викориÑтано заміÑть \fBgrep\fP(1), \fBgrep \-E\fP або \fBgrep \-F\fP. +. +.SH "ДИВ. ТÐКОЖ" +\fBgrep\fP(1), \fBxz\fP(1), \fBgzip\fP(1), \fBbzip2\fP(1), \fBlzop\fP(1), \fBzstd\fP(1), +\fBlz4\fP(1), \fBzgrep\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/uk/xzless.1 b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzless.1 new file mode 100644 index 000000000..c3b275d0d --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzless.1 @@ -0,0 +1,49 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Ukrainian translation for xz-man. +.\" Yuri Chornoivan , 2019, 2022, 2023, 2024, 2025. +.\" +.\" (Note that this file is not based on gzip's zless.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZLESS 1 "6 Ð±ÐµÑ€ÐµÐ·Ð½Ñ 2025 року" Tukaani "XZ Utils" +.SH ÐÐЗВР+xzless, lzless — переглÑд ÑтиÑнених xz або lzma (текÑтових) файлів +.SH "КОРОТКИЙ ОПИС" +\fBxzless\fP [\fIфайл\fP...] +.br +\fBlzless\fP [\fIфайл\fP...] (ЗÐСТÐРІЛО) +.SH ОПИС +\fBxzless\fP Ñ” фільтром, Ñкий показує текÑÑ‚ зі ÑтиÑнених файлів у +терміналі. Файли, підтримку обробки Ñких передбачено у \fBxz\fP(1), буде +розпаковано; інші файли вважатимутьÑÑ Ð½ÐµÑтиÑненими. Якщо не вказано жодного +\fIфайла\fP, \fBxzless\fP читатиме дані зі Ñтандартного джерела вхідних даних. +.PP +Ð”Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ виведених даних \fBxzless\fP викориÑтовує \fBless\fP(1). Ðа відміну від +\fBxzmore\fP, вибір програми Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ–Ð»Ñƒ на Ñторінки не можна змінити за +допомогою змінної Ñередовища. Команди заÑновано на \fBmore\fP(1) Ñ– \fBvi\fP(1). За +допомогою команд можна проÑуватиÑÑ Ð½Ð°Ð·Ð°Ð´ Ñ– вперед даними та шукати дані. Щоб +дізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ, ознайомтеÑÑ Ñ–Ð· підручником з \fBless\fP(1). +.PP +Команду \fBlzless\fP реалізовано Ð´Ð»Ñ Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¾Ñ— ÑуміÑноÑті з LZMA +Utils. Ð¦Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° вважаєтьÑÑ Ð·Ð°Ñтарілою, Ñ—Ñ— буде вилучено у майбутній верÑÑ–Ñ— +комплекту програм. +.SH СЕРЕДОВИЩЕ +.TP +\fBLESSMETACHARS\fP +СпиÑок Ñимволів, Ñкі Ñ” оÑобливими Ñимволами командної +оболонки. Ð’ÑтановлюєтьÑÑ \fBxzless\fP, Ñкщо його ще не вÑтановлено у +Ñередовищі. +.TP +\fBLESSOPEN\fP +Має Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ñдка команди Ð´Ð»Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑƒ заÑобу Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ \fBxz\fP(1) Ð´Ð»Ñ +обробки вхідних файлів \fBless\fP(1). +.SH "ДИВ. ТÐКОЖ" +\fBless\fP(1), \fBxz\fP(1), \fBxzmore\fP(1), \fBzless\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/man/uk/xzmore.1 b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzmore.1 new file mode 100644 index 000000000..bf320be54 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/man/uk/xzmore.1 @@ -0,0 +1,51 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Authors: Andrew Dudman +.\" Lasse Collin +.\" +.\" Ukrainian translation for xz-man. +.\" Yuri Chornoivan , 2019, 2022, 2023, 2024, 2025. +.\" +.\" (Note that this file is based on xzless.1 instead of gzip's zmore.1.) +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH XZMORE 1 "6 Ð±ÐµÑ€ÐµÐ·Ð½Ñ 2025 року" Tukaani "XZ Utils" +.SH ÐÐЗВР+xzmore, lzmore — переглÑд ÑтиÑнених xz або lzma (текÑтових) файлів +. +.SH "КОРОТКИЙ ОПИС" +\fBxzmore\fP [\fIфайл\fP...] +.br +\fBlzmore\fP [\fIфайл\fP...] (ЗÐСТÐРІЛО) +. +.SH ОПИС +\fBxzmore\fP показує текÑÑ‚ зі ÑтиÑнених файлів у терміналі за допомогою +\fBmore\fP(1). Файли, підтримку Ñких передбачено у \fBxz\fP(1), буде розпаковано; +інші файли вважатимутьÑÑ Ð²Ð¶Ðµ наданими у розпакованій формі. Якщо не вказано +аргументу \fIфайли\fP, \fBxzmore\fP читатиме дані зі Ñтандартного джерела +даних. Див. підручник з \fBmore\fP(1), щоб дізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про клавіатурні +команди. +.PP +Зауважте, що Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ñƒ зворотному напрÑмку може бути неможливим через +реалізацію \fBmore\fP(1). Причиною Ñ” те, що \fBxzmore\fP викориÑтовує канал Ð´Ð»Ñ +Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²Ð°Ð½Ð¸Ñ… даних \fBmore\fP(1). \fBxzless\fP(1) викориÑтовує +\fBless\fP(1), можливоÑті Ñкої Ñ” ширшими. +.PP +Команду \fBlzmore\fP реалізовано Ð´Ð»Ñ Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¾Ñ— ÑуміÑноÑті з LZMA +Utils. Ð¦Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° вважаєтьÑÑ Ð·Ð°Ñтарілою, Ñ—Ñ— буде вилучено у майбутній верÑÑ–Ñ— +комплекту програм. +. +.SH СЕРЕДОВИЩЕ +.TP +.\" TRANSLATORS: Don't translate the uppercase PAGER. +.\" It is a name of an environment variable. +\fBPAGER\fP +Якщо вÑтановлено Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \fBPAGER\fP, Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ викориÑтано Ð´Ð»Ñ Ð·Ð°Ñобу +поділу на Ñторінки, заміÑть \fBmore\fP(1). +. +.SH "ДИВ. ТÐКОЖ" +\fBmore\fP(1), \fBxz\fP(1), \fBxzless\fP(1), \fBzmore\fP(1) diff --git a/cpp/third_party/xz-5.8.3/po4a/po4a.conf b/cpp/third_party/xz-5.8.3/po4a/po4a.conf new file mode 100644 index 000000000..0f93706a9 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/po4a.conf @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: 0BSD + +# To add a new language, add it to po4a_langs and run "update-po" +# to get a new .po file. After translating the .po file, run +# "update-po" again to generate the translated man pages. + +[po4a_langs] ar de fr it ko pt_BR ro sr sv uk +[po4a_paths] xz-man.pot $lang:$lang.po + +[type: man] ../src/xz/xz.1 $lang:man/$lang/xz.1 add_$lang:?$lang.po.authors +[type: man] ../src/xzdec/xzdec.1 $lang:man/$lang/xzdec.1 add_$lang:?$lang.po.authors +[type: man] ../src/lzmainfo/lzmainfo.1 $lang:man/$lang/lzmainfo.1 add_$lang:?$lang.po.authors +[type: man] ../src/scripts/xzdiff.1 $lang:man/$lang/xzdiff.1 add_$lang:?$lang.po.authors +[type: man] ../src/scripts/xzgrep.1 $lang:man/$lang/xzgrep.1 add_$lang:?$lang.po.authors +[type: man] ../src/scripts/xzless.1 $lang:man/$lang/xzless.1 add_$lang:?$lang.po.authors +[type: man] ../src/scripts/xzmore.1 $lang:man/$lang/xzmore.1 add_$lang:?$lang.po.authors diff --git a/cpp/third_party/xz-5.8.3/po4a/pt_BR.po b/cpp/third_party/xz-5.8.3/po4a/pt_BR.po new file mode 100644 index 000000000..6091fe67b --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/pt_BR.po @@ -0,0 +1,4003 @@ +# Brazilian Portuguese translations for xz package +# Traduções em português brasileiro para o pacote xz. +# This file is put in the public domain. +# Rafael Fontenelle , 2022-2023. +# +msgid "" +msgstr "" +"Project-Id-Version: xz-man 5.4.0-pre2\n" +"POT-Creation-Date: 2026-03-31 18:27+0300\n" +"PO-Revision-Date: 2023-01-26 13:29-0300\n" +"Last-Translator: Rafael Fontenelle \n" +"Language-Team: Brazilian Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"X-Generator: Gtranslator 42.0\n" + +#. type: TH +#: ../src/xz/xz.1 +#, no-wrap +msgid "XZ" +msgstr "XZ" + +#. type: TH +#: ../src/xz/xz.1 +#, no-wrap +msgid "2025-03-08" +msgstr "" + +#. type: TH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "Tukaani" +msgstr "Tukaani" + +#. type: TH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "XZ Utils" +msgstr "XZ Utils" + +#. type: SH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "NAME" +msgstr "NOME" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "xz, unxz, xzcat, lzma, unlzma, lzcat - Compress or decompress .xz and .lzma files" +msgstr "xz, unxz, xzcat, lzma, unlzma, lzcat - Compacta ou descompacta arquivos .xz e .lzma" + +#. type: SH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "SYNOPSIS" +msgstr "SINOPSE" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B [I] [I]" +msgstr "B [I] [I]" + +#. type: SH +#: ../src/xz/xz.1 +#, no-wrap +msgid "COMMAND ALIASES" +msgstr "COMANDOS APELIDOS" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B é equivalente a B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B é equivalente a B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B é equivalente a B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B é equivalente a B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B é equivalente a B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When writing scripts that need to decompress files, it is recommended to always use the name B with appropriate arguments (B or B) instead of the names B and B." +msgstr "Ao escrever scripts que precisam descompactar arquivos, é recomendável sempre usar o nome B com os argumentos apropriados (B ou B) em vez dos nomes B e B." + +#. type: SH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "DESCRIPTION" +msgstr "DESCRIÇÃO" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is a general-purpose data compression tool with command line syntax similar to B(1) and B(1). The native file format is the B<.xz> format, but the legacy B<.lzma> format used by LZMA Utils and raw compressed streams with no container format headers are also supported. In addition, decompression of the B<.lz> format used by B is supported." +msgstr "B é uma ferramenta de compactação de dados de uso geral com sintaxe de linha de comando semelhante ao B(1) e ao B(1). O formato de arquivo nativo é o formato B<.xz>, mas o formato legado B<.lzma> usado por LZMA Utils e fluxos compactados brutos sem cabeçalhos de formato de contêiner também são suportados. Além disso, a descompactação do formato B<.lz> usado por B é suportada." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B compresses or decompresses each I according to the selected operation mode. If no I are given or I is B<->, B reads from standard input and writes the processed data to standard output. B will refuse (display an error and skip the I) to write compressed data to standard output if it is a terminal. Similarly, B will refuse to read compressed data from standard input if it is a terminal." +msgstr "B compacta ou descompacta cada I de acordo com o modo de operação selecionado. Se nenhum I for fornecido ou I for B<->, B lê da entrada padrão e grava os dados processados na saída padrão. B recusará (exibirá um erro e ignorará o I) para gravar dados compactados na saída padrão se for um terminal. Da mesma forma, B se recusará a ler dados compactados da entrada padrão se for um terminal." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Unless B<--stdout> is specified, I other than B<-> are written to a new file whose name is derived from the source I name:" +msgstr "A menos que B<--stdout> seja especificado, I diferentes de B<-> são gravados em um novo arquivo cujo nome é derivado do nome I de origem:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "\\(bu" +msgstr "\\(bu" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing, the suffix of the target file format (B<.xz> or B<.lzma>) is appended to the source filename to get the target filename." +msgstr "Ao compactar, o sufixo do formato de arquivo de destino (B<.xz> ou B<.lzma>) é anexado ao nome do arquivo de origem para obter o nome do arquivo de destino." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When decompressing, the B<.xz>, B<.lzma>, or B<.lz> suffix is removed from the filename to get the target filename. B also recognizes the suffixes B<.txz> and B<.tlz>, and replaces them with the B<.tar> suffix." +msgstr "Ao descompactar, o sufixo B<.xz>, B<.lzma> ou B<.lz> é removido do nome do arquivo para obter o nome do arquivo de destino. B também reconhece os sufixos B<.txz> e B<.tlz> e os substitui pelo sufixo B<.tar>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the target file already exists, an error is displayed and the I is skipped." +msgstr "Se o arquivo de destino já existir, um erro será exibido e I será ignorado." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Unless writing to standard output, B will display a warning and skip the I if any of the following applies:" +msgstr "A menos que grave na saída padrão, B exibirá um aviso e pulará o I se qualquer um dos seguintes se aplicar:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I is not a regular file. Symbolic links are not followed, and thus they are not considered to be regular files." +msgstr "I não é um arquivo normal. Links simbólicos não são seguidos e, portanto, não são considerados arquivos comuns." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I has more than one hard link." +msgstr "I tem mais de um link físico." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I has setuid, setgid, or sticky bit set." +msgstr "I tem setuid, setgid ou sticky bit definido." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The operation mode is set to compress and the I already has a suffix of the target file format (B<.xz> or B<.txz> when compressing to the B<.xz> format, and B<.lzma> or B<.tlz> when compressing to the B<.lzma> format)." +msgstr "O modo de operação está definido para compactar e o I já possui um sufixo do formato de arquivo de destino (B<.xz> ou B<.txz> ao compactar para o formato B<.xz> e B<.lzma > ou B<.tlz> ao compactar para o formato B<.lzma>)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The operation mode is set to decompress and the I doesn't have a suffix of any of the supported file formats (B<.xz>, B<.txz>, B<.lzma>, B<.tlz>, or B<.lz>)." +msgstr "O modo de operação está definido para descompactar e o I não possui um sufixo de nenhum dos formatos de arquivo suportados (B<.xz>, B<.txz>, B<.lzma>, B<.tlz> , ou B<.lz>)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "After successfully compressing or decompressing the I, B copies the owner, group, permissions, access time, and modification time from the source I to the target file. If copying the group fails, the permissions are modified so that the target file doesn't become accessible to users who didn't have permission to access the source I. B doesn't support copying other metadata like access control lists or extended attributes yet." +msgstr "Depois de compactar ou descompactar com êxito o I, o B copia o dono, grupo, permissões, horário de acesso e horário de modificação do I de origem para o arquivo de destino. Se a cópia do grupo falhar, as permissões serão modificadas para que o arquivo de destino não se torne acessível a usuários que não têm permissão para acessar o I de origem. B ainda não oferece suporte à cópia de outros metadados, como listas de controle de acesso ou atributos estendidos." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Once the target file has been successfully closed, the source I is removed unless B<--keep> was specified. The source I is never removed if the output is written to standard output or if an error occurs." +msgstr "Depois que o arquivo de destino for fechado com êxito, o I de origem será removido, a menos que B<--keep> tenha sido especificado. O I de origem nunca é removido se a saída for gravada na saída padrão ou se ocorrer um erro." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Sending B or B to the B process makes it print progress information to standard error. This has only limited use since when standard error is a terminal, using B<--verbose> will display an automatically updating progress indicator." +msgstr "O envio de B ou B para o processo do B faz com que ele imprima informações de andamento para erro padrão. Isso tem uso limitado, pois quando o erro padrão é um terminal, usar B<--verbose> exibirá um indicador de progresso de atualização automática." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Memory usage" +msgstr "Uso de memória" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The memory usage of B varies from a few hundred kilobytes to several gigabytes depending on the compression settings. The settings used when compressing a file determine the memory requirements of the decompressor. Typically the decompressor needs 5\\ % to 20\\ % of the amount of memory that the compressor needed when creating the file. For example, decompressing a file created with B currently requires 65\\ MiB of memory. Still, it is possible to have B<.xz> files that require several gigabytes of memory to decompress." +msgstr "O uso de memória de B varia de algumas centenas de kilobytes a vários gigabytes, dependendo das configurações de compactação. As configurações usadas ao compactar um arquivo determinam os requisitos de memória do descompactador. Normalmente, o descompactador precisa de 5\\ % a 20\\ % da quantidade de memória que o compactador precisou ao criar o arquivo. Por exemplo, descompactar um arquivo criado com B atualmente requer 65\\ MiB de memória. Ainda assim, é possível ter arquivos B<.xz> que requerem vários gigabytes de memória para descompactar." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Especially users of older systems may find the possibility of very large memory usage annoying. To prevent uncomfortable surprises, B has a built-in memory usage limiter, which is disabled by default. While some operating systems provide ways to limit the memory usage of processes, relying on it wasn't deemed to be flexible enough (for example, using B(1) to limit virtual memory tends to cripple B(2))." +msgstr "Especialmente os usuários de sistemas mais antigos podem achar irritante a possibilidade de uso de memória muito grande. Para evitar surpresas desconfortáveis, o B possui um limitador de uso de memória embutido, que está desabilitado por padrão. Embora alguns sistemas operacionais forneçam maneiras de limitar o uso de memória dos processos, confiar nele não foi considerado flexível o suficiente (por exemplo, usar B(1) para limitar a memória virtual tende a prejudicar B(2))." + +#. TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +#. It's a name of an environment variable. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The memory usage limiter can be enabled with the command line option B<--memlimit=>I. Often it is more convenient to enable the limiter by default by setting the environment variable B, for example, B. It is possible to set the limits separately for compression and decompression by using B<--memlimit-compress=>I and B<--memlimit-decompress=>I. Using these two options outside B is rarely useful because a single run of B cannot do both compression and decompression and B<--memlimit=>I (or B<-M> I) is shorter to type on the command line." +msgstr "O limitador de uso de memória pode ser ativado com a opção de linha de comando B<--memlimit=>I. Geralmente é mais conveniente habilitar o limitador por padrão definindo a variável de ambiente B, por exemplo, B. É possível definir os limites separadamente para compactação e descompactação usando B<--memlimit-compress=>I e B<--memlimit-decompress=>I. Usar essas duas opções fora de B raramente é útil porque uma única execução de B não pode fazer compactação e descompactação e B<--memlimit=>I (ou B<-M> I ) é mais curto para digitar na linha de comando." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the specified memory usage limit is exceeded when decompressing, B will display an error and decompressing the file will fail. If the limit is exceeded when compressing, B will try to scale the settings down so that the limit is no longer exceeded (except when using B<--format=raw> or B<--no-adjust>). This way the operation won't fail unless the limit is very small. The scaling of the settings is done in steps that don't match the compression level presets, for example, if the limit is only slightly less than the amount required for B, the settings will be scaled down only a little, not all the way down to B." +msgstr "Se o limite de uso de memória especificado for excedido durante a descompactação, B exibirá um erro e a descompactação do arquivo falhará. Se o limite for excedido durante a compactação, B tentará reduzir as configurações para que o limite não seja mais excedido (exceto ao usar B<--format=raw> ou B<--no-adjust>). Dessa forma, a operação não falhará, a menos que o limite seja muito pequeno. A escala das configurações é feita em etapas que não correspondem às predefinições do nível de compactação, por exemplo, se o limite for apenas um pouco menor que o valor necessário para B, as configurações serão reduzidas apenas um pouco , não até B." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Concatenation and padding with .xz files" +msgstr "Concatenação e preenchimento com arquivos .xz" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "It is possible to concatenate B<.xz> files as is. B will decompress such files as if they were a single B<.xz> file." +msgstr "É possível concatenar arquivos B<.xz> como estão. B irá descompactar tais arquivos como se fossem um único arquivo B<.xz>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "It is possible to insert padding between the concatenated parts or after the last part. The padding must consist of null bytes and the size of the padding must be a multiple of four bytes. This can be useful, for example, if the B<.xz> file is stored on a medium that measures file sizes in 512-byte blocks." +msgstr "É possível inserir preenchimento entre as partes concatenadas ou após a última parte. O preenchimento deve consistir em bytes nulos e o tamanho do preenchimento deve ser um múltiplo de quatro bytes. Isso pode ser útil, por exemplo, se o arquivo B<.xz> for armazenado em uma mídia que mede tamanhos de arquivo em blocos de 512 bytes." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Concatenation and padding are not allowed with B<.lzma> files or raw streams." +msgstr "Concatenação e preenchimento não são permitidos com arquivos B<.lzma> ou fluxos brutos." + +#. type: SH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "OPTIONS" +msgstr "OPÇÕES" + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Integer suffixes and special values" +msgstr "Sufixos inteiros e valores especiais" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers. There must be no space between the integer and the suffix." +msgstr "Na maioria dos lugares onde um argumento inteiro é esperado, um sufixo opcional é suportado para indicar facilmente números inteiros grandes. Não deve haver espaço entre o número inteiro e o sufixo." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Multiply the integer by 1,024 (2^10). B, B, B, B, and B are accepted as synonyms for B." +msgstr "Multiplica o inteiro por 1.024 (2^10). B, B, B, B e B são aceitos como sinônimos de B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Multiply the integer by 1,048,576 (2^20). B, B, B, and B are accepted as synonyms for B." +msgstr "Multiplica o número inteiro por 1.048.576 (2^20). B, B, B e B são aceitos como sinônimos de B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Multiply the integer by 1,073,741,824 (2^30). B, B, B, and B are accepted as synonyms for B." +msgstr "Multiplica o número inteiro por 1.073.741.824 (2^30). B, B, B e B são aceitos como sinônimos de B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The special value B can be used to indicate the maximum integer value supported by the option." +msgstr "O valor especial B pode ser usado para indicar o valor inteiro máximo suportado pela opção." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Operation mode" +msgstr "Modo de operação" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If multiple operation mode options are given, the last one takes effect." +msgstr "Se várias opções de modo de operação forem dadas, a última entrará em vigor." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-z>, B<--compress>" +msgstr "B<-z>, B<--compress>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress. This is the default operation mode when no operation mode option is specified and no other operation mode is implied from the command name (for example, B implies B<--decompress>)." +msgstr "Compacta. Este é o modo de operação padrão quando nenhuma opção de modo de operação é especificada e nenhum outro modo de operação está implícito no nome do comando (por exemplo, B implica em B<--decompress>)." + +#. The DESCRIPTION section already says this but it's good to repeat it +#. here because the default behavior is a bit dangerous and new users +#. in a hurry may skip reading the DESCRIPTION section. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "After successful compression, the source file is removed unless writing to standard output or B<--keep> was specified." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-d>, B<--decompress>, B<--uncompress>" +msgstr "B<-d>, B<--decompress>, B<--uncompress>" + +#. The DESCRIPTION section already says this but it's good to repeat it +#. here because the default behavior is a bit dangerous and new users +#. in a hurry may skip reading the DESCRIPTION section. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Decompress. After successful decompression, the source file is removed unless writing to standard output or B<--keep> was specified." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-t>, B<--test>" +msgstr "B<-t>, B<--test>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Test the integrity of compressed I. This option is equivalent to B<--decompress --stdout> except that the decompressed data is discarded instead of being written to standard output. No files are created or removed." +msgstr "Testa a integridade de I compactados. Esta opção é equivalente a B<--decompress --stdout> exceto que os dados descompactados são descartados em vez de serem gravados na saída padrão. Nenhum arquivo é criado ou removido." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-l>, B<--list>" +msgstr "B<-l>, B<--list>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Print information about compressed I. No uncompressed output is produced, and no files are created or removed. In list mode, the program cannot read the compressed data from standard input or from other unseekable sources." +msgstr "Imprime informações sobre I compactados. Nenhuma saída descompactada é produzida e nenhum arquivo é criado ou removido. No modo de lista, o programa não pode ler os dados compactados da entrada padrão ou de outras fontes não pesquisáveis." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default listing shows basic information about I, one file per line. To get more detailed information, use also the B<--verbose> option. For even more information, use B<--verbose> twice, but note that this may be slow, because getting all the extra information requires many seeks. The width of verbose output exceeds 80 characters, so piping the output to, for example, B may be convenient if the terminal isn't wide enough." +msgstr "A listagem padrão mostra informações básicas sobre I, um arquivo por linha. Para obter informações mais detalhadas, use também a opção B<--verbose>. Para obter ainda mais informações, use B<--verbose> duas vezes, mas observe que isso pode ser lento, porque obter todas as informações extras requer muitas buscas. A largura da saída detalhada excede 80 caracteres, portanto, canalizar a saída para, por exemplo, B pode ser conveniente se o terminal não tiver largura o suficiente." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The exact output may vary between B versions and different locales. For machine-readable output, B<--robot --list> should be used." +msgstr "A saída exata pode variar entre versões B e localidades diferentes. Para saída legível por máquina, B<--robot --list> deve ser usado." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Operation modifiers" +msgstr "Modificadores de operação" + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-k>, B<--keep>" +msgstr "B<-k>, B<--keep>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Don't delete the input files." +msgstr "Não exclui os arquivos de entrada." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Since B 5.2.6, this option also makes B compress or decompress even if the input is a symbolic link to a regular file, has more than one hard link, or has the setuid, setgid, or sticky bit set. The setuid, setgid, and sticky bits are not copied to the target file. In earlier versions this was only done with B<--force>." +msgstr "Desde B 5.2.6, esta opção também faz B compactar ou descompactar mesmo se a entrada for um link simbólico para um arquivo comum, tiver mais de um link físico ou tiver o setuid, setgid ou sticky bit definir. Os bits setuid, setgid e sticky não são copiados para o arquivo de destino. Nas versões anteriores, isso era feito apenas com B<--force>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-f>, B<--force>" +msgstr "B<-f>, B<--force>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This option has several effects:" +msgstr "Esta opção tem vários efeitos:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the target file already exists, delete it before compressing or decompressing." +msgstr "Se o arquivo de destino já existir, o exclui antes de compactar ou descompactar." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress or decompress even if the input is a symbolic link to a regular file, has more than one hard link, or has the setuid, setgid, or sticky bit set. The setuid, setgid, and sticky bits are not copied to the target file." +msgstr "Compacta ou descompacta, mesmo que a entrada seja um link simbólico para um arquivo normal, tenha mais de um link físico ou tenha setuid, setgid ou sticky bit definido. Os bits setuid, setgid e sticky não são copiados para o arquivo de destino." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When used with B<--decompress> B<--stdout> and B cannot recognize the type of the source file, copy the source file as is to standard output. This allows B B<--force> to be used like B(1) for files that have not been compressed with B. Note that in future, B might support new compressed file formats, which may make B decompress more types of files instead of copying them as is to standard output. B<--format=>I can be used to restrict B to decompress only a single file format." +msgstr "Quando usado com B<--decompress> B<--stdout> e B não consegue reconhecer o tipo do arquivo de origem, copia o arquivo de origem como está na saída padrão. Isso permite que B B<--force> seja usado como B(1) para arquivos que não foram compactados com B. Observe que, no futuro, o B pode oferecer suporte a novos formatos de arquivo compactado, o que pode fazer com que o B descompacte mais tipos de arquivos em vez de copiá-los como na saída padrão. B<--format=>I pode ser usado para restringir B para descompactar apenas um único formato de arquivo." + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-c>, B<--stdout>, B<--to-stdout>" +msgstr "B<-c>, B<--stdout>, B<--to-stdout>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Write the compressed or decompressed data to standard output instead of a file. This implies B<--keep>." +msgstr "Grava os dados compactados ou descompactados na saída padrão em vez de em um arquivo. Isso implica em B<--keep>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--single-stream>" +msgstr "B<--single-stream>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Decompress only the first B<.xz> stream, and silently ignore possible remaining input data following the stream. Normally such trailing garbage makes B display an error." +msgstr "Descompacta apenas o primeiro fluxo de B<.xz> e ignora silenciosamente possíveis dados de entrada restantes após o fluxo. Normalmente, esse restante posterior sem uso faz com que B exiba um erro." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B never decompresses more than one stream from B<.lzma> files or raw streams, but this option still makes B ignore the possible trailing data after the B<.lzma> file or raw stream." +msgstr "B nunca descompacta mais de um fluxo de arquivos B<.lzma> ou fluxos brutos, mas esta opção ainda faz B ignorar os possíveis dados posteriores após o arquivo B<.lzma> ou fluxo bruto." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This option has no effect if the operation mode is not B<--decompress> or B<--test>." +msgstr "Esta opção não tem efeito se o modo de operação não for B<--decompress> ou B<--test>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Since B 5.7.1alpha, B<--single-stream> implies B<--keep>." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--no-sparse>" +msgstr "B<--no-sparse>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Disable creation of sparse files. By default, if decompressing into a regular file, B tries to make the file sparse if the decompressed data contains long sequences of binary zeros. It also works when writing to standard output as long as standard output is connected to a regular file and certain additional conditions are met to make it safe. Creating sparse files may save disk space and speed up the decompression by reducing the amount of disk I/O." +msgstr "Desativa a criação de arquivos esparsos. Por padrão, ao descompactar em um arquivo normal, B tenta tornar o arquivo esparso se os dados descompactados contiverem longas sequências de zeros binários. Ele também funciona ao gravar na saída padrão, desde que a saída padrão esteja conectada a um arquivo normal e certas condições adicionais sejam atendidas para torná-la segura. A criação de arquivos esparsos pode economizar espaço em disco e acelerar a descompactação, reduzindo a quantidade de E/S do disco." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-S> I<.suf>, B<--suffix=>I<.suf>" +msgstr "B<-S> I<.suf>, B<--suffix=>I<.suf>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing, use I<.suf> as the suffix for the target file instead of B<.xz> or B<.lzma>. If not writing to standard output and the source file already has the suffix I<.suf>, a warning is displayed and the file is skipped." +msgstr "Ao compactar, usa I<.suf> como sufixo para o arquivo de destino em vez de B<.xz> ou B<.lzma>. Se não estiver gravando na saída padrão e o arquivo de origem já tiver o sufixo I<.suf>, um aviso será exibido e o arquivo será ignorado." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When decompressing, recognize files with the suffix I<.suf> in addition to files with the B<.xz>, B<.txz>, B<.lzma>, B<.tlz>, or B<.lz> suffix. If the source file has the suffix I<.suf>, the suffix is removed to get the target filename." +msgstr "Ao descompactar, reconhece arquivos com o sufixo I<.suf> além de arquivos com o sufixo B<.xz>, B<.txz>, B<.lzma>, B<.tlz> ou B<.lz> . Se o arquivo de origem tiver o sufixo I<.suf>, o sufixo será removido para obter o nome do arquivo de destino." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing or decompressing raw streams (B<--format=raw>), the suffix must always be specified unless writing to standard output, because there is no default suffix for raw streams." +msgstr "Ao compactar ou descompactar fluxos brutos (B<--format=raw>), o sufixo sempre deve ser especificado, a menos que seja gravado na saída padrão, porque não há sufixo padrão para fluxos brutos." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--files>[B<=>I]" +msgstr "B<--files>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Read the filenames to process from I; if I is omitted, filenames are read from standard input. Filenames must be terminated with the newline character. A dash (B<->) is taken as a regular filename; it doesn't mean standard input. If filenames are given also as command line arguments, they are processed before the filenames read from I." +msgstr "Lê os nomes dos arquivos a serem processados em I; se I for omitido, os nomes dos arquivos serão lidos da entrada padrão. Os nomes de arquivo devem terminar com o caractere de nova linha. Um traço (B<->) é considerado um nome de arquivo regular; não significa entrada padrão. Se os nomes de arquivo forem fornecidos também como argumentos de linha de comando, eles serão processados antes da leitura dos nomes de arquivo de I." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--files0>[B<=>I]" +msgstr "B<--files0>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is identical to B<--files>[B<=>I] except that each filename must be terminated with the null character." +msgstr "Isso é idêntico a B<--files>[B<=>I], exceto que cada nome de arquivo deve ser finalizado com o caractere nulo." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Basic file format and compression options" +msgstr "Opções básicas de formato de arquivo e de compactação" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-F> I, B<--format=>I" +msgstr "B<-F> I, B<--format=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the file I to compress or decompress:" +msgstr "Especifica o I de arquivo para compactar ou descompactar:" + +#. TRANSLATORS: Don't translate bold string B. +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is the default. When compressing, B is equivalent to B. When decompressing, the format of the input file is automatically detected. Note that raw streams (created with B<--format=raw>) cannot be auto-detected." +msgstr "Este é o padrão. Ao compactar, B é equivalente a B. Ao descompactar, o formato do arquivo de entrada é detectado automaticamente. Observe que os fluxos brutos (criados com B<--format=raw>) não podem ser detectados automaticamente." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress to the B<.xz> file format, or accept only B<.xz> files when decompressing." +msgstr "Compacta no formato de arquivo B<.xz> ou aceite apenas arquivos B<.xz> ao descompactar." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B, B" +msgstr "B, B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress to the legacy B<.lzma> file format, or accept only B<.lzma> files when decompressing. The alternative name B is provided for backwards compatibility with LZMA Utils." +msgstr "Compacta no formato de arquivo legado B<.lzma> ou aceite apenas arquivos B<.lzma> ao descompactar. O nome alternativo B é fornecido para compatibilidade com versões anteriores do LZMA Utils." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Accept only B<.lz> files when decompressing. Compression is not supported." +msgstr "Aceita apenas arquivos B<.lz> ao descompactar. Sem suporte a compactação." + +#. type: Plain text +#: ../src/xz/xz.1 +#, fuzzy +#| msgid "The B<.lz> format version 0 and the unextended version 1 are supported. Version 0 files were produced by B 1.3 and older. Such files aren't common but may be found from file archives as a few source packages were released in this format. People might have old personal files in this format too. Decompression support for the format version 0 was removed in B 1.18." +msgid "The B<.lz> format versions 0 and 1 are supported. Version 0 files were produced by B 1.3 and older. Such files aren't common but may be found from file archives as a few source packages were released in this format. People might have old personal files in this format too. Decompression support for the format version 0 was removed in B 1.18. B 1.4 and later create files in the format version 1." +msgstr "O formato B<.lz> versão 0 e a versão não estendida 1 são suportados. Os arquivos da versão 0 foram produzidos por B 1.3 e anteriores. Esses arquivos não são comuns, mas podem ser encontrados em arquivos compactados, pois alguns pacotes de origem foram lançados nesse formato. As pessoas também podem ter arquivos pessoais antigos neste formato. O suporte de descompactação para o formato versão 0 foi removido em B 1.18." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress or uncompress a raw stream (no headers). This is meant for advanced users only. To decode raw streams, you need use B<--format=raw> and explicitly specify the filter chain, which normally would have been stored in the container headers." +msgstr "Compacta ou descompacta um fluxo bruto (sem cabeçalhos). Isso é destinado apenas a usuários avançados. Para decodificar fluxos brutos, você precisa usar B<--format=raw> e especificar explicitamente a cadeia de filtros, que normalmente seria armazenada nos cabeçalhos do contêiner." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-C> I, B<--check=>I" +msgstr "B<-C> I, B<--check=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the type of the integrity check. The check is calculated from the uncompressed data and stored in the B<.xz> file. This option has an effect only when compressing into the B<.xz> format; the B<.lzma> format doesn't support integrity checks. The integrity check (if any) is verified when the B<.xz> file is decompressed." +msgstr "Especifica o tipo de verificação de integridade. A verificação é calculada a partir dos dados descompactados e armazenados no arquivo B<.xz>. Esta opção tem efeito somente ao compactar no formato B<.xz>; o formato B<.lzma> não oferece suporte a verificações de integridade. A verificação de integridade (se for o caso) é verificada quando o arquivo B<.xz> é descompactado." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Supported I types:" +msgstr "Tipos de I suportados:" + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, and B. The command line option --check accepts +#. only the untranslated strings. +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Don't calculate an integrity check at all. This is usually a bad idea. This can be useful when integrity of the data is verified by other means anyway." +msgstr "Não calcula uma verificação de integridade. Isso geralmente é uma má ideia. Pode ser útil quando a integridade dos dados é verificada por outros meios." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Calculate CRC32 using the polynomial from IEEE-802.3 (Ethernet)." +msgstr "Calcula CRC32 usando o polinômio do IEEE-802.3 (Ethernet)." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Calculate CRC64 using the polynomial from ECMA-182. This is the default, since it is slightly better than CRC32 at detecting damaged files and the speed difference is negligible." +msgstr "Calcula CRC64 usando o polinômio de ECMA-182. Este é o padrão, pois é um pouco melhor que o CRC32 na detecção de arquivos danificados e a diferença de velocidade é insignificante." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Calculate SHA-256. This is somewhat slower than CRC32 and CRC64." +msgstr "Calcula SHA-256. Isso é um pouco mais lento do que CRC32 e CRC64." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Integrity of the B<.xz> headers is always verified with CRC32. It is not possible to change or disable it." +msgstr "A integridade dos cabeçalhos de B<.xz> é sempre verificada com CRC32. Não é possível alterá-la ou desativá-la." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--ignore-check>" +msgstr "B<--ignore-check>" + +# Enquanto verify=verificar, achei melhor alterar para conferir para evitar excesso de "verificar" e "verificação" -- Rafael +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Don't verify the integrity check of the compressed data when decompressing. The CRC32 values in the B<.xz> headers will still be verified normally." +msgstr "Não confere a verificação de integridade dos dados compactados ao descompactar. Os valores CRC32 nos cabeçalhos B<.xz> ainda serão conferidos normalmente." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B Possible reasons to use this option:" +msgstr "B Possíveis razões para usar esta opção:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Trying to recover data from a corrupt .xz file." +msgstr "Tentativa de recuperar dados de um arquivo .xz corrompido." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Speeding up decompression. This matters mostly with SHA-256 or with files that have compressed extremely well. It's recommended to not use this option for this purpose unless the file integrity is verified externally in some other way." +msgstr "Acelerar a descompactação. Isso é importante principalmente com SHA-256 ou com arquivos extremamente bem compactados. É recomendável não usar essa opção para essa finalidade, a menos que a integridade do arquivo seja verificada externamente de alguma outra forma." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-0> ... B<-9>" +msgstr "B<-0> ... B<-9>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Select a compression preset level. The default is B<-6>. If multiple preset levels are specified, the last one takes effect. If a custom filter chain was already specified, setting a compression preset level clears the custom filter chain." +msgstr "Seleciona um nível de predefinição de compactação. O padrão é B<-6>. Se vários níveis de predefinição forem especificados, o último terá efeito. Se uma cadeia de filtro personalizada já foi especificada, especificar um nível de predefinição de compactação limpa a cadeia de filtro personalizada." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The differences between the presets are more significant than with B(1) and B(1). The selected compression settings determine the memory requirements of the decompressor, thus using a too high preset level might make it painful to decompress the file on an old system with little RAM. Specifically, B like it often is with B(1) and B(1)." +msgstr "As diferenças entre as predefinições são mais significativas do que com B(1) e B(1). As configurações de compactação selecionadas determinam os requisitos de memória do descompactador, portanto, usar um nível de predefinição muito alto pode dificultar a descompactação do arquivo em um sistema antigo com pouca RAM. Especificamente, B como costuma acontecer com B(1) e B(1)." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-0> ... B<-3>" +msgstr "B<-0> ... B<-3>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "These are somewhat fast presets. B<-0> is sometimes faster than B while compressing much better. The higher ones often have speed comparable to B(1) with comparable or better compression ratio, although the results depend a lot on the type of data being compressed." +msgstr "Estas são predefinições um tanto rápidas. B<-0> às vezes é mais rápida que B ao mesmo tempo que compacta muito melhor. As mais altas geralmente têm velocidade comparável ao B(1) com taxa de compactação comparável ou melhor, embora os resultados dependam muito do tipo de dados que estão sendo compactados." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-4> ... B<-6>" +msgstr "B<-4> ... B<-6>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Good to very good compression while keeping decompressor memory usage reasonable even for old systems. B<-6> is the default, which is usually a good choice for distributing files that need to be decompressible even on systems with only 16\\ MiB RAM. (B<-5e> or B<-6e> may be worth considering too. See B<--extreme>.)" +msgstr "Compactação boa a muito boa, mantendo o uso de memória do descompactador razoável mesmo para sistemas antigos. B<-6> é o padrão, que geralmente é uma boa escolha para distribuir arquivos que precisam ser descompactáveis, mesmo em sistemas com apenas 16\\ MiB de RAM. (B<-5e> ou B<-6e> também vale a pena considerar. Veja B<--extreme>.)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-7 ... -9>" +msgstr "B<-7 ... -9>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "These are like B<-6> but with higher compressor and decompressor memory requirements. These are useful only when compressing files bigger than 8\\ MiB, 16\\ MiB, and 32\\ MiB, respectively." +msgstr "Eles são como B<-6>, mas com requisitos de memória de compressor e descompressor mais altos. Eles são úteis apenas ao compactar arquivos maiores que 8\\ MiB, 16\\ MiB e 32\\ MiB, respectivamente." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "On the same hardware, the decompression speed is approximately a constant number of bytes of compressed data per second. In other words, the better the compression, the faster the decompression will usually be. This also means that the amount of uncompressed output produced per second can vary a lot." +msgstr "No mesmo hardware, a velocidade de descompactação é aproximadamente um número constante de bytes de dados compactados por segundo. Em outras palavras, quanto melhor a compactação, mais rápida será a descompactação. Isso também significa que a quantidade de saída não compactada produzida por segundo pode variar muito." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The following table summarises the features of the presets:" +msgstr "A tabela a seguir resume os recursos das predefinições:" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Preset" +msgstr "Predefinição" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "DictSize" +msgstr "DicTam" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "CompCPU" +msgstr "CompCPU" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "CompMem" +msgstr "CompMem" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "DecMem" +msgstr "DecMem" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-0" +msgstr "-0" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "256 KiB" +msgstr "256 KiB" + +#. type: TP +#: ../src/xz/xz.1 ../src/scripts/xzgrep.1 +#, no-wrap +msgid "0" +msgstr "0" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "3 MiB" +msgstr "3 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "1 MiB" +msgstr "1 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-1" +msgstr "-1" + +#. type: TP +#: ../src/xz/xz.1 ../src/scripts/xzgrep.1 +#, no-wrap +msgid "1" +msgstr "1" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "9 MiB" +msgstr "9 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "2 MiB" +msgstr "2 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-2" +msgstr "-2" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "2" +msgstr "2" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "17 MiB" +msgstr "17 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-3" +msgstr "-3" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "4 MiB" +msgstr "4 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "3" +msgstr "3" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "32 MiB" +msgstr "32 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "5 MiB" +msgstr "5 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-4" +msgstr "-4" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "4" +msgstr "4" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "48 MiB" +msgstr "48 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-5" +msgstr "-5" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "8 MiB" +msgstr "8 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "5" +msgstr "5" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "94 MiB" +msgstr "94 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-6" +msgstr "-6" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "6" +msgstr "6" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-7" +msgstr "-7" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "16 MiB" +msgstr "16 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "186 MiB" +msgstr "186 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-8" +msgstr "-8" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "370 MiB" +msgstr "370 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "33 MiB" +msgstr "33 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-9" +msgstr "-9" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "64 MiB" +msgstr "64 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "674 MiB" +msgstr "674 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "65 MiB" +msgstr "65 MiB" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Column descriptions:" +msgstr "Descrições das colunas:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "DictSize is the LZMA2 dictionary size. It is waste of memory to use a dictionary bigger than the size of the uncompressed file. This is why it is good to avoid using the presets B<-7> ... B<-9> when there's no real need for them. At B<-6> and lower, the amount of memory wasted is usually low enough to not matter." +msgstr "DicTam é o tamanho do dicionário LZMA2. É desperdício de memória usar um dicionário maior que o tamanho do arquivo descompactado. É por isso que é bom evitar usar as predefinições B<-7> ... B<-9> quando não há real necessidade deles. Em B<-6> e inferior, a quantidade de memória desperdiçada geralmente é baixa o suficiente para não importar." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "CompCPU is a simplified representation of the LZMA2 settings that affect compression speed. The dictionary size affects speed too, so while CompCPU is the same for levels B<-6> ... B<-9>, higher levels still tend to be a little slower. To get even slower and thus possibly better compression, see B<--extreme>." +msgstr "CompCPU é uma representação simplificada das configurações LZMA2 que afetam a velocidade de compactação. O tamanho do dicionário também afeta a velocidade, portanto, embora o CompCPU seja o mesmo para os níveis B<-6> ... B<-9>, níveis mais altos ainda tendem a ser um pouco mais lentos. Para obter uma compactação ainda mais lenta e possivelmente melhor, consulte B<--extreme>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "CompMem contains the compressor memory requirements in the single-threaded mode. It may vary slightly between B versions." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "DecMem contains the decompressor memory requirements. That is, the compression settings determine the memory requirements of the decompressor. The exact decompressor memory usage is slightly more than the LZMA2 dictionary size, but the values in the table have been rounded up to the next full MiB." +msgstr "DecMem contém os requisitos de memória do descompactador. Ou seja, as configurações de compactação determinam os requisitos de memória do descompactador. O uso exato da memória do descompactador é um pouco maior do que o tamanho do dicionário LZMA2, mas os valores na tabela foram arredondados para o próximo MiB completo." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Memory requirements of the multi-threaded mode are significantly higher than that of the single-threaded mode. With the default value of B<--block-size>, each thread needs 3*3*DictSize plus CompMem or DecMem. For example, four threads with preset B<-6> needs 660\\(en670\\ MiB of memory." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-e>, B<--extreme>" +msgstr "B<-e>, B<--extreme>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Use a slower variant of the selected compression preset level (B<-0> ... B<-9>) to hopefully get a little bit better compression ratio, but with bad luck this can also make it worse. Decompressor memory usage is not affected, but compressor memory usage increases a little at preset levels B<-0> ... B<-3>." +msgstr "Usa uma variante mais lenta do nível de predefinição de compactação selecionado (B<-0> ... B<-9>) para obter uma taxa de compactação um pouco melhor, mas, com azar, isso também pode piorar. O uso da memória do descompressor não é afetado, mas o uso da memória do compactador aumenta um pouco nos níveis de predefinição B<-0> ... B<-3>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Since there are two presets with dictionary sizes 4\\ MiB and 8\\ MiB, the presets B<-3e> and B<-5e> use slightly faster settings (lower CompCPU) than B<-4e> and B<-6e>, respectively. That way no two presets are identical." +msgstr "Como existem duas predefinições com tamanhos de dicionário 4\\ MiB e 8\\ MiB, as predefinições B<-3e> e B<-5e> usam configurações um pouco mais rápidas (CompCPU inferior) do que B<-4e> e B<-6e>, respectivamente. Dessa forma, não há duas predefinições idênticas." + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-0e" +msgstr "-0e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "8" +msgstr "8" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-1e" +msgstr "-1e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "13 MiB" +msgstr "13 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-2e" +msgstr "-2e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "25 MiB" +msgstr "25 MiB" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-3e" +msgstr "-3e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "7" +msgstr "7" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-4e" +msgstr "-4e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-5e" +msgstr "-5e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-6e" +msgstr "-6e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-7e" +msgstr "-7e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-8e" +msgstr "-8e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-9e" +msgstr "-9e" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "For example, there are a total of four presets that use 8\\ MiB dictionary, whose order from the fastest to the slowest is B<-5>, B<-6>, B<-5e>, and B<-6e>." +msgstr "Por exemplo, há um total de quatro predefinições que usam o dicionário 8\\ MiB, cuja ordem do mais rápido ao mais lento é B<-5>, B<-6>, B<-5e> e B<-6e>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--fast>" +msgstr "B<--fast>" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--best>" +msgstr "B<--best>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "These are somewhat misleading aliases for B<-0> and B<-9>, respectively. These are provided only for backwards compatibility with LZMA Utils. Avoid using these options." +msgstr "Esses são apelidos um tanto enganosos para B<-0> e B<-9>, respectivamente. Eles são fornecidos apenas para compatibilidade com versões anteriores do LZMA Utils. Evite usar essas opções." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--block-size=>I" +msgstr "B<--block-size=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing to the B<.xz> format, split the input data into blocks of I bytes. The blocks are compressed independently from each other, which helps with multi-threading and makes limited random-access decompression possible. This option is typically used to override the default block size in multi-threaded mode, but this option can be used in single-threaded mode too." +msgstr "Ao compactar para o formato B<.xz>, divida os dados de entrada em blocos de I bytes. Os blocos são compactados independentemente uns dos outros, o que ajuda no multi-threading e torna possível a descompactação limitada de acesso aleatório. Essa opção normalmente é usada para substituir o tamanho de bloco padrão no modo multi-thread, mas também pode ser usada em thread única." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In multi-threaded mode about three times I bytes will be allocated in each thread for buffering input and output. The default I is three times the LZMA2 dictionary size or 1 MiB, whichever is more. Typically a good value is 2\\(en4 times the size of the LZMA2 dictionary or at least 1 MiB. Using I less than the LZMA2 dictionary size is waste of RAM because then the LZMA2 dictionary buffer will never get fully used. In multi-threaded mode, the sizes of the blocks are stored in the block headers. This size information is required for multi-threaded decompression." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In single-threaded mode no block splitting is done by default. Setting this option doesn't affect memory usage. No size information is stored in block headers, thus files created in single-threaded mode won't be identical to files created in multi-threaded mode. The lack of size information also means that B won't be able decompress the files in multi-threaded mode." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, fuzzy, no-wrap +#| msgid "B<--block-size=>I" +msgid "B<--block-list=>I" +msgstr "B<--block-size=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing to the B<.xz> format, start a new block with an optional custom filter chain after the given intervals of uncompressed data." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I are a comma-separated list. Each item consists of an optional filter chain number between 0 and 9 followed by a colon (B<:>) and a required size of uncompressed data. Omitting an item (two or more consecutive commas) is a shorthand to use the size and filters of the previous item." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the input file is bigger than the sum of the sizes in I, the last item is repeated until the end of the file. A special value of B<0> may be used as the last size to indicate that the rest of the file should be encoded as a single block." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "An alternative filter chain for each block can be specified in combination with the B<--filters1=>I \\&...\\& B<--filters9=>I options. These options define filter chains with an identifier between 1\\(en9. Filter chain 0 can be used to refer to the default filter chain, which is the same as not specifying a filter chain. The filter chain identifier can be used before the uncompressed size, followed by a colon (B<:>). For example, if one specifies B<--block-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB> then blocks will be created using:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The filter chain specified by B<--filters1> and 2 MiB input" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The filter chain specified by B<--filters3> and 2 MiB input" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The filter chain specified by B<--filters2> and 4 MiB input" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default filter chain and 2 MiB input" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default filter chain and 4 MiB input for every block until end of input." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If one specifies a size that exceeds the encoder's block size (either the default value in threaded mode or the value specified with B<--block-size=>I), the encoder will create additional blocks while keeping the boundaries specified in I. For example, if one specifies B<--block-size=10MiB> B<--block-list=5MiB,10MiB,8MiB,12MiB,24MiB> and the input file is 80 MiB, one will get 11 blocks: 5, 10, 8, 10, 2, 10, 10, 4, 10, 10, and 1 MiB." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In multi-threaded mode the sizes of the blocks are stored in the block headers. This isn't done in single-threaded mode, so the encoded output won't be identical to that of the multi-threaded mode." +msgstr "No modo multi-thread, os tamanhos dos blocos são armazenados nos cabeçalhos dos blocos. Isso não é feito no modo de thread única, portanto, a saída codificada não será idêntica à do modo multi-thread." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--flush-timeout=>I" +msgstr "B<--flush-timeout=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing, if more than I milliseconds (a positive integer) has passed since the previous flush and reading more input would block, all the pending input data is flushed from the encoder and made available in the output stream. This can be useful if B is used to compress data that is streamed over a network. Small I values make the data available at the receiving end with a small delay, but large I values give better compression ratio." +msgstr "Ao compactar, se mais de I milissegundos (um número inteiro positivo) se passaram desde a liberação anterior e a leitura de mais entrada seria bloqueada, todos os dados de entrada pendentes serão liberados do codificador e disponibilizados no fluxo de saída. Isso pode ser útil se B for usado para compactar dados transmitidos por uma rede. Valores I pequenos tornam os dados disponíveis na extremidade receptora com um pequeno atraso, mas valores I grandes oferecem melhor taxa de compactação." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This feature is disabled by default. If this option is specified more than once, the last one takes effect. The special I value of B<0> can be used to explicitly disable this feature." +msgstr "Esse recurso está desabilitado por padrão. Se esta opção for especificada mais de uma vez, a última terá efeito. O valor especial I de B<0> pode ser usado para desabilitar explicitamente esse recurso." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This feature is not available on non-POSIX systems." +msgstr "Este recurso não está disponível em sistemas não-POSIX." + +#. FIXME +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B Currently B is unsuitable for decompressing the stream in real time due to how B does buffering." +msgstr "B Atualmente, B não é adequado para descompactar o fluxo em tempo real devido à forma como B faz o buffer." + +#. type: TP +#: ../src/xz/xz.1 +#, fuzzy, no-wrap +#| msgid "B<--no-sparse>" +msgid "B<--no-sync>" +msgstr "B<--no-sparse>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Do not synchronize the target file and its directory to the storage device before removing the source file. This can improve performance if compressing or decompressing many small files. However, if the system crashes soon after the deletion, it is possible that the target file was not written to the storage device but the delete operation was. In that case neither the original source file nor the target file is available." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This option has an effect only when B is going to remove the source file. In other cases synchronization is never done." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The synchronization and B<--no-sync> were added in B 5.7.1alpha." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--memlimit-compress=>I" +msgstr "B<--memlimit-compress=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Set a memory usage limit for compression. If this option is specified multiple times, the last one takes effect." +msgstr "Define um limite de uso de memória para compactação. Se esta opção for especificada várias vezes, a última entrará em vigor." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the compression settings exceed the I, B will attempt to adjust the settings downwards so that the limit is no longer exceeded and display a notice that automatic adjustment was done. The adjustments are done in this order: reducing the number of threads, switching to single-threaded mode if even one thread in multi-threaded mode exceeds the I, and finally reducing the LZMA2 dictionary size." +msgstr "Se as configurações de compactação excederem o I, B tentará ajustar as configurações para baixo para que o limite não seja mais excedido e exibirá um aviso de que o ajuste automático foi feito. Os ajustes são feitos nesta ordem: reduzindo o número de encadeamentos, alternando para o modo sigle-thread se até mesmo uma thread no modo multi-thread exceder o I e, finalmente, reduzindo o tamanho do dicionário LZMA2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing with B<--format=raw> or if B<--no-adjust> has been specified, only the number of threads may be reduced since it can be done without affecting the compressed output." +msgstr "Ao compactar com B<--format=raw> ou se B<--no-adjust> tiver sido especificado, apenas o número de threads pode ser reduzido, pois isso pode ser feito sem afetar a saída compactada." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the I cannot be met even with the adjustments described above, an error is displayed and B will exit with exit status 1." +msgstr "Se o I não puder ser alcançado mesmo com os ajustes descritos acima, um erro será exibido e B sairá com status de saída 1." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I can be specified in multiple ways:" +msgstr "O I pode ser especificado de várias maneiras:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I can be an absolute value in bytes. Using an integer suffix like B can be useful. Example: B<--memlimit-compress=80MiB>" +msgstr "O I pode ser um valor absoluto em bytes. Usar um sufixo inteiro como B pode ser útil. Exemplo: B<--memlimit-compress=80MiB>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I can be specified as a percentage of total physical memory (RAM). This can be useful especially when setting the B environment variable in a shell initialization script that is shared between different computers. That way the limit is automatically bigger on systems with more memory. Example: B<--memlimit-compress=70%>" +msgstr "O I pode ser especificado como uma porcentagem da memória física total (RAM). Isso pode ser útil especialmente ao definir a variável de ambiente B em um script de inicialização de shell que é compartilhado entre diferentes computadores. Dessa forma o limite é automaticamente maior em sistemas com mais memória. Exemplo: B<--memlimit-compress=70%>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I can be reset back to its default value by setting it to B<0>. This is currently equivalent to setting the I to B (no memory usage limit)." +msgstr "O I pode ser redefinido para seu valor padrão, definindo-o como B<0>. Atualmente, isso equivale a definir I como B (sem limite de uso de memória)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "For 32-bit B there is a special case: if the I would be over B<4020\\ MiB>, the I is set to B<4020\\ MiB>. On MIPS32 B<2000\\ MiB> is used instead. (The values B<0> and B aren't affected by this. A similar feature doesn't exist for decompression.) This can be helpful when a 32-bit executable has access to 4\\ GiB address space (2 GiB on MIPS32) while hopefully doing no harm in other situations." +msgstr "Para B de 32 bits, há um caso especial: se o I estiver acima de B<4020\\ MiB>, o I é definido como B<4020\\ MiB>. No MIPS32 B<2000\\ MiB> é usado em seu lugar. (Os valores B<0> e B não são afetados por isso. Um recurso semelhante não existe para descompactação.) Isso pode ser útil quando um executável de 32 bits tem acesso a espaço de endereço de 4\\ GiB (2 GiB no MIPS32) enquanto espero não causar danos em outras situações." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "See also the section B." +msgstr "Consulte também a seção B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--memlimit-decompress=>I" +msgstr "B<--memlimit-decompress=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Set a memory usage limit for decompression. This also affects the B<--list> mode. If the operation is not possible without exceeding the I, B will display an error and decompressing the file will fail. See B<--memlimit-compress=>I for possible ways to specify the I." +msgstr "Define um limite de uso de memória para descompactação. Isso também afeta o modo B<--list>. Se a operação não for possível sem exceder o I, B exibirá um erro e a descompactação do arquivo falhará. Consulte B<--memlimit-compress=>I para possíveis maneiras de especificar o I." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--memlimit-mt-decompress=>I" +msgstr "B<--memlimit-mt-decompress=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Set a memory usage limit for multi-threaded decompression. This can only affect the number of threads; this will never make B refuse to decompress a file. If I is too low to allow any multi-threading, the I is ignored and B will continue in single-threaded mode. Note that if also B<--memlimit-decompress> is used, it will always apply to both single-threaded and multi-threaded modes, and so the effective I for multi-threading will never be higher than the limit set with B<--memlimit-decompress>." +msgstr "Define um limite de uso de memória para descompactação multi-thread. Isso pode afetar apenas o número de threads; isso nunca fará com que B se recuse a descompactar um arquivo. Se I for muito baixo para permitir qualquer multi-thread, o I será ignorado e B continuará no modo de thread única. Observe que se B<--memlimit-decompress> também for usado, ele sempre se aplicará aos modos de thread única e multi-thread e, portanto, o I efetivo para multi-threading nunca será maior que o limite definido com B<--memlimit-decompress>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In contrast to the other memory usage limit options, B<--memlimit-mt-decompress=>I has a system-specific default I. B can be used to see the current value." +msgstr "Em contraste com as outras opções de limite de uso de memória, B<--memlimit-mt-decompress=>I tem um padrão I específico do sistema. B pode ser usado para ver o valor atual." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This option and its default value exist because without any limit the threaded decompressor could end up allocating an insane amount of memory with some input files. If the default I is too low on your system, feel free to increase the I but never set it to a value larger than the amount of usable RAM as with appropriate input files B will attempt to use that amount of memory even with a low number of threads. Running out of memory or swapping will not improve decompression performance." +msgstr "Esta opção e seu valor padrão existem porque, sem qualquer limite, o descompactador usando threads pode acabar alocando uma quantidade insana de memória com alguns arquivos de entrada. Se o I padrão for muito baixo em seu sistema, sinta-se à vontade para aumentar o I, mas nunca defina-o para um valor maior que a quantidade de RAM utilizável, pois com os arquivos de entrada apropriados B tentará usar essa quantidade de memória mesmo com um baixo número de threads. Ficar sem memória ou trocar não melhorará o desempenho da descompactação." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "See B<--memlimit-compress=>I for possible ways to specify the I. Setting I to B<0> resets the I to the default system-specific value." +msgstr "Consulte B<--memlimit-compress=>I para possíveis maneiras de especificar o I. Definir I como B<0> redefine I para o valor padrão específico do sistema." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-M> I, B<--memlimit=>I, B<--memory=>I" +msgstr "B<-M> I, B<--memlimit=>I, B<--memory=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is equivalent to specifying B<--memlimit-compress=>I B<--memlimit-decompress=>I B<--memlimit-mt-decompress=>I." +msgstr "Isso é equivalente a especificar B<--memlimit-compress=>I B<--memlimit-decompress=>I B<--memlimit-mt-decompress=>I." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--no-adjust>" +msgstr "B<--no-adjust>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display an error and exit if the memory usage limit cannot be met without adjusting settings that affect the compressed output. That is, this prevents B from switching the encoder from multi-threaded mode to single-threaded mode and from reducing the LZMA2 dictionary size. Even when this option is used the number of threads may be reduced to meet the memory usage limit as that won't affect the compressed output." +msgstr "Exibe um erro e saia se o limite de uso de memória não puder ser atendido sem ajustar as configurações que afetam a saída compactada. Ou seja, isso evita que B alterne o codificador do modo multi-thread para o modo encadeado único e reduza o tamanho do dicionário LZMA2. Mesmo quando esta opção é usada, o número de threads pode ser reduzido para atender ao limite de uso de memória, pois isso não afetará a saída compactada." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Automatic adjusting is always disabled when creating raw streams (B<--format=raw>)." +msgstr "O ajuste automático é sempre desativado ao criar fluxos brutos (B<--format=raw>)." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-T> I, B<--threads=>I" +msgstr "B<-T> I, B<--threads=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the number of worker threads to use. Setting I to a special value B<0> makes B use up to as many threads as the processor(s) on the system support. The actual number of threads can be fewer than I if the input file is not big enough for threading with the given settings or if using more threads would exceed the memory usage limit." +msgstr "Especifica o número de threads de trabalho a serem usados. Definir I para um valor especial B<0> faz com que B use tantos threads quanto o(s) processador(es) no suporte do sistema. O número real de encadeamentos pode ser menor que I se o arquivo de entrada não for grande o suficiente para subdividir em threads com as configurações fornecidas ou se o uso de mais threads exceder o limite de uso de memória." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The single-threaded and multi-threaded compressors produce different output. Single-threaded compressor will give the smallest file size but only the output from the multi-threaded compressor can be decompressed using multiple threads. Setting I to B<1> will use the single-threaded mode. Setting I to any other value, including B<0>, will use the multi-threaded compressor even if the system supports only one hardware thread. (B 5.2.x used single-threaded mode in this situation.)" +msgstr "Os compactadores usando thread única e várias threads produzem saídas diferentes. O compactador de thread única fornecerá o menor tamanho de arquivo, mas apenas a saída do compactador de várias threads pode ser descompactada usando várias threads. Definir I como B<1> usará o modo de thread única. Definir I para qualquer outro valor, incluindo B<0>, usará o compressor de várias threads, mesmo que o sistema tenha suporte a apenas uma thread de hardware. (B 5.2.x usou o modo de thread única nesta situação.)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "To use multi-threaded mode with only one thread, set I to B<+1>. The B<+> prefix has no effect with values other than B<1>. A memory usage limit can still make B switch to single-threaded mode unless B<--no-adjust> is used. Support for the B<+> prefix was added in B 5.4.0." +msgstr "Para usar o modo de várias threads com apenas uma thread, defina I como B<+1>. O prefixo B<+> não tem efeito com valores diferentes de B<1>. Um limite de uso de memória ainda pode fazer B alternar para o modo de thread única, a menos que B<--no-adjust> seja usado. O suporte para o prefixo B<+> foi adicionado no B 5.4.0." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If an automatic number of threads has been requested and no memory usage limit has been specified, then a system-specific default soft limit will be used to possibly limit the number of threads. It is a soft limit in sense that it is ignored if the number of threads becomes one, thus a soft limit will never stop B from compressing or decompressing. This default soft limit will not make B switch from multi-threaded mode to single-threaded mode. The active limits can be seen with B." +msgstr "Se um número automático de threads foi solicitado e nenhum limite de uso de memória foi especificado, um limite flexível padrão específico do sistema será usado para possivelmente limitar o número de threads. É um limite flexível no sentido de que é ignorado se o número de threads se tornar um, portanto, um limite flexível nunca impedirá B de compactar ou descompactar. Este limite flexível padrão não fará com que B alterne do modo de várias threads para o modo de thread única. Os limites ativos podem ser vistos com B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Currently the only threading method is to split the input into blocks and compress them independently from each other. The default block size depends on the compression level and can be overridden with the B<--block-size=>I option." +msgstr "Atualmente, o único método de threading é dividir a entrada em blocos e comprimi-los independentemente um do outro. O tamanho padrão do bloco depende do nível de compactação e pode ser substituído com a opção B<--block-size=>I." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Threaded decompression only works on files that contain multiple blocks with size information in block headers. All large enough files compressed in multi-threaded mode meet this condition, but files compressed in single-threaded mode don't even if B<--block-size=>I has been used." +msgstr "A descompactação em threads funciona apenas em arquivos que contêm vários blocos com informações de tamanho nos cabeçalhos dos blocos. Todos os arquivos grandes o suficiente compactados no modo de várias thread atendem a essa condição, mas os arquivos compactados no modo de thread única não atendem, mesmo se B<--block-size=>I tiver sido usado." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default value for I is B<0>. In B 5.4.x and older the default is B<1>." +msgstr "" + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Custom compressor filter chains" +msgstr "Cadeias de filtro de compressor personalizadas" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "A custom filter chain allows specifying the compression settings in detail instead of relying on the settings associated to the presets. When a custom filter chain is specified, preset options (B<-0> \\&...\\& B<-9> and B<--extreme>) earlier on the command line are forgotten. If a preset option is specified after one or more custom filter chain options, the new preset takes effect and the custom filter chain options specified earlier are forgotten." +msgstr "Uma cadeia de filtro personalizada permite especificar as configurações de compactação em detalhes, em vez de confiar nas configurações associadas às predefinições. Quando uma cadeia de filtro personalizada é especificada, as opções predefinidas (B<-0> \\&...\\& B<-9> e B<--extreme>) anteriores na linha de comando são esquecidas. Se uma opção predefinida for especificada após uma ou mais opções de cadeia de filtros personalizados, a nova predefinição entrará em vigor e as opções de cadeia de filtros personalizados especificadas anteriormente serão esquecidas." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "A filter chain is comparable to piping on the command line. When compressing, the uncompressed input goes to the first filter, whose output goes to the next filter (if any). The output of the last filter gets written to the compressed file. The maximum number of filters in the chain is four, but typically a filter chain has only one or two filters." +msgstr "Uma cadeia de filtro é comparável à tubulação na linha de comando. Ao compactar, a entrada descompactada vai para o primeiro filtro, cuja saída vai para o próximo filtro (se houver). A saída do último filtro é gravada no arquivo compactado. O número máximo de filtros na cadeia é quatro, mas normalmente uma cadeia de filtros tem apenas um ou dois filtros." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Many filters have limitations on where they can be in the filter chain: some filters can work only as the last filter in the chain, some only as a non-last filter, and some work in any position in the chain. Depending on the filter, this limitation is either inherent to the filter design or exists to prevent security issues." +msgstr "Muitos filtros têm limitações sobre onde podem estar na cadeia de filtros: alguns filtros podem funcionar apenas como o último filtro na cadeia, alguns apenas como filtro não-último e alguns funcionam em qualquer posição na cadeia. Dependendo do filtro, essa limitação é inerente ao projeto do filtro ou existe para evitar problemas de segurança." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "A custom filter chain can be specified in two different ways. The options B<--filters=>I and B<--filters1=>I \\&...\\& B<--filters9=>I allow specifying an entire filter chain in one option using the liblzma filter string syntax. Alternatively, a filter chain can be specified by using one or more individual filter options in the order they are wanted in the filter chain. That is, the order of the individual filter options is significant! When decoding raw streams (B<--format=raw>), the filter chain must be specified in the same order as it was specified when compressing. Any individual filter or preset options specified before the full chain option (B<--filters=>I) will be forgotten. Individual filters specified after the full chain option will reset the filter chain." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Both the full and individual filter options take filter-specific I as a comma-separated list. Extra commas in I are ignored. Every option has a default value, so specify those you want to change." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "To see the whole filter chain and I, use B (that is, use B<--verbose> twice). This works also for viewing the filter chain options used by presets." +msgstr "Para ver toda a cadeia de filtros e I, use B (isto é, use B<--verbose> duas vezes). Isso também funciona para visualizar as opções da cadeia de filtros usadas pelas predefinições." + +#. type: TP +#: ../src/xz/xz.1 +#, fuzzy, no-wrap +#| msgid "B<--files>[B<=>I]" +msgid "B<--filters=>I" +msgstr "B<--files>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the full filter chain or a preset in a single option. Each filter can be separated by spaces or two dashes (B<-->). I may need to be quoted on the shell command line so it is parsed as a single option. To denote I, use B<:> or B<=>. A preset can be prefixed with a B<-> and followed with zero or more flags. The only supported flag is B to apply the same options as B<--extreme>." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--filters1>=I ... B<--filters9>=I" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify up to nine additional filter chains that can be used with B<--block-list>." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "For example, when compressing an archive with executable files followed by text files, the executable part could use a filter chain with a BCJ filter and the text part only the LZMA2 filter." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, fuzzy, no-wrap +#| msgid "B<-h>, B<--help>" +msgid "B<--filters-help>" +msgstr "B<-h>, B<--help>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display a help message describing how to specify presets and custom filter chains in the B<--filters> and B<--filters1=>I \\&...\\& B<--filters9=>I options, and exit successfully." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--lzma1>[B<=>I]" +msgstr "B<--lzma1>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--lzma2>[B<=>I]" +msgstr "B<--lzma2>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Add LZMA1 or LZMA2 filter to the filter chain. These filters can be used only as the last filter in the chain." +msgstr "Adiciona o filtro LZMA1 ou LZMA2 à cadeia de filtros. Esses filtros podem ser usados apenas como o último filtro na cadeia." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "LZMA1 is a legacy filter, which is supported almost solely due to the legacy B<.lzma> file format, which supports only LZMA1. LZMA2 is an updated version of LZMA1 to fix some practical issues of LZMA1. The B<.xz> format uses LZMA2 and doesn't support LZMA1 at all. Compression speed and ratios of LZMA1 and LZMA2 are practically the same." +msgstr "LZMA1 é um filtro legado, que é suportado quase exclusivamente devido ao formato de arquivo legado B<.lzma>, que suporta apenas LZMA1. LZMA2 é uma versão atualizada do LZMA1 para corrigir alguns problemas práticos do LZMA1. O formato B<.xz> usa LZMA2 e não suporta LZMA1. A velocidade de compactação e as proporções de LZMA1 e LZMA2 são praticamente as mesmas." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "LZMA1 and LZMA2 share the same set of I:" +msgstr "LZMA1 e LZMA2 compartilham o mesmo conjunto de I:" + +#. TRANSLATORS: Don't translate bold strings like B, B, +#. B, B, B, or B because those are command line +#. options. On the other hand, do translate the italic strings like +#. I, I, and I, because such italic strings are +#. placeholders which a user replaces with an actual value. +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Reset all LZMA1 or LZMA2 I to I. I consist of an integer, which may be followed by single-letter preset modifiers. The integer can be from B<0> to B<9>, matching the command line options B<-0> \\&...\\& B<-9>. The only supported modifier is currently B, which matches B<--extreme>. If no B is specified, the default values of LZMA1 or LZMA2 I are taken from the preset B<6>." +msgstr "Redefine todas as I de LZMA1 ou LZMA2 para I. I consiste em um número inteiro, que pode ser seguido por modificadores de predefinição de uma única letra. O inteiro pode ser de B<0> a B<9>, correspondendo às opções de linha de comando B<-0> \\&...\\& B<-9>. O único modificador suportado atualmente é B, que corresponde a B<--extreme>. Se nenhum B for especificado, os valores padrão das I LZMA1 ou LZMA2 serão obtidos da predefinição B<6>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Dictionary (history buffer) I indicates how many bytes of the recently processed uncompressed data is kept in memory. The algorithm tries to find repeating byte sequences (matches) in the uncompressed data, and replace them with references to the data currently in the dictionary. The bigger the dictionary, the higher is the chance to find a match. Thus, increasing dictionary I usually improves compression ratio, but a dictionary bigger than the uncompressed file is waste of memory." +msgstr "O I do dicionário (buffer de histórico) indica quantos bytes dos dados não compactados processados recentemente são mantidos na memória. O algoritmo tenta encontrar sequências de bytes repetidos (correspondências) nos dados não compactados e substituí-los por referências aos dados atualmente no dicionário. Quanto maior o dicionário, maior a chance de encontrar uma correspondência. Portanto, aumentar o dicionário I geralmente melhora a taxa de compactação, mas um dicionário maior que o arquivo não compactado é um desperdício de memória." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Typical dictionary I is from 64\\ KiB to 64\\ MiB. The minimum is 4\\ KiB. The maximum for compression is currently 1.5\\ GiB (1536\\ MiB). The decompressor already supports dictionaries up to one byte less than 4\\ GiB, which is the maximum for the LZMA1 and LZMA2 stream formats." +msgstr "Um I de dicionário típico é de 64\\ KiB a 64\\ MiB. O mínimo é 4\\ KiB. O máximo para compactação é atualmente 1,5\\ GiB (1536\\ MiB). O descompactador já oferece suporte a dicionários de até um byte a menos de 4\\ GiB, que é o máximo para os formatos de fluxo LZMA1 e LZMA2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Dictionary I and match finder (I) together determine the memory usage of the LZMA1 or LZMA2 encoder. The same (or bigger) dictionary I is required for decompressing that was used when compressing, thus the memory usage of the decoder is determined by the dictionary size used when compressing. The B<.xz> headers store the dictionary I either as 2^I or 2^I + 2^(I-1), so these I are somewhat preferred for compression. Other I will get rounded up when stored in the B<.xz> headers." +msgstr "O I de dicionário e o localizador de correspondência (I) juntos determinam o uso de memória do codificador LZMA1 ou LZMA2. O mesmo (ou maior) I de dicionário é necessário para descompactar que foi usado durante a compactação, portanto, o uso de memória do decodificador é determinado pelo tamanho do dicionário usado durante a compactação. Os cabeçalhos B<.xz> armazenam o I de dicionário como 2^I ou 2^I + 2^(I-1), então esses I são um tanto preferidos para compactação. Outros I serão arredondados quando armazenados nos cabeçalhos B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the number of literal context bits. The minimum is 0 and the maximum is 4; the default is 3. In addition, the sum of I and I must not exceed 4." +msgstr "Especifica o número de bits de contexto literais. O mínimo é 0 e o máximo é 4; o padrão é 3. Além disso, a soma de I e I não deve exceder 4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "All bytes that cannot be encoded as matches are encoded as literals. That is, literals are simply 8-bit bytes that are encoded one at a time." +msgstr "Todos os bytes que não podem ser codificados como correspondências são codificados como literais. Ou seja, literais são simplesmente bytes de 8 bits que são codificados um de cada vez." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The literal coding makes an assumption that the highest I bits of the previous uncompressed byte correlate with the next byte. For example, in typical English text, an upper-case letter is often followed by a lower-case letter, and a lower-case letter is usually followed by another lower-case letter. In the US-ASCII character set, the highest three bits are 010 for upper-case letters and 011 for lower-case letters. When I is at least 3, the literal coding can take advantage of this property in the uncompressed data." +msgstr "A codificação literal assume que os bits I mais altos do byte não compactado anterior se correlacionam com o próximo byte. Por exemplo, em um texto típico em inglês, uma letra maiúscula geralmente é seguida por uma letra minúscula, e uma letra minúscula geralmente é seguida por outra letra minúscula. No conjunto de caracteres US-ASCII, os três bits mais altos são 010 para letras maiúsculas e 011 para letras minúsculas. Quando I é pelo menos 3, a codificação literal pode aproveitar essa propriedade nos dados não compactados." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default value (3) is usually good. If you want maximum compression, test B. Sometimes it helps a little, and sometimes it makes compression worse. If it makes it worse, test B too." +msgstr "O valor padrão (3) geralmente é bom. Se você deseja compactação máxima, experimente B. Às vezes ajuda um pouco, às vezes piora a compactação. Se piorar, experimente B também." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the number of literal position bits. The minimum is 0 and the maximum is 4; the default is 0." +msgstr "Especifica o número de bits de posição literal. O mínimo é 0 e o máximo é 4; o padrão é 0." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I affects what kind of alignment in the uncompressed data is assumed when encoding literals. See I below for more information about alignment." +msgstr "I afeta que tipo de alinhamento nos dados não compactados é assumido ao codificar literais. Consulte I abaixo para obter mais informações sobre alinhamento." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the number of position bits. The minimum is 0 and the maximum is 4; the default is 2." +msgstr "Especifica o número de bits de posição. O mínimo é 0 e o máximo é 4; o padrão é 2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I affects what kind of alignment in the uncompressed data is assumed in general. The default means four-byte alignment (2^I=2^2=4), which is often a good choice when there's no better guess." +msgstr "I afeta que tipo de alinhamento nos dados não compactados é assumido em geral. O padrão significa alinhamento de quatro bytes (2^I=2^2=4), que geralmente é uma boa escolha quando não há melhor estimativa." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When the alignment is known, setting I accordingly may reduce the file size a little. For example, with text files having one-byte alignment (US-ASCII, ISO-8859-*, UTF-8), setting B can improve compression slightly. For UTF-16 text, B is a good choice. If the alignment is an odd number like 3 bytes, B might be the best choice." +msgstr "Quando o alinhamento é conhecido, definir I adequadamente pode reduzir um pouco o tamanho do arquivo. Por exemplo, com arquivos de texto com alinhamento de um byte (US-ASCII, ISO-8859-*, UTF-8), a configuração B pode melhorar um pouco a compactação. Para texto UTF-16, B é uma boa escolha. Se o alinhamento for um número ímpar como 3 bytes, B pode ser a melhor escolha." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Even though the assumed alignment can be adjusted with I and I, LZMA1 and LZMA2 still slightly favor 16-byte alignment. It might be worth taking into account when designing file formats that are likely to be often compressed with LZMA1 or LZMA2." +msgstr "Embora o alinhamento assumido possa ser ajustado com I e I, LZMA1 e LZMA2 ainda favorecem ligeiramente o alinhamento de 16 bytes. Pode valer a pena levar em consideração ao projetar formatos de arquivo que provavelmente serão compactados com LZMA1 ou LZMA2." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Match finder has a major effect on encoder speed, memory usage, and compression ratio. Usually Hash Chain match finders are faster than Binary Tree match finders. The default depends on the I: 0 uses B, 1\\(en3 use B, and the rest use B." +msgstr "O localizador de correspondência tem um efeito importante na velocidade do codificador, uso de memória e taxa de compactação. Normalmente, os localizadores de correspondência de Hash Chain são mais rápidos do que os localizadores de correspondência de árvore binária. O padrão depende do I: 0 usa B, 1\\(en3 usa B e o resto usa B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The following match finders are supported. The memory usage formulas below are rough approximations, which are closest to the reality when I is a power of two." +msgstr "Os seguintes localizadores de correspondência são suportados. As fórmulas de uso de memória abaixo são aproximações aproximadas, que estão mais próximas da realidade quando I é uma potência de dois." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Hash Chain with 2- and 3-byte hashing" +msgstr "Cadeia de hashs com hashing de 2 e 3 bytes" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum value for I: 3" +msgstr "Valor mínimo para I: 3" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Memory usage:" +msgstr "Uso de memória:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 7.5 (if I E= 16 MiB);" +msgstr "I * 7.5 (if I E= 16 MiB);" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 5.5 + 64 MiB (if I E 16 MiB)" +msgstr "I * 5.5 + 64 MiB (if I E 16 MiB)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Hash Chain with 2-, 3-, and 4-byte hashing" +msgstr "Cadeia de hashs com hashing de 2, 3 e 4 bytes" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum value for I: 4" +msgstr "Valor mínimo para I: 4" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 7.5 (if I E= 32 MiB);" +msgstr "I * 7.5 (if I E= 32 MiB);" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 6.5 (if I E 32 MiB)" +msgstr "I * 6.5 (if I E 32 MiB)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Binary Tree with 2-byte hashing" +msgstr "Ãrvore binária com hashing de 2 bytes" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum value for I: 2" +msgstr "Valor mínimo para I: 2" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Memory usage: I * 9.5" +msgstr "Uso de memória: I * 9.5" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Binary Tree with 2- and 3-byte hashing" +msgstr "Ãrvore binária com hashing de 2 e 3 bytes" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 11.5 (if I E= 16 MiB);" +msgstr "I * 11.5 (if I E= 16 MiB);" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 9.5 + 64 MiB (if I E 16 MiB)" +msgstr "I * 9.5 + 64 MiB (if I E 16 MiB)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Binary Tree with 2-, 3-, and 4-byte hashing" +msgstr "Ãrvore binária com hashing de 2, 3 e 4 bytes" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 11.5 (if I E= 32 MiB);" +msgstr "I * 11.5 (if I E= 32 MiB);" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 10.5 (if I E 32 MiB)" +msgstr "I * 10.5 (if I E 32 MiB)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression I specifies the method to analyze the data produced by the match finder. Supported I are B and B. The default is B for I 0\\(en3 and B for I 4\\(en9." +msgstr "O I de compactação especifica o método para analisar os dados produzidos pelo localizador de correspondência. Os I suportados são B e B. O padrão é B para I 0\\(en3 e B para I 4\\(en9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Usually B is used with Hash Chain match finders and B with Binary Tree match finders. This is also what the I do." +msgstr "Normalmente, B é usado com localizadores de correspondência cadeia de hashs e B com localizadores de correspondência de árvore binária. Isso também é o que os I fazem." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify what is considered to be a nice length for a match. Once a match of at least I bytes is found, the algorithm stops looking for possibly better matches." +msgstr "Especifica o que é considerado um bom comprimento para uma correspondência. Uma vez que uma correspondência de pelo menos I bytes é encontrada, o algoritmo para de procurar correspondências possivelmente melhores." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I can be 2\\(en273 bytes. Higher values tend to give better compression ratio at the expense of speed. The default depends on the I." +msgstr "I pode ser 2\\(en273 bytes. Valores mais altos tendem a fornecer melhor taxa de compactação em detrimento da velocidade. O padrão depende do I." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the maximum search depth in the match finder. The default is the special value of 0, which makes the compressor determine a reasonable I from I and I." +msgstr "Especifica a profundidade máxima de pesquisa no localizador de correspondências. O padrão é o valor especial de 0, que faz com que o compressor determine um I razoável de I e I." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Reasonable I for Hash Chains is 4\\(en100 and 16\\(en1000 for Binary Trees. Using very high values for I can make the encoder extremely slow with some files. Avoid setting the I over 1000 unless you are prepared to interrupt the compression in case it is taking far too long." +msgstr "Uma I razoável para cadeias de hash é 4\\(en100 e 16\\(en1000 para árvores binárias. Usar valores muito altos para I pode tornar o codificador extremamente lento com alguns arquivos. Evite definir I acima de 1000 a menos que você esteja preparado para interromper a compactação caso ela esteja demorando muito." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When decoding raw streams (B<--format=raw>), LZMA2 needs only the dictionary I. LZMA1 needs also I, I, and I." +msgstr "Ao decodificar fluxos brutos (B<--format=raw>), o LZMA2 precisa apenas do dicionário I. LZMA1 também precisa de I, I e I." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--x86>[B<=>I]" +msgstr "B<--x86>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--arm>[B<=>I]" +msgstr "B<--arm>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--armthumb>[B<=>I]" +msgstr "B<--armthumb>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--arm64>[B<=>I]" +msgstr "B<--arm64>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--powerpc>[B<=>I]" +msgstr "B<--powerpc>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--ia64>[B<=>I]" +msgstr "B<--ia64>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--sparc>[B<=>I]" +msgstr "B<--sparc>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--riscv>[B<=>I]" +msgstr "B<--riscv>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Add a branch/call/jump (BCJ) filter to the filter chain. These filters can be used only as a non-last filter in the filter chain." +msgstr "Adiciona um filtro de ramificação/chamada/salto (BCJ) à cadeia de filtros. Esses filtros podem ser usados apenas como um filtro não último na cadeia de filtros." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "A BCJ filter converts relative addresses in the machine code to their absolute counterparts. This doesn't change the size of the data but it increases redundancy, which can help LZMA2 to produce 0\\(en15\\ % smaller B<.xz> file. The BCJ filters are always reversible, so using a BCJ filter for wrong type of data doesn't cause any data loss, although it may make the compression ratio slightly worse. The BCJ filters are very fast and use an insignificant amount of memory." +msgstr "Um filtro BCJ converte endereços relativos no código de máquina em suas contrapartes absolutas. Isso não altera o tamanho dos dados, mas aumenta a redundância, o que pode ajudar o LZMA2 a produzir um arquivo B<.xz> 0\\(en15\\ % menor. Os filtros BCJ são sempre reversíveis, portanto, usar um filtro BCJ para o tipo errado de dados não causa nenhuma perda de dados, embora possa piorar um pouco a taxa de compactação.Os filtros BCJ são muito rápidos e usam uma quantidade insignificante de memória." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "These BCJ filters have known problems related to the compression ratio:" +msgstr "Esses filtros BCJ têm problemas conhecidos relacionados à taxa de compactação:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Some types of files containing executable code (for example, object files, static libraries, and Linux kernel modules) have the addresses in the instructions filled with filler values. These BCJ filters will still do the address conversion, which will make the compression worse with these files." +msgstr "Alguns tipos de arquivos contendo código executável (por exemplo, arquivos de objeto, bibliotecas estáticas e módulos do kernel do Linux) têm os endereços nas instruções preenchidos com valores de preenchimento. Esses filtros BCJ ainda vão fazer a conversão de endereço, o que vai piorar a compactação desses arquivos." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If a BCJ filter is applied on an archive, it is possible that it makes the compression ratio worse than not using a BCJ filter. For example, if there are similar or even identical executables then filtering will likely make the files less similar and thus compression is worse. The contents of non-executable files in the same archive can matter too. In practice one has to try with and without a BCJ filter to see which is better in each situation." +msgstr "Se um filtro BCJ for aplicado em um arquivo, é possível que isso torne a taxa de compactação pior do que não usar um filtro BCJ. Por exemplo, se houver executáveis semelhantes ou mesmo idênticos, a filtragem provavelmente tornará os arquivos menos semelhantes e, portanto, a compactação será pior. O conteúdo de arquivos não executáveis no mesmo arquivo também pode ser importante. Na prática tem que tentar com e sem filtro BCJ para ver qual é melhor em cada situação." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Different instruction sets have different alignment: the executable file must be aligned to a multiple of this value in the input data to make the filter work." +msgstr "Conjuntos de instruções diferentes têm alinhamento diferente: o arquivo executável deve ser alinhado a um múltiplo desse valor nos dados de entrada para fazer o filtro funcionar." + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filter" +msgstr "Filtro" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Alignment" +msgstr "Alinhamento" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Notes" +msgstr "Observações" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "x86" +msgstr "x86" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "32-bit or 64-bit x86" +msgstr "x86 32 bits ou 64 bits" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "ARM" +msgstr "ARM" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "ARM-Thumb" +msgstr "ARM-Thumb" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "ARM64" +msgstr "ARM64" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "4096-byte alignment is best" +msgstr "" +"Alinhamento de 4096 bytes\n" +";;é melhor" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "PowerPC" +msgstr "PowerPC" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Big endian only" +msgstr "Somente big endian" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "IA-64" +msgstr "IA-64" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "16" +msgstr "16" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Itanium" +msgstr "Itanium" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "SPARC" +msgstr "SPARC" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "RISC-V" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Since the BCJ-filtered data is usually compressed with LZMA2, the compression ratio may be improved slightly if the LZMA2 options are set to match the alignment of the selected BCJ filter. Examples:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IA-64 filter has 16-byte alignment so B is good with LZMA2 (2^4=16)." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "RISC-V code has 2-byte or 4-byte alignment depending on whether the file contains 16-bit compressed instructions (the C extension). When 16-bit instructions are used, B or B is good. When 16-bit instructions aren't present, B is the best. B can be used to check if \"RVC\" appears on the \"Flags\" line." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "ARM64 is always 4-byte aligned so B is the best." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The x86 filter is an exception. It's usually good to stick to LZMA2's defaults (B) when compressing x86 executables." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "All BCJ filters support the same I:" +msgstr "Todos os filtros BCJ suportam as mesmas I:" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the start I that is used when converting between relative and absolute addresses. The I must be a multiple of the alignment of the filter (see the table above). The default is zero. In practice, the default is good; specifying a custom I is almost never useful." +msgstr "Especifica o I inicial que é usado na conversão entre endereços relativos e absolutos. O I deve ser um múltiplo do alinhamento do filtro (ver tabela acima). O padrão é zero. Na prática, o padrão é bom; especificar um I personalizado quase nunca é útil." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--delta>[B<=>I]" +msgstr "B<--delta>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Add the Delta filter to the filter chain. The Delta filter can be only used as a non-last filter in the filter chain." +msgstr "Adiciona o filtro Delta à cadeia de filtros. O filtro Delta só pode ser usado como filtro não-último na cadeia de filtros." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Currently only simple byte-wise delta calculation is supported. It can be useful when compressing, for example, uncompressed bitmap images or uncompressed PCM audio. However, special purpose algorithms may give significantly better results than Delta + LZMA2. This is true especially with audio, which compresses faster and better, for example, with B(1)." +msgstr "Atualmente, apenas o cálculo simples de delta byte a byte é suportado. Pode ser útil ao compactar, por exemplo, imagens bitmap não compactadas ou áudio PCM não compactado. No entanto, algoritmos de propósito especial podem fornecer resultados significativamente melhores do que Delta + LZMA2. Isso é verdade especialmente com áudio, que compacta mais rápido e melhor, por exemplo, com B(1)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Supported I:" +msgstr "I suportadas:" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the I of the delta calculation in bytes. I must be 1\\(en256. The default is 1." +msgstr "Especifica a I do cálculo delta em bytes. I deve ser 1\\(en256. O padrão é 1." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "For example, with B and eight-byte input A1 B1 A2 B3 A3 B5 A4 B7, the output will be A1 B1 01 02 01 02 01 02." +msgstr "Por exemplo, com B e entrada de oito bytes A1 B1 A2 B3 A3 B5 A4 B7, a saída será A1 B1 01 02 01 02 01 02." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Other options" +msgstr "Outras opções" + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-q>, B<--quiet>" +msgstr "B<-q>, B<--quiet>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Suppress warnings and notices. Specify this twice to suppress errors too. This option has no effect on the exit status. That is, even if a warning was suppressed, the exit status to indicate a warning is still used." +msgstr "Suprime avisos e avisos. Especifique isso duas vezes para suprimir erros também. Esta opção não tem efeito no status de saída. Ou seja, mesmo que um aviso tenha sido suprimido, o status de saída para indicar um aviso ainda é usado." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-v>, B<--verbose>" +msgstr "B<-v>, B<--verbose>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Be verbose. If standard error is connected to a terminal, B will display a progress indicator. Specifying B<--verbose> twice will give even more verbose output." +msgstr "Ser detalhado. Se o erro padrão estiver conectado a um terminal, B exibirá um indicador de progresso. Especifique B<--verbose> duas vezes dará uma saída ainda mais detalhada." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The progress indicator shows the following information:" +msgstr "O indicador de progresso mostra as seguintes informações:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Completion percentage is shown if the size of the input file is known. That is, the percentage cannot be shown in pipes." +msgstr "A porcentagem de conclusão é mostrada se o tamanho do arquivo de entrada for conhecido. Ou seja, a porcentagem não pode ser mostrada em encadeamentos (pipe)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of compressed data produced (compressing) or consumed (decompressing)." +msgstr "Quantidade de dados compactados produzidos (compactando) ou consumidos (descompactando)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of uncompressed data consumed (compressing) or produced (decompressing)." +msgstr "Quantidade de dados não compactados consumidos (compactação) ou produzidos (descompactação)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, which is calculated by dividing the amount of compressed data processed so far by the amount of uncompressed data processed so far." +msgstr "Taxa de compactação, que é calculada dividindo a quantidade de dados compactados processados até o momento pela quantidade de dados não compactados processados até o momento." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression or decompression speed. This is measured as the amount of uncompressed data consumed (compression) or produced (decompression) per second. It is shown after a few seconds have passed since B started processing the file." +msgstr "Velocidade de compactação ou descompactação. Isso é medido como a quantidade de dados não compactados consumidos (compactação) ou produzidos (descompactação) por segundo. É mostrado após alguns segundos desde que B começou a processar o arquivo." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Elapsed time in the format M:SS or H:MM:SS." +msgstr "Tempo decorrido no formato M:SS ou H:MM:SS." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Estimated remaining time is shown only when the size of the input file is known and a couple of seconds have already passed since B started processing the file. The time is shown in a less precise format which never has any colons, for example, 2 min 30 s." +msgstr "O tempo restante estimado é mostrado apenas quando o tamanho do arquivo de entrada é conhecido e alguns segundos já se passaram desde que B começou a processar o arquivo. A hora é mostrada em um formato menos preciso que nunca tem dois pontos, por exemplo, 2 min 30 s." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When standard error is not a terminal, B<--verbose> will make B print the filename, compressed size, uncompressed size, compression ratio, and possibly also the speed and elapsed time on a single line to standard error after compressing or decompressing the file. The speed and elapsed time are included only when the operation took at least a few seconds. If the operation didn't finish, for example, due to user interruption, also the completion percentage is printed if the size of the input file is known." +msgstr "Quando o erro padrão não é um terminal, B<--verbose> fará com que B imprima o nome do arquivo, tamanho compactado, tamanho não compactado, taxa de compactação e possivelmente também a velocidade e o tempo decorrido em uma única linha para o erro padrão após a compactação ou descompactando o arquivo. A velocidade e o tempo decorrido são incluídos apenas quando a operação leva pelo menos alguns segundos. Se a operação não foi concluída, por exemplo, devido à interrupção do usuário, também é impressa a porcentagem de conclusão se o tamanho do arquivo de entrada for conhecido." + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-Q>, B<--no-warn>" +msgstr "B<-Q>, B<--no-warn>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Don't set the exit status to 2 even if a condition worth a warning was detected. This option doesn't affect the verbosity level, thus both B<--quiet> and B<--no-warn> have to be used to not display warnings and to not alter the exit status." +msgstr "Não define o status de saída como 2, mesmo que uma condição digna de um aviso tenha sido detectada. Esta opção não afeta o nível de detalhamento, portanto, tanto B<--quiet> quanto B<--no-warn> devem ser usados para não exibir avisos e não alterar o status de saída." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--robot>" +msgstr "B<--robot>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Print messages in a machine-parsable format. This is intended to ease writing frontends that want to use B instead of liblzma, which may be the case with various scripts. The output with this option enabled is meant to be stable across B releases. See the section B for details." +msgstr "Imprime mensagens em um formato analisável por máquina. Isso visa facilitar a criação de frontends que desejam usar B em vez de liblzma, o que pode ser o caso de vários scripts. A saída com esta opção habilitada deve ser estável em versões B. Consulte a seção B para obter detalhes." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--info-memory>" +msgstr "B<--info-memory>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display, in human-readable format, how much physical memory (RAM) and how many processor threads B thinks the system has and the memory usage limits for compression and decompression, and exit successfully." +msgstr "Exibe, em formato legível por humanos, quanta memória física (RAM) e quantos threads de processador B acredita que o sistema possui e os limites de uso de memória para compactação e descompactação e saia com êxito." + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-h>, B<--help>" +msgstr "B<-h>, B<--help>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display a help message describing the most commonly used options, and exit successfully." +msgstr "Exibe uma mensagem de ajuda descrevendo as opções mais usadas e sai com sucesso." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-H>, B<--long-help>" +msgstr "B<-H>, B<--long-help>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display a help message describing all features of B, and exit successfully" +msgstr "Exibe uma mensagem de ajuda descrevendo todos os recursos de B e sai com sucesso" + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-V>, B<--version>" +msgstr "B<-V>, B<--version>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display the version number of B and liblzma in human readable format. To get machine-parsable output, specify B<--robot> before B<--version>." +msgstr "Exibe o número da versão de B e liblzma em formato legível por humanos. Para obter uma saída analisável por máquina, especifique B<--robot> antes de B<--version>." + +#. type: SH +#: ../src/xz/xz.1 +#, no-wrap +msgid "ROBOT MODE" +msgstr "MODO ROBÔ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The robot mode is activated with the B<--robot> option. It makes the output of B easier to parse by other programs. Currently B<--robot> is supported only together with B<--list>, B<--filters-help>, B<--info-memory>, and B<--version>. It will be supported for compression and decompression in the future." +msgstr "" + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "List mode" +msgstr "Modo lista" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B uses tab-separated output. The first column of every line has a string that indicates the type of the information found on that line:" +msgstr "B usa saída separada por tabulações. A primeira coluna de cada linha possui uma string que indica o tipo de informação encontrada naquela linha:" + +#. TRANSLATORS: The bold strings B, B, B, B, +#. B, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "Esta é sempre a primeira linha ao começar a listar um arquivo. A segunda coluna na linha é o nome do arquivo." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "Esta linha contém informações gerais sobre o arquivo B<.xz>. Esta linha é sempre impressa após a linha B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "Este tipo de linha é usado somente quando B<--verbose> foi especificado. Existem tantas linhas de B quanto fluxos no arquivo B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "Este tipo de linha é usado somente quando B<--verbose> foi especificado. Existem tantas linhas B quanto blocos no arquivo B<.xz>. As linhas B são mostradas após todas as linhas B; diferentes tipos de linha não são intercalados." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "Este tipo de linha é usado apenas quando B<--verbose> foi especificado duas vezes. Esta linha é impressa após todas as linhas de B. Assim como a linha B, a linha B contém informações gerais sobre o arquivo B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "Esta linha é sempre a última linha da saída da lista. Ele mostra as contagens totais e tamanhos." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "As colunas das linhas B:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "Número de fluxos no arquivo" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "Número total de blocos no(s) fluxo(s)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "Tamanho compactado do arquivo" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "Uncompressed size of the file" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "Taxa de compactação, por exemplo, B<0.123>. Se a proporção for superior a 9.999, serão exibidos três traços (B<--->) em vez da proporção." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "Lista separada por vírgulas de nomes de verificação de integridade. As seguintes strings são usadas para os tipos de verificação conhecidos: B, B, B e B. Para tipos de verificações desconhecidos, BI é usado, onde I é o ID do cheque como um número decimal (um ou dois dígitos)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "Tamanho total do preenchimento de fluxo no arquivo" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "As colunas das linhas B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "Número do fluxo (o primeiro fluxo é 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "Número de blocos no fluxo" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "Deslocamento inicial compactado" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "Deslocamento inicial descompactado" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "Tamanho compactado (não inclui preenchimento de fluxo)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "Tamanho descompactado" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "Taxa de compactação" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "Nome da verificação de integridade" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "Tamanho do preenchimento do fluxo" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "As colunas das linhas B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "Número do fluxo que contém este bloco" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "Número do bloco relativo ao início do fluxo (o primeiro bloco é 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "Número do bloco relativo ao início do arquivo" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "Deslocamento inicial compactado em relação ao início do arquivo" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "Deslocamento inicial descompactado em relação ao início do arquivo" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "Tamanho total compactado do bloco (inclui cabeçalhos)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "Se B<--verbose> for especificado duas vezes, colunas adicionais serão incluídas nas linhas B. Eles não são exibidos com um único B<--verbose>, porque obter essas informações requer muitas buscas e, portanto, pode ser lento:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "Valor da verificação de integridade em hexadecimal" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "Tamanho do cabeçalho do bloco" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "Sinalizadores de bloco: B indica que o tamanho compactado está presente e B indica que o tamanho não compactado está presente. Se o sinalizador não estiver definido, um traço (B<->) será exibido para manter o comprimento da string fixo. Novos sinalizadores podem ser adicionados ao final da string no futuro." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "Tamanho dos dados reais compactados no bloco (isso exclui o cabeçalho do bloco, o preenchimento do bloco e os campos de verificação)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "Quantidade de memória (em bytes) necessária para descompactar este bloco com esta versão B" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "Cadeia de filtro. Observe que a maioria das opções usadas no momento da compactação não pode ser conhecida, pois apenas as opções necessárias para a descompactação são armazenadas nos cabeçalhos B<.xz>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "As colunas das linhas B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "Quantidade de memória (em bytes) necessária para descompactar este arquivo com esta versão do B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B ou B indicando se todos os cabeçalhos de bloco têm tamanho compactado e tamanho não compactado armazenados neles" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "Versão mínima do B necessária para descompactar o arquivo" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "As colunas da linha B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "Número de fluxos" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "Número de blocos" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "Tamanho compactado" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "Taxa de compactação média" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "Lista separada por vírgulas de nomes de verificação de integridade que estavam presentes nos arquivos" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "Tamanho do preenchimento do fluxo" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "Número de arquivos. Isso está aqui para manter a ordem das colunas anteriores a mesma das linhas B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "Se B<--verbose> for especificado duas vezes, colunas adicionais serão incluídas na linha B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "Quantidade máxima de memória (em bytes) necessária para descompactar os arquivos com esta versão do B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "Versões futuras podem adicionar novos tipos de linha e novas colunas podem ser adicionadas aos tipos de linha existentes, mas as colunas existentes não serão alteradas." + +#. type: SS +#: ../src/xz/xz.1 +#, fuzzy, no-wrap +#| msgid "Filter" +msgid "Filters help" +msgstr "Filtro" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "Aceasta este întotdeauna prima linie când începe să se listeze un fiÈ™ier. A doua coloană de pe linie este numele fiÈ™ierului." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "Această linie conÈ›ine informaÈ›ii generale despre fiÈ™ierul B<.xz>. Această linie este întotdeauna tipărită după linia B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "Acest tip de linie este utilizat numai atunci când a fost specificată opÈ›iunea B<--verbose>. Există tot atâtea linii B câte fluxuri există în fiÈ™ierul B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "Acest tip de linie este utilizat numai atunci când a fost specificată opÈ›iunea B<--verbose>. Există tot atâtea linii B câte blocuri există în fiÈ™ierul B<.xz>. Liniile B sunt afiÈ™ate după toate liniile B; tipurile diferite de linii nu sunt intercalate." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "Acest tip de linie este folosit numai atunci când opÈ›iunea B<--verbose> a fost specificată de două ori. Această linie este afiÈ™ată după toate liniile B. Ca È™i linia B, linia B conÈ›ine informaÈ›ii generale despre fiÈ™ierul B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "Această linie este întotdeauna ultima linie din lista afiÈ™ată la ieÈ™ire. Aceasta arată numărul total È™i dimensiunile." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Coloanele din liniile B:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "Numărul de fluxuri din fiÈ™ier" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "Numărul total de blocuri din fluxuri" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "Dimensiunea comprimată a fiÈ™ierului" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "Dimensiunea necomprimată a fiÈ™ierului" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "Raportul de comprimare, de exemplu, B<0,123>. Dacă raportul este peste 9,999, în locul raportului sunt afiÈ™ate trei liniuÈ›e (B<--->)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "Lista de nume de verificare a integrității, separate prin virgule. Următoarele È™iruri sunt utilizate pentru tipurile de verificare cunoscute: B, B, B È™i B. Pentru tipurile de verificări necunoscute, se utilizează BI, unde I este ID-ul de verificare ca număr zecimal (una sau două cifre)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "Dimensiunea totală a umpluturii fluxului din fiÈ™ier" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Coloanele din liniile B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "Numărul fluxului (primul flux este 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "Numărul de blocuri din flux" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "PoziÈ›ia de pornire a comprimării" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "PoziÈ›ia de pornire a decomprimării" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "Dimensiune comprimată (nu include umplutura fluxului)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "Dimensiune necomprimată" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "Raport de comprimare" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "Numele verificării de integritate" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "Dimensiunea umpluturii fluxului" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Coloanele din liniile B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "Numărul fluxului care conÈ›ine acest bloc" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "Numărul blocului în raport cu începutul fluxului (primul bloc este 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "Numărul blocului în raport cu începutul fiÈ™ierului" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "PoziÈ›ia de pornire a comprimării în raport cu începutul fiÈ™ierului" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "PoziÈ›ia de pornire necomprimată în raport cu începutul fiÈ™ierului" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "Dimensiunea totală comprimată a blocului (include antetele)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "Dacă opÈ›iunea B<--verbose> a fost specificată de două ori, coloane suplimentare sunt incluse pe liniile B. Acestea nu sunt afiÈ™ate cu o singură specificare a opÈ›iunii B<--verbose>, deoarece obÈ›inerea acestor informaÈ›ii necesită multe căutări È™i, prin urmare, poate fi lentă:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "Valoarea verificării integrității în hexazecimal" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "Dimensiunea antetului blocului" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "Indicatori de bloc: B indică faptul că este prezentă dimensiunea comprimată, iar B indică faptul că este prezentă dimensiunea necomprimată. Dacă indicatorul nu este determinat, este afiÈ™ată o liniuță (B<->) pentru a menÈ›ine lungimea È™irului fixă. Pot fi adăugate noi indicatoare la sfârÈ™itul È™irului, în viitor." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "Dimensiunea datelor comprimate reale din bloc (acest lucru exclude antetul blocului, umplutura blocului È™i câmpurile de verificare)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "Cantitatea de memorie (în octeÈ›i) necesară pentru a decomprima acest bloc cu această versiune B" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "LanÈ› de filtrare. ReÈ›ineÈ›i că majoritatea opÈ›iunilor utilizate în timpul comprimării nu pot fi cunoscute, deoarece doar opÈ›iunile necesare pentru decomprimare sunt stocate în anteturile B<.xz>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Coloanele din liniile B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "Cantitatea de memorie (în octeÈ›i) necesară pentru a decomprima acest fiÈ™ier cu această versiune B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B sau B indicând dacă toate antetele blocurilor au atât dimensiunea comprimată, cât È™i dimensiunea necomprimată stocate în ele" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I<ÃŽncepând cu> B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "Versiunea B minimă necesară pentru a decomprima fiÈ™ierul" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "Coloanele din linia B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "Numărul de fluxuri" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "Numărul de blocuri" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "Dimensiunea comprimată" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "Raportul mediu de comprimare" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "Lista de nume de verificare a integrității, separate prin virgule, care au fost prezente în fiÈ™iere" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "Dimensiunea umpluturii fluxului" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "Numărul de fiÈ™iere. Aceasta este aici pentru a păstra ordinea coloanelor anterioare la fel ca pe liniile B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "Dacă opÈ›iunea B<--verbose> a fost specificată de două ori, pe linia B sunt incluse coloane suplimentare:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "Cantitatea maximă de memorie (în octeÈ›i) necesară pentru a decomprima fiÈ™ierele cu această versiune B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "Versiunile viitoare pot adăuga noi tipuri de linii È™i pot fi adăugate coloane noi la tipurile de linii existente, dar coloanele existente nu vor fi modificate." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "Ajutor pentru filtrare" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "B afiÈ™ează filtrele acceptate în următorul format:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (назив)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "Ово је увек први ред приликом почетка лиÑтања датотеке. Друга колона у реду је назив датотеке." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (датотека)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "Овај ред Ñадржи Ñвеукупне информације о B<.xz> датотеци. Овај ред Ñе увек иÑпиÑује поÑле реда B<назив>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (ток)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "Ова врÑта реда Ñе кориÑти Ñамо када је B<--verbose> наведено. Има толико редова B<тока> колико има токова у B<.xz> даатотеци." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (блок)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "Ова врÑта реда Ñе кориÑти Ñамо када је B<--verbose> наведено. Има онолико редова B<блока> колико има блокова у B<.xz> датотеци. Редови B<блока> Ñе приказују након Ñвих редова B<тока>; различите врÑте реда Ñе не преплићу." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (Ñажетак)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "Ова врÑта реда Ñе кориÑти Ñамо када је B<--verbose> наведено два пута. Овај ред Ñе иÑпиÑује након Ñвих редова B<блока>. Као ред B<датотека>, ред B<Ñажетка> Ñадржи преглед информација о B<.xz> датотеци." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B (укупноÑÑ‚)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "Овај ред је увек поÑледњи ред на ÑпиÑку излаза. Показује укупне збирове и величине." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Колоне редова B<датотеке>:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "Број токова у датотеци" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "Укупан број блокова у току(овима)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "Величина запаковане датотеке" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "Величина незапаковане датотеке" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "Размера паковања, на пример, B<0.123>. Ðко је размера преко 9.999, три цртице (B<--->) Ñе приказују умеÑто размере." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "Зарезом раздвојен ÑпиÑак назива провера целовитоÑти. Следеће ниÑке Ñе кориÑте за познате врÑте провера: B, B, B и B. За непознате врÑте провера, кориÑти Ñе BI, где је I ИД провере као децимални број (једна или две цифре)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "Укупна величина попуњавања тока у датотеци" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Колоне редова B<тока>:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "Број тока (први ток је 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "Број блокова у току" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "Померај почетка запакованог" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "Померај почетка незапаковане" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "Величина запакованог (не укључује попуну тока)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "Величина незапаковане" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "Размера паковања" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "Ðазив провере целовитоÑти" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "Величина попуне тока" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Колоне редова B<блока>:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "Број тока који Ñадржи овај блок" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "Број блока релативан на почетак тока (први блок је 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "Број блока релативан на почетак датотеке" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "Померај почетка запакованог одноÑан на почетак датотеке" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "Померај почетка незапаковане одноÑан на почетак датотеке" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "Укупна запакована величина блока (заједно Ñа заглављима)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "Ðко је B<--verbose> наведено два пута, додатне колоне Ñу укључене у редовима B<блока>. Они Ñе не приказују Ñа једним B<--verbose>, јер добијање ове информације захтева много тражења и Ñтога може бити Ñпоро:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "ВредноÑÑ‚ провере целовитоÑти у хекÑадецималном облику" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "Величина заглавља блока" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "ЗаÑтавице блока: B указује да је величина запакованог приÑутна, а B указује да је величина нераÑпакованог приÑутна. Ðко заÑтавица није поÑтављена, цртица (B<->) Ñе приказује умеÑто да Ñе наÑтави Ñа поправком дужине ниÑке. У будућноÑти нове заÑтавице могу бити додате на крај ниÑке." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "Величина Ñтварних запакованих података у блоку (ово иÑкључује заглавље блока, попуњавање блока и поља провере)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "Количина меморије (у бајтовима) потребна за раÑпакивање овог блока Ñа овим B издањем" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "Ланац филтера. Знајте да већина опција коришћених за време запакивања не може бити познато, јер Ñе Ñамо опције које Ñу потребне за раÑпакивање чувају у B<.xz> заглављима." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Колоне редова B<Ñажетка>:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "Количина меморије (у бајтовима) потребна за раÑпакивање ове датотеке Ñа овим B издањем" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B или B указује да ли Ñва заглавља блока имају и величину запакованог и величину незапакованог Ñачуване у њима" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I<Од> B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "Потребно је најмање B издање за раÑпакивање датотеке" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "Колоне редова B<укупноÑти>:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "Број токова" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "Број блокова" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "Величина запакованог" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "ПроÑечан Ñтепен запакивања" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "СпиÑак зарезом раздвојених назива провере целовитоÑти која Ñу била приÑутна у датотекама" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "Величина попуњавања тока" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "Број датотека. Ту Ñе држи поредак ранијих колона иÑто као у редовима B<датотеке>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "Ðко је B<--verbose> наведено два пута, додатне колоне Ñу укључене у реду B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "Ðајвећа количина меморије (у бајтима) потребна за раÑпакивање датотеке Ñа овим B издањем" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "Будућа издања могу додати нове врÑте реда и нове колоне Ñе могу додати поÑтојећим врÑтама реда, али поÑтојеће колоне Ñе неће променити." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "Помоћ филтера" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "B иÑпиÑује подржане филтере у Ñледећем формату:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "Detta är alltid första raden när en fil börjar listas. Den andra kolumen pÃ¥ raden är filnamnet." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "Denna rad innehÃ¥ller övergripande information om B<.xz>-filen. Denna rad skrivs alltid efter raden B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "Denna radtyp används endast när B<--verbose> angetts. Det finns lika mÃ¥nga B-rader som det finns strömmar i B<.xz>-filen." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "Denna radtyp används bara när B<--verbose> angetts. Det finns lika mÃ¥nga B-rader som det finns block i B<.xz>-filen. B-rader visas efter alla B-raderna; olika radtyper blandas inte." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "Denna radtyp används bara när B<--verbose> angetts tvÃ¥ gÃ¥nger. Denna rad skrivs eefter alla B-rader. Liksom raden B inenhÃ¥ller raden B övergripande information om B<.xz>-filen." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "Denna rad är alltid den allra sista raden i listutmatningen. Den visar det totala antalen och storlekarna." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Kolumnerna pÃ¥ B-raderna:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "Antalet strömmar i filen" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "Totalt antal block i strömmarna" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "Komprimerad storlek pÃ¥ filen" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "Okomprimerad storlek pÃ¥ filen" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "KomprimeringsförhÃ¥llande, till exempel B<0.123>. Om förhÃ¥llandet är över 9.999 visas tre bindestreck (B<--->) istället för förhÃ¥llandet." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "Kommaseparerad lista med integritetskontrollnamn. Följande strängar används för de kända kontrolltyperna: B, B, B och B. För okända kontrolltyper används BI, där I är kontroll-ID:t som ett decimalt nummer (en eller tvÃ¥ siffror)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "Total storlek pÃ¥ strömutfyllnad i filen" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Kolumnerna pÃ¥ B-raderna:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "Strömnummer (den första strömmen är 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "Antal block i strömmen" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "Komprimerat startavstÃ¥nd" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "Okomprimerat startavstÃ¥nd" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "Komprimerad storlek (inkluderar inte strömutfyllnad)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "Okomprimerad storlek" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "KomprimeringsförhÃ¥llande" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "Namnet pÃ¥ integritetskontrollen" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "Storleken pÃ¥ strömutfyllnad" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Kolumnerna pÃ¥ B-raderna:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "Numret pÃ¥ strömmen som innehÃ¥ller detta block" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "Blocknummer relativt början pÃ¥ strömmen (det första blocket är 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "Blocknummer relativt början pÃ¥ filen" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "Komprimerat startavstÃ¥nd relativt början av filen" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "Okomprimerat startavstÃ¥nd relativt början av filen" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "Total komprimerad storlek pÃ¥ blocket (inkluderar huvuden)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "Om B<--verbose> angavs tvÃ¥ gÃ¥nger inkluderas ytterligare kolumner pÃ¥ B-raderna. Dessa visas inte med bara ett B<--verbose>, eftersom det för att fÃ¥ fram denna information krävs mÃ¥nga sökningar och kan därmed vara lÃ¥ngsamt:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "Värdet pÃ¥ integritetskontrollen hexadecimalt" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "Blockhuvudstorlek" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "Blockflaggor: B indikerar att komprimerad storlek finns, och B indikerar att okomprimerad storlek finns. Om flaggan inte är satt visas ett bindestreck (B<->) istället för att hÃ¥lla stränglängden fast. Nya flaggor kan läggas till i slutet av strängen i frmtiden." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "Storlek pÃ¥ den faktiska komprimerade datan i blocket (detta utelämnar blockhuvud, blockutfyllnad och kontrollfält)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "Mängd minne (i byte) som behövs för att dekomprimera detta block med denna version av B" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "Filterkedja. Observera att de flesta av flaggorna som användes vid komprimeringstillfället inte kan vara kända, eftersom endat de flaggor som behövs för dekomprimering lagras i B<.xz>-huvudet." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Kolumnerna pÃ¥ B-raderna:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "Mängd minne (i byte) som behövs för att dekomprimera denna fil med denna version av B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B eller B som indikerar om alla blockhuvuden bÃ¥de har komprimerad storlek och okomprimerad storlek i sig" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "Minsta version av B som krävs för att dekomprimera filen" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "Kolumnerna pÃ¥ B-raden:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "Antal strömmar" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "Antal block" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "Komprimerad storlek" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "Genomsnittligt komprimeringsförhÃ¥llande" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "Kommaseparerad lista med integritetskontrollnamn som fanns i filerna" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "Strömutfyllnadsstorlek" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "Antal filer. Denna finns här för att hÃ¥lla ordningen av de tidigare kolumnerna desamma som pÃ¥ B-rader." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "Om B<--verbose> angavs tvÃ¥ gÃ¥nger inkluderas ytterligare kolumner pÃ¥ B-raden:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "Maximal mängd minne (i byte) som behövs för att dekomprimera filerna med denna version av B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "Framtida versioner kan lägga till fler radtyper och fler kolumner kan läggas til pÃ¥ de befintliga radtyperna, men de befintliga kolumnerna kommmer inte ändras." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "Filterhjälp" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "B skriver ut de filter som stödjs i följande format:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "Це завжди перший Ñ€Ñдок на початку ÑпиÑку файла. Другим Ñтовпчиком у Ñ€Ñдку Ñ” назва файла." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "У цьому Ñ€Ñдку міÑÑ‚ÑтьÑÑ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ñ– відомоÑті щодо файла B<.xz>. Цей Ñ€Ñдок завжди виводÑть піÑÐ»Ñ Ñ€Ñдка B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "Цей тип Ñ€Ñдка викориÑтовують, лише Ñкщо було вказано B<--verbose>. Буде Ñтільки Ñ€Ñдків B, Ñкільки потоків у файлі B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "Цей тип Ñ€Ñдка викориÑтовують, лише Ñкщо було вказано B<--verbose>. Буде Ñтільки Ñ€Ñдків B, Ñкільки блоків у файлі B<.xz>. РÑдки B буде показано піÑÐ»Ñ ÑƒÑÑ–Ñ… Ñ€Ñдків B; різні типи Ñ€Ñдків не перемежовуютьÑÑ." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "Цей тип Ñ€Ñдків викориÑтовують, лише Ñкщо B<--verbose> було вказано двічі. Цей Ñ€Ñдок буде виведено піÑÐ»Ñ ÑƒÑÑ–Ñ… Ñ€Ñдків B. Подібно до Ñ€Ñдка B, Ñ€Ñдок B міÑтить загальні відомоÑті щодо файла B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "Цей Ñ€Ñдок завжди Ñ” найоÑтаннішим Ñ€Ñдком у виведеному ÑпиÑку. У ньому буде показано загальні кількоÑті та розміри." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Стовпчики у Ñ€Ñдках B<файла>:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "КількіÑть потоків у файлі" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "3." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "Загальна кількіÑть блоків у потоках" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "Розмір ÑтиÑненого файла" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "5." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "Розмір неÑтиÑненого файла" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "6." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "Коефіцієнт ÑтиÑканнÑ, наприклад, B<0.123>. Якщо коефіцієнт перевищує 9.999, заміÑть коефіцієнта буде показано дефіÑи (B<--->)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "7." + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "СпиÑок відокремлених комами назв перевірок ціліÑноÑті. Ðаведені нижче Ñ€Ñдки викориÑтовують Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð¼Ð¸Ñ… типів перевірок: B, B, B Ñ– B. Ð”Ð»Ñ Ð½ÐµÐ²Ñ–Ð´Ð¾Ð¼Ð¸Ñ… типів перевірок буде викориÑтано BI, де I Ñ” ідентифікатором перевірки у форматі деÑÑткового чиÑла (одна або дві цифри)." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "8." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "Загальний розмір Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ у файлі" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Стовпчики у Ñ€Ñдках B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "Ðомер потоку (перший потік має номер 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "КількіÑть блоків у потоці" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "ЗÑув початку ÑтиÑненого" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "ЗÑув початку неÑтиÑненого" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "СтиÑнений розмір (не включає Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "ÐеÑтиÑнутий розмір" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "Рівень ÑтиÑканнÑ" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "Ðазва перевірки ціліÑноÑті" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "10." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "Розмір Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Стовпчики у Ñ€Ñдках B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "Ðомер потоку, що міÑтить цей блок" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "Ðомер блоку відноÑно початку потоку (перший блок має номер 1)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "Ðомер блоку відноÑно початку файла" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "ЗÑув початку ÑтиÑненого відноÑно початку файла" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "ЗÑув початку неÑтиÑненого відноÑно початку файла" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "Загальний ÑтиÑнений розмір блоку (включено з заголовками)" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "Якщо B<--verbose> було вказано двічі, до Ñ€Ñдків B буде включено додаткові Ñтовпчики. Ці Ñтовпчики не буде показано, Ñкщо вказано одинарний параметр B<--verbose>, оÑкільки Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ†Ð¸Ñ… відомоÑтей потребує багатьох позиціювань, а Ñ†Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° може бути повільною:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "11." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ ціліÑноÑті у шіÑтнадцÑтковій формі" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "12." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "Розмір заголовка блоку" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "13." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "Прапорці блоку: B вказує, що наÑвний ÑтиÑнений розмір, а B вказує, що наÑвний неÑтиÑнений розмір. Якщо прапорець не вÑтановлено, буде показано (B<->) заміÑть Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ„Ñ–ÐºÑованого розміру Ñ€Ñдка. У майбутньому наприкінці Ñ€Ñдка може бути додано нові прапорці." + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "14." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "Розмір Ñправжніх ÑтиÑнених даних у блоці (це включає заголовок блоку, Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð±Ð»Ð¾ÐºÑƒ та Ð¿Ð¾Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€Ð¾Ðº)" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "15." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "Об'єм пам'Ñті (у байтах), Ñкий потрібен Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ блоку за допомогою цієї верÑÑ–Ñ— B" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "16." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "Ланцюжок фільтрів. Зауважте, що більшіÑть параметрів, Ñкі викориÑтано під Ñ‡Ð°Ñ ÑтиÑканнÑ, не Ñ” наперед відомим, оÑкільки у заголовках B<.xz> зберігаютьÑÑ Ð»Ð¸ÑˆÐµ параметри, Ñкі потрібні Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "Стовпчики у Ñ€Ñдках B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "Об'єм пам'Ñті (у байтах), Ñкий потрібен Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файла за допомогою цієї верÑÑ–Ñ— B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "B або B вказує, Ñкщо уÑÑ– заголовки блоків міÑÑ‚Ñть одразу ÑтиÑнений розмір та розпакований розмір" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "I<Починаючи з> B I<5.1.2alpha:>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "Мінімальна верÑÑ–Ñ B, Ñка потрібна Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð°" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "Стовпчики Ñ€Ñдка B:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "КількіÑть потоків" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "КількіÑть блоків" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "СтиÑнутий розмір" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "Середній коефіцієнт ÑтиÑканнÑ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "СпиÑок відокремлених комами назв перевірок ціліÑноÑті, результати Ñких наÑвні у файлах" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "Розмір Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "КількіÑть файлів. ÐаÑвний тут Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ñ‚Ð°ÐºÐ¾Ð³Ð¾ Ñамого порÑдку Ñтовпчиків, що Ñ– у попередніх Ñ€Ñдках B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "Якщо B<--verbose> було вказано двічі, до Ñ€Ñдка B буде включено додаткові Ñтовпчики:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "МакÑимальний об'єм пам'Ñті (у байтах), Ñкий потрібен Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² за допомогою цієї верÑÑ–Ñ— B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "У майбутніх верÑÑ–ÑÑ… може бути додано нові типи Ñ€Ñдків Ñ– нові Ñтовпчики до наÑвних типів Ñ€Ñдків, але наÑвні Ñтовпчики мають лишитиÑÑ Ð½ÐµÐ·Ð¼Ñ–Ð½Ð½Ð¸Ð¼Ð¸." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "Довідка з фільтруваннÑ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "B виведе ÑпиÑок підтримуваних фільтрів у такому форматі:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +#. parse, thus the untranslated strings must be included in the translated +#. man page. It may be useful to provide a translated string in parenthesis +#. without bold, for example: "B (nimi)" +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is always the first line when starting to list a file. The second column on the line is the filename." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line contains overall information about the B<.xz> file. This line is always printed after the B line." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are streams in the B<.xz> file." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified. There are as many B lines as there are blocks in the B<.xz> file. The B lines are shown after all the B lines; different line types are not interleaved." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line type is used only when B<--verbose> was specified twice. This line is printed after all B lines. Like the B line, the B line contains overall information about the B<.xz> file." +msgstr "" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This line is always the very last line of the list output. It shows the total counts and sizes." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "2." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams in the file" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "3." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total number of blocks in the stream(s)" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "4." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size of the file" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "5." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size of the file" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "6." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, for example, B<0.123>. If ratio is over 9.999, three dashes (B<--->) are displayed instead of the ratio." +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "7." +msgstr "" + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, B, or B here. In robot mode, xz produces +#. them in untranslated form for scripts to parse. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names. The following strings are used for the known check types: B, B, B, and B. For unknown check types, BI is used, where I is the Check ID as a decimal number (one or two digits)." +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "8." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total size of stream padding in the file" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream number (the first stream is 1)" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks in the stream" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size (does not include stream padding)" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed size" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "9." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Name of the integrity check" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "10." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of stream padding" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of the stream containing this block" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the stream (the first block is 1)" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block number relative to the beginning of the file" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed start offset relative to the beginning of the file" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Uncompressed start offset relative to the beginning of the file" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Total compressed size of the block (includes headers)" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B lines. These are not displayed with a single B<--verbose>, because getting this information requires many seeks and can thus be slow:" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "11." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Value of the integrity check in hexadecimal" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "12." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block header size" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "13." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Block flags: B indicates that compressed size is present, and B indicates that uncompressed size is present. If the flag is not set, a dash (B<->) is shown instead to keep the string length fixed. New flags may be added to the end of the string in the future." +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "14." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Size of the actual compressed data in the block (this excludes the block header, block padding, and check fields)" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "15." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this block with this B version" +msgstr "" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "16." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Filter chain. Note that most of the options used at compression time cannot be known, because only the options that are needed for decompression are stored in the B<.xz> headers." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B lines:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of memory (in bytes) required to decompress this file with this B version" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B or B indicating if all block headers have both compressed size and uncompressed size stored in them" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I B I<5.1.2alpha:>" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum B version required to decompress the file" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The columns of the B line:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of streams" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of blocks" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compressed size" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Average compression ratio" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Comma-separated list of integrity check names that were present in the files" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Stream padding size" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Number of files. This is here to keep the order of the earlier columns the same as on B lines." +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If B<--verbose> was specified twice, additional columns are included on the B line:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Maximum amount of memory (in bytes) required to decompress the files with this B version" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Future versions may add new line types and new columns can be added to the existing line types, but the existing columns won't be changed." +msgstr "" + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filters help" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B prints the supported filters in the following format:" +msgstr "" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IB<:>I, and B are produced by the xz tool for scripts to +.\" parse, thus the untranslated strings must be included in the translated +.\" man page. It may be useful to provide a translated string in parenthesis +.\" without bold, for example: "B (nimi)" +.B name +This is always the first line when starting to list a file. +The second column on the line is the filename. +.TP +.B file +This line contains overall information about the +.B .xz +file. +This line is always printed after the +.B name +line. +.TP +.B stream +This line type is used only when +.B \-\-verbose +was specified. +There are as many +.B stream +lines as there are streams in the +.B .xz +file. +.TP +.B block +This line type is used only when +.B \-\-verbose +was specified. +There are as many +.B block +lines as there are blocks in the +.B .xz +file. +The +.B block +lines are shown after all the +.B stream +lines; different line types are not interleaved. +.TP +.B summary +This line type is used only when +.B \-\-verbose +was specified twice. +This line is printed after all +.B block +lines. +Like the +.B file +line, the +.B summary +line contains overall information about the +.B .xz +file. +.TP +.B totals +This line is always the very last line of the list output. +It shows the total counts and sizes. +.PP +The columns of the +.B file +lines: +.PD 0 +.RS +.IP 2. 4 +Number of streams in the file +.IP 3. 4 +Total number of blocks in the stream(s) +.IP 4. 4 +Compressed size of the file +.IP 5. 4 +Uncompressed size of the file +.IP 6. 4 +Compression ratio, for example, +.BR 0.123 . +If ratio is over 9.999, three dashes +.RB ( \-\-\- ) +are displayed instead of the ratio. +.IP 7. 4 +Comma-separated list of integrity check names. +The following strings are used for the known check types: +.\" TRANSLATORS: Don't translate the bold strings B, B, +.\" B, B, or B here. In robot mode, xz produces +.\" them in untranslated form for scripts to parse. +.BR None , +.BR CRC32 , +.BR CRC64 , +and +.BR SHA\-256 . +For unknown check types, +.BI Unknown\- N +is used, where +.I N +is the Check ID as a decimal number (one or two digits). +.IP 8. 4 +Total size of stream padding in the file +.RE +.PD +.PP +The columns of the +.B stream +lines: +.PD 0 +.RS +.IP 2. 4 +Stream number (the first stream is 1) +.IP 3. 4 +Number of blocks in the stream +.IP 4. 4 +Compressed start offset +.IP 5. 4 +Uncompressed start offset +.IP 6. 4 +Compressed size (does not include stream padding) +.IP 7. 4 +Uncompressed size +.IP 8. 4 +Compression ratio +.IP 9. 4 +Name of the integrity check +.IP 10. 4 +Size of stream padding +.RE +.PD +.PP +The columns of the +.B block +lines: +.PD 0 +.RS +.IP 2. 4 +Number of the stream containing this block +.IP 3. 4 +Block number relative to the beginning of the stream +(the first block is 1) +.IP 4. 4 +Block number relative to the beginning of the file +.IP 5. 4 +Compressed start offset relative to the beginning of the file +.IP 6. 4 +Uncompressed start offset relative to the beginning of the file +.IP 7. 4 +Total compressed size of the block (includes headers) +.IP 8. 4 +Uncompressed size +.IP 9. 4 +Compression ratio +.IP 10. 4 +Name of the integrity check +.RE +.PD +.PP +If +.B \-\-verbose +was specified twice, additional columns are included on the +.B block +lines. +These are not displayed with a single +.BR \-\-verbose , +because getting this information requires many seeks +and can thus be slow: +.PD 0 +.RS +.IP 11. 4 +Value of the integrity check in hexadecimal +.IP 12. 4 +Block header size +.IP 13. 4 +Block flags: +.B c +indicates that compressed size is present, and +.B u +indicates that uncompressed size is present. +If the flag is not set, a dash +.RB ( \- ) +is shown instead to keep the string length fixed. +New flags may be added to the end of the string in the future. +.IP 14. 4 +Size of the actual compressed data in the block (this excludes +the block header, block padding, and check fields) +.IP 15. 4 +Amount of memory (in bytes) required to decompress +this block with this +.B xz +version +.IP 16. 4 +Filter chain. +Note that most of the options used at compression time +cannot be known, because only the options +that are needed for decompression are stored in the +.B .xz +headers. +.RE +.PD +.PP +The columns of the +.B summary +lines: +.PD 0 +.RS +.IP 2. 4 +Amount of memory (in bytes) required to decompress +this file with this +.B xz +version +.IP 3. 4 +.B yes +or +.B no +indicating if all block headers have both compressed size and +uncompressed size stored in them +.PP +.I Since +.B xz +.I 5.1.2alpha: +.IP 4. 4 +Minimum +.B xz +version required to decompress the file +.RE +.PD +.PP +The columns of the +.B totals +line: +.PD 0 +.RS +.IP 2. 4 +Number of streams +.IP 3. 4 +Number of blocks +.IP 4. 4 +Compressed size +.IP 5. 4 +Uncompressed size +.IP 6. 4 +Average compression ratio +.IP 7. 4 +Comma-separated list of integrity check names +that were present in the files +.IP 8. 4 +Stream padding size +.IP 9. 4 +Number of files. +This is here to +keep the order of the earlier columns the same as on +.B file +lines. +.PD +.RE +.PP +If +.B \-\-verbose +was specified twice, additional columns are included on the +.B totals +line: +.PD 0 +.RS +.IP 10. 4 +Maximum amount of memory (in bytes) required to decompress +the files with this +.B xz +version +.IP 11. 4 +.B yes +or +.B no +indicating if all block headers have both compressed size and +uncompressed size stored in them +.PP +.I Since +.B xz +.I 5.1.2alpha: +.IP 12. 4 +Minimum +.B xz +version required to decompress the file +.RE +.PD +.PP +Future versions may add new line types and +new columns can be added to the existing line types, +but the existing columns won't be changed. +. +.SS "Filters help" +.B "xz \-\-robot \-\-filters-help" +prints the supported filters in the following format: +.PP +\fIfilter\fB:\fIoption\fB=<\fIvalue\fB>,\fIoption\fB=<\fIvalue\fB>\fR... +.TP +.I filter +Name of the filter +.TP +.I option +Name of a filter specific option +.TP +.I value +Numeric +.I value +ranges appear as +\fB<\fImin\fB\-\fImax\fB>\fR. +String +.I value +choices are shown within +.B "< >" +and separated by a +.B | +character. +.PP +Each filter is printed on its own line. +. +.SS "Memory limit information" +.B "xz \-\-robot \-\-info\-memory" +prints a single line with multiple tab-separated columns: +.IP 1. 4 +Total amount of physical memory (RAM) in bytes. +.IP 2. 4 +Memory usage limit for compression in bytes +.RB ( \-\-memlimit\-compress ). +A special value of +.B 0 +indicates the default setting +which for single-threaded mode is the same as no limit. +.IP 3. 4 +Memory usage limit for decompression in bytes +.RB ( \-\-memlimit\-decompress ). +A special value of +.B 0 +indicates the default setting +which for single-threaded mode is the same as no limit. +.IP 4. 4 +Since +.B xz +5.3.4alpha: +Memory usage for multi-threaded decompression in bytes +.RB ( \-\-memlimit\-mt\-decompress ). +This is never zero because a system-specific default value +shown in the column 5 +is used if no limit has been specified explicitly. +This is also never greater than the value in the column 3 +even if a larger value has been specified with +.BR \-\-memlimit\-mt\-decompress . +.IP 5. 4 +Since +.B xz +5.3.4alpha: +A system-specific default memory usage limit +that is used to limit the number of threads +when compressing with an automatic number of threads +.RB ( \-\-threads=0 ) +and no memory usage limit has been specified +.RB ( \-\-memlimit\-compress ). +This is also used as the default value for +.BR \-\-memlimit\-mt\-decompress . +.IP 6. 4 +Since +.B xz +5.3.4alpha: +Number of available processor threads. +.PP +In the future, the output of +.B "xz \-\-robot \-\-info\-memory" +may have more columns, but never more than a single line. +. +.SS Version +.B "xz \-\-robot \-\-version" +prints the version number of +.B xz +and liblzma in the following format: +.PP +.\" TRANSLATORS: Don't translate the uppercase XZ_VERSION or LIBLZMA_VERSION. +.BI XZ_VERSION= XYYYZZZS +.br +.BI LIBLZMA_VERSION= XYYYZZZS +.TP +.I X +Major version. +.TP +.I YYY +Minor version. +Even numbers are stable. +Odd numbers are alpha or beta versions. +.TP +.I ZZZ +Patch level for stable releases or +just a counter for development releases. +.TP +.I S +Stability. +0 is alpha, 1 is beta, and 2 is stable. +.I S +should be always 2 when +.I YYY +is even. +.PP +.I XYYYZZZS +are the same on both lines if +.B xz +and liblzma are from the same XZ Utils release. +.PP +Examples: 4.999.9beta is +.B 49990091 +and +5.0.0 is +.BR 50000002 . +. +.SH "EXIT STATUS" +.TP +.B 0 +All is good. +.TP +.B 1 +An error occurred. +.TP +.B 2 +Something worth a warning occurred, +but no actual errors occurred. +.PP +Notices (not warnings or errors) printed on standard error +don't affect the exit status. +. +.SH ENVIRONMENT +.B xz +parses space-separated lists of options +from the environment variables +.\" TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS or XZ_OPT. +.\" They are names of environment variables. +.B XZ_DEFAULTS +and +.BR XZ_OPT , +in this order, before parsing the options from the command line. +Note that only options are parsed from the environment variables; +all non-options are silently ignored. +Parsing is done with +.BR getopt_long (3) +which is used also for the command line arguments. +.PP +.B Warning: +By setting these environment variables, +one is effectively modifying programs and scripts that run +.BR xz . +Most of the time it is safe to set memory usage limits, number of threads, +and compression options via the environment variables. +However, some options can break scripts. +An obvious example is +.B \-\-help +which makes +.B xz +show the help text instead of compressing or decompressing a file. +More subtle examples are +.B \-\-quiet +and +.BR \-\-verbose . +In many cases it works well to enable the progress indicator using +.BR \-\-verbose , +but in some situations the extra messages create problems. +The verbosity level also affects the behavior of +.BR \-\-list . +.TP +.B XZ_DEFAULTS +User-specific or system-wide default options. +Typically this is set in a shell initialization script to enable +.BR xz 's +memory usage limiter by default or set the default number of threads. +Excluding shell initialization scripts +and similar special cases, scripts should never set or unset +.BR XZ_DEFAULTS . +.TP +.B XZ_OPT +This is for passing options to +.B xz +when it is not possible to set the options directly on the +.B xz +command line. +This is the case when +.B xz +is run by a script or tool, for example, GNU +.BR tar (1): +.RS +.RS +.PP +.nf +.ft CR +XZ_OPT=\-2v tar caf foo.tar.xz foo +.ft R +.fi +.RE +.RE +.IP "" +Scripts may use +.BR XZ_OPT , +for example, to set script-specific default compression options. +It is still recommended to allow users to override +.B XZ_OPT +if that is reasonable. +For example, in +.BR sh (1) +scripts one may use something like this: +.RS +.RS +.PP +.nf +.ft CR +XZ_OPT=${XZ_OPT\-"\-7e"} +export XZ_OPT +.ft R +.fi +.RE +.RE +. +.SH "LZMA UTILS COMPATIBILITY" +The command line syntax of +.B xz +is practically a superset of +.BR lzma , +.BR unlzma , +and +.B lzcat +as found from LZMA Utils 4.32.x. +In most cases, it is possible to replace +LZMA Utils with XZ Utils without breaking existing scripts. +There are some incompatibilities though, +which may sometimes cause problems. +. +.SS "Compression preset levels" +The numbering of the compression level presets is not identical in +.B xz +and LZMA Utils. +The most important difference is how dictionary sizes +are mapped to different presets. +Dictionary size is roughly equal to the decompressor memory usage. +.RS +.PP +.TS +tab(;); +c c c +c n n. +Level;xz;LZMA Utils +\-0;256 KiB;N/A +\-1;1 MiB;64 KiB +\-2;2 MiB;1 MiB +\-3;4 MiB;512 KiB +\-4;4 MiB;1 MiB +\-5;8 MiB;2 MiB +\-6;8 MiB;4 MiB +\-7;16 MiB;8 MiB +\-8;32 MiB;16 MiB +\-9;64 MiB;32 MiB +.TE +.RE +.PP +The dictionary size differences affect +the compressor memory usage too, +but there are some other differences between +LZMA Utils and XZ Utils, which +make the difference even bigger: +.RS +.PP +.TS +tab(;); +c c c +c n n. +Level;xz;LZMA Utils 4.32.x +\-0;3 MiB;N/A +\-1;9 MiB;2 MiB +\-2;17 MiB;12 MiB +\-3;32 MiB;12 MiB +\-4;48 MiB;16 MiB +\-5;94 MiB;26 MiB +\-6;94 MiB;45 MiB +\-7;186 MiB;83 MiB +\-8;370 MiB;159 MiB +\-9;674 MiB;311 MiB +.TE +.RE +.PP +The default preset level in LZMA Utils is +.B \-7 +while in XZ Utils it is +.BR \-6 , +so both use an 8 MiB dictionary by default. +. +.SS "Streamed vs. non-streamed .lzma files" +The uncompressed size of the file can be stored in the +.B .lzma +header. +LZMA Utils does that when compressing regular files. +The alternative is to mark that uncompressed size is unknown +and use end-of-payload marker to indicate +where the decompressor should stop. +LZMA Utils uses this method when uncompressed size isn't known, +which is the case, for example, in pipes. +.PP +.B xz +supports decompressing +.B .lzma +files with or without end-of-payload marker, but all +.B .lzma +files created by +.B xz +will use end-of-payload marker and have uncompressed size +marked as unknown in the +.B .lzma +header. +This may be a problem in some uncommon situations. +For example, a +.B .lzma +decompressor in an embedded device might work +only with files that have known uncompressed size. +If you hit this problem, you need to use LZMA Utils +or LZMA SDK to create +.B .lzma +files with known uncompressed size. +. +.SS "Unsupported .lzma files" +The +.B .lzma +format allows +.I lc +values up to 8, and +.I lp +values up to 4. +LZMA Utils can decompress files with any +.I lc +and +.IR lp , +but always creates files with +.B lc=3 +and +.BR lp=0 . +Creating files with other +.I lc +and +.I lp +is possible with +.B xz +and with LZMA SDK. +.PP +The implementation of the LZMA1 filter in liblzma +requires that the sum of +.I lc +and +.I lp +must not exceed 4. +Thus, +.B .lzma +files, which exceed this limitation, cannot be decompressed with +.BR xz . +.PP +LZMA Utils creates only +.B .lzma +files which have a dictionary size of +.RI "2^" n +(a power of 2) but accepts files with any dictionary size. +liblzma accepts only +.B .lzma +files which have a dictionary size of +.RI "2^" n +or +.RI "2^" n " + 2^(" n "\-1)." +This is to decrease false positives when detecting +.B .lzma +files. +.PP +These limitations shouldn't be a problem in practice, +since practically all +.B .lzma +files have been compressed with settings that liblzma will accept. +. +.SS "Trailing garbage" +When decompressing, +LZMA Utils silently ignore everything after the first +.B .lzma +stream. +In most situations, this is a bug. +This also means that LZMA Utils +don't support decompressing concatenated +.B .lzma +files. +.PP +If there is data left after the first +.B .lzma +stream, +.B xz +considers the file to be corrupt unless +.B \-\-single\-stream +was used. +This may break obscure scripts which have +assumed that trailing garbage is ignored. +. +.SH NOTES +. +.SS "Compressed output may vary" +The exact compressed output produced from +the same uncompressed input file +may vary between XZ Utils versions even if +compression options are identical. +This is because the encoder can be improved +(faster or better compression) +without affecting the file format. +The output can vary even between different +builds of the same XZ Utils version, +if different build options are used. +.PP +The above means that once +.B \-\-rsyncable +has been implemented, +the resulting files won't necessarily be rsyncable +unless both old and new files have been compressed +with the same xz version. +This problem can be fixed if a part of the encoder +implementation is frozen to keep rsyncable output +stable across xz versions. +. +.SS "Embedded .xz decompressors" +Embedded +.B .xz +decompressor implementations like XZ Embedded don't necessarily +support files created with integrity +.I check +types other than +.B none +and +.BR crc32 . +Since the default is +.BR \-\-check=crc64 , +you must use +.B \-\-check=none +or +.B \-\-check=crc32 +when creating files for embedded systems. +.PP +Outside embedded systems, all +.B .xz +format decompressors support all the +.I check +types, or at least are able to decompress +the file without verifying the +integrity check if the particular +.I check +is not supported. +.PP +XZ Embedded supports BCJ filters, +but only with the default start offset. +. +.SH EXAMPLES +. +.SS Basics +Compress the file +.I foo +into +.I foo.xz +using the default compression level +.RB ( \-6 ), +and remove +.I foo +if compression is successful: +.RS +.PP +.nf +.ft CR +xz foo +.ft R +.fi +.RE +.PP +Decompress +.I bar.xz +into +.I bar +and don't remove +.I bar.xz +even if decompression is successful: +.RS +.PP +.nf +.ft CR +xz \-dk bar.xz +.ft R +.fi +.RE +.PP +Create +.I baz.tar.xz +with the preset +.B \-4e +.RB ( "\-4 \-\-extreme" ), +which is slower than the default +.BR \-6 , +but needs less memory for compression and decompression (48\ MiB +and 5\ MiB, respectively): +.RS +.PP +.nf +.ft CR +tar cf \- baz | xz \-4e > baz.tar.xz +.ft R +.fi +.RE +.PP +A mix of compressed and uncompressed files can be decompressed +to standard output with a single command: +.RS +.PP +.nf +.ft CR +xz \-dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt +.ft R +.fi +.RE +. +.SS "Parallel compression of many files" +On GNU and *BSD, +.BR find (1) +and +.BR xargs (1) +can be used to parallelize compression of many files: +.RS +.PP +.nf +.ft CR +find . \-type f \e! \-name '*.xz' \-print0 \e + | xargs \-0r \-P4 \-n16 xz \-T1 +.ft R +.fi +.RE +.PP +The +.B \-P +option to +.BR xargs (1) +sets the number of parallel +.B xz +processes. +The best value for the +.B \-n +option depends on how many files there are to be compressed. +If there are only a couple of files, +the value should probably be 1; +with tens of thousands of files, +100 or even more may be appropriate to reduce the number of +.B xz +processes that +.BR xargs (1) +will eventually create. +.PP +The option +.B \-T1 +for +.B xz +is there to force it to single-threaded mode, because +.BR xargs (1) +is used to control the amount of parallelization. +. +.SS "Robot mode" +Calculate how many bytes have been saved in total +after compressing multiple files: +.RS +.PP +.nf +.ft CR +xz \-\-robot \-\-list *.xz | awk '/^totals/{print $5\-$4}' +.ft R +.fi +.RE +.PP +A script may want to know that it is using new enough +.BR xz . +The following +.BR sh (1) +script checks that the version number of the +.B xz +tool is at least 5.0.0. +This method is compatible with old beta versions, +which didn't support the +.B \-\-robot +option: +.RS +.PP +.nf +.ft CR +if ! eval "$(xz \-\-robot \-\-version 2> /dev/null)" || + [ "$XZ_VERSION" \-lt 50000002 ]; then + echo "Your xz is too old." +fi +unset XZ_VERSION LIBLZMA_VERSION +.ft R +.fi +.RE +.PP +Set a memory usage limit for decompression using +.BR XZ_OPT , +but if a limit has already been set, don't increase it: +.RS +.PP +.nf +.ft CR +NEWLIM=$((123 << 20))\ \ # 123 MiB +OLDLIM=$(xz \-\-robot \-\-info\-memory | cut \-f3) +if [ $OLDLIM \-eq 0 \-o $OLDLIM \-gt $NEWLIM ]; then + XZ_OPT="$XZ_OPT \-\-memlimit\-decompress=$NEWLIM" + export XZ_OPT +fi +.ft R +.fi +.RE +. +.SS "Custom compressor filter chains" +The simplest use for custom filter chains is +customizing a LZMA2 preset. +This can be useful, +because the presets cover only a subset of the +potentially useful combinations of compression settings. +.PP +The CompCPU columns of the tables +from the descriptions of the options +.BR "\-0" " ... " "\-9" +and +.B \-\-extreme +are useful when customizing LZMA2 presets. +Here are the relevant parts collected from those two tables: +.RS +.PP +.TS +tab(;); +c c +n n. +Preset;CompCPU +\-0;0 +\-1;1 +\-2;2 +\-3;3 +\-4;4 +\-5;5 +\-6;6 +\-5e;7 +\-6e;8 +.TE +.RE +.PP +If you know that a file requires +somewhat big dictionary (for example, 32\ MiB) to compress well, +but you want to compress it quicker than +.B "xz \-8" +would do, a preset with a low CompCPU value (for example, 1) +can be modified to use a bigger dictionary: +.RS +.PP +.nf +.ft CR +xz \-\-lzma2=preset=1,dict=32MiB foo.tar +.ft R +.fi +.RE +.PP +With certain files, the above command may be faster than +.B "xz \-6" +while compressing significantly better. +However, it must be emphasized that only some files benefit from +a big dictionary while keeping the CompCPU value low. +The most obvious situation, +where a big dictionary can help a lot, +is an archive containing very similar files +of at least a few megabytes each. +The dictionary size has to be significantly bigger +than any individual file to allow LZMA2 to take +full advantage of the similarities between consecutive files. +.PP +If very high compressor and decompressor memory usage is fine, +and the file being compressed is +at least several hundred megabytes, it may be useful +to use an even bigger dictionary than the 64 MiB that +.B "xz \-9" +would use: +.RS +.PP +.nf +.ft CR +xz \-vv \-\-lzma2=dict=192MiB big_foo.tar +.ft R +.fi +.RE +.PP +Using +.B \-vv +.RB ( "\-\-verbose \-\-verbose" ) +like in the above example can be useful +to see the memory requirements +of the compressor and decompressor. +Remember that using a dictionary bigger than +the size of the uncompressed file is waste of memory, +so the above command isn't useful for small files. +.PP +Sometimes the compression time doesn't matter, +but the decompressor memory usage has to be kept low, for example, +to make it possible to decompress the file on an embedded system. +The following command uses +.B \-6e +.RB ( "\-6 \-\-extreme" ) +as a base and sets the dictionary to only 64\ KiB. +The resulting file can be decompressed with XZ Embedded +(that's why there is +.BR \-\-check=crc32 ) +using about 100\ KiB of memory. +.RS +.PP +.nf +.ft CR +xz \-\-check=crc32 \-\-lzma2=preset=6e,dict=64KiB foo +.ft R +.fi +.RE +.PP +If you want to squeeze out as many bytes as possible, +adjusting the number of literal context bits +.RI ( lc ) +and number of position bits +.RI ( pb ) +can sometimes help. +Adjusting the number of literal position bits +.RI ( lp ) +might help too, but usually +.I lc +and +.I pb +are more important. +For example, a source code archive contains mostly US-ASCII text, +so something like the following might give +slightly (like 0.1\ %) smaller file than +.B "xz \-6e" +(try also without +.BR lc=4 ): +.RS +.PP +.nf +.ft CR +xz \-\-lzma2=preset=6e,pb=0,lc=4 source_code.tar +.ft R +.fi +.RE +.PP +Using another filter together with LZMA2 can improve +compression with certain file types. +For example, to compress a x86-32 or x86-64 shared library +using the x86 BCJ filter: +.RS +.PP +.nf +.ft CR +xz \-\-x86 \-\-lzma2 libfoo.so +.ft R +.fi +.RE +.PP +Note that the order of the filter options is significant. +If +.B \-\-x86 +is specified after +.BR \-\-lzma2 , +.B xz +will give an error, +because there cannot be any filter after LZMA2, +and also because the x86 BCJ filter cannot be used +as the last filter in the chain. +.PP +The Delta filter together with LZMA2 +can give good results with bitmap images. +It should usually beat PNG, +which has a few more advanced filters than simple +delta but uses Deflate for the actual compression. +.PP +The image has to be saved in uncompressed format, +for example, as uncompressed TIFF. +The distance parameter of the Delta filter is set +to match the number of bytes per pixel in the image. +For example, 24-bit RGB bitmap needs +.BR dist=3 , +and it is also good to pass +.B pb=0 +to LZMA2 to accommodate the three-byte alignment: +.RS +.PP +.nf +.ft CR +xz \-\-delta=dist=3 \-\-lzma2=pb=0 foo.tiff +.ft R +.fi +.RE +.PP +If multiple images have been put into a single archive (for example, +.BR .tar ), +the Delta filter will work on that too as long as all images +have the same number of bytes per pixel. +. +.SH "SEE ALSO" +.BR xzdec (1), +.BR xzdiff (1), +.BR xzgrep (1), +.BR xzless (1), +.BR xzmore (1), +.BR gzip (1), +.BR bzip2 (1), +.BR 7z (1) +.PP +XZ Utils: +.br +XZ Embedded: +.br +LZMA SDK: diff --git a/cpp/third_party/xz-5.8.3/src/xz/xz_w32res.rc b/cpp/third_party/xz-5.8.3/src/xz/xz_w32res.rc new file mode 100644 index 000000000..e80903eb7 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/src/xz/xz_w32res.rc @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: 0BSD */ + +/* + * Author: Lasse Collin + */ + +#define MY_TYPE VFT_APP +#define MY_NAME "xz" +#define MY_SUFFIX ".exe" +#define MY_DESC "xz data compression tool for .xz and .lzma files" +#include "common_w32res.rc" diff --git a/cpp/third_party/xz-5.8.3/src/xzdec/Makefile.am b/cpp/third_party/xz-5.8.3/src/xzdec/Makefile.am new file mode 100644 index 000000000..c2810479a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/src/xzdec/Makefile.am @@ -0,0 +1,111 @@ +## SPDX-License-Identifier: 0BSD +## Author: Lasse Collin + +# Windows resource compiler support. It's fine to use xz_CPPFLAGS +# also for lzmadec. +.rc.o: + $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(xzdec_CPPFLAGS) $(CPPFLAGS) $(RCFLAGS) -i $< -o $@ + + +xzdec_SOURCES = \ + xzdec.c \ + ../common/tuklib_progname.c \ + ../common/tuklib_mbstr_nonprint.c \ + ../common/tuklib_exit.c + +if COND_W32 +xzdec_SOURCES += xzdec_w32res.rc +endif + +xzdec_CPPFLAGS = \ + -DTUKLIB_GETTEXT=0 \ + -I$(top_srcdir)/src/common \ + -I$(top_srcdir)/src/liblzma/api +xzdec_LDADD = $(top_builddir)/src/liblzma/liblzma.la + +if COND_GNULIB +xzdec_CPPFLAGS += \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib +xzdec_LDADD += $(top_builddir)/lib/libgnu.a +endif + +xzdec_LDADD += $(LTLIBINTL) + + +lzmadec_SOURCES = \ + xzdec.c \ + ../common/tuklib_progname.c \ + ../common/tuklib_mbstr_nonprint.c \ + ../common/tuklib_exit.c + +if COND_W32 +lzmadec_SOURCES += lzmadec_w32res.rc +endif + +lzmadec_CPPFLAGS = $(xzdec_CPPFLAGS) -DLZMADEC +lzmadec_LDFLAGS = $(xzdec_LDFLAGS) +lzmadec_LDADD = $(xzdec_LDADD) + + +bin_PROGRAMS = +lzmadecmanlink = + +if COND_XZDEC +bin_PROGRAMS += xzdec +dist_man_MANS = xzdec.1 +endif + +if COND_LZMADEC +bin_PROGRAMS += lzmadec + +# Create the symlink lzmadec.1->xzdec.1 only if xzdec.1 was installed. +# This is better than creating a dangling symlink. The correct solution +# would be to install xzdec.1 as lzmadec.1 but this code is already too +# complicated so I won't do it. Installing only lzmadec is a bit unusual +# situation anyway so it's not that important. +if COND_XZDEC +lzmadecmanlink += lzmadec +endif +endif + +if COND_XZDEC +# The installation of translated man pages abuses Automake internals +# by calling "install-man" with redefined dist_man_MANS and man_MANS. +# If this breaks some day, don't blame Automake developers. +install-data-hook: + languages= ; \ + if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \ + languages=`ls "$(top_srcdir)/po4a/man"`; \ + fi; \ + target=`echo xzdec | sed '$(transform)'` && \ + link=`echo lzmadec | sed '$(transform)'` && \ + for lang in . $$languages; do \ + man="$(top_srcdir)/po4a/man/$$lang/xzdec.1" ; \ + if test -f "$$man"; then \ + $(MAKE) dist_man_MANS="$$man" man_MANS= \ + mandir="$(mandir)/$$lang" install-man; \ + fi; \ + man1dir="$(DESTDIR)$(mandir)/$$lang/man1" && \ + if test -f "$$man1dir/$$target.1"; then \ + if test -n "$(lzmadecmanlink)"; then ( \ + cd "$$man1dir" && \ + rm -f "$$link.1" && \ + $(LN_S) "$$target.1" "$$link.1" \ + ); fi; \ + fi; \ + done + +uninstall-hook: + languages= ; \ + if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \ + languages=`ls "$(top_srcdir)/po4a/man"`; \ + fi; \ + for lang in . $$languages; do \ + for name in xzdec $(lzmadecmanlink); do \ + name=`echo $$name | sed '$(transform)'` && \ + rm -f "$(DESTDIR)$(mandir)/$$lang/man1/$$name.1"; \ + done; \ + done +endif diff --git a/cpp/third_party/xz-5.8.3/src/xzdec/Makefile.in b/cpp/third_party/xz-5.8.3/src/xzdec/Makefile.in new file mode 100644 index 000000000..ae52f881e --- /dev/null +++ b/cpp/third_party/xz-5.8.3/src/xzdec/Makefile.in @@ -0,0 +1,1019 @@ +# Makefile.in generated by automake 1.18.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2025 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)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) +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@ +@COND_W32_TRUE@am__append_1 = xzdec_w32res.rc +@COND_GNULIB_TRUE@am__append_2 = \ +@COND_GNULIB_TRUE@ -I$(top_builddir)/lib \ +@COND_GNULIB_TRUE@ -I$(top_srcdir)/lib + +@COND_GNULIB_TRUE@am__append_3 = $(top_builddir)/lib/libgnu.a +@COND_W32_TRUE@am__append_4 = lzmadec_w32res.rc +bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) +@COND_XZDEC_TRUE@am__append_5 = xzdec +@COND_LZMADEC_TRUE@am__append_6 = lzmadec + +# Create the symlink lzmadec.1->xzdec.1 only if xzdec.1 was installed. +# This is better than creating a dangling symlink. The correct solution +# would be to install xzdec.1 as lzmadec.1 but this code is already too +# complicated so I won't do it. Installing only lzmadec is a bit unusual +# situation anyway so it's not that important. +@COND_LZMADEC_TRUE@@COND_XZDEC_TRUE@am__append_7 = lzmadec +subdir = src/xzdec +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/build-to-host.m4 $(top_srcdir)/m4/getopt.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/host-cpu-c-abi.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/posix-shell.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/tuklib_common.m4 \ + $(top_srcdir)/m4/tuklib_cpucores.m4 \ + $(top_srcdir)/m4/tuklib_integer.m4 \ + $(top_srcdir)/m4/tuklib_mbstr.m4 \ + $(top_srcdir)/m4/tuklib_physmem.m4 \ + $(top_srcdir)/m4/tuklib_progname.m4 \ + $(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@COND_XZDEC_TRUE@am__EXEEXT_1 = xzdec$(EXEEXT) +@COND_LZMADEC_TRUE@am__EXEEXT_2 = lzmadec$(EXEEXT) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +am__lzmadec_SOURCES_DIST = xzdec.c ../common/tuklib_progname.c \ + ../common/tuklib_mbstr_nonprint.c ../common/tuklib_exit.c \ + lzmadec_w32res.rc +@COND_W32_TRUE@am__objects_1 = lzmadec_w32res.$(OBJEXT) +am_lzmadec_OBJECTS = lzmadec-xzdec.$(OBJEXT) \ + lzmadec-tuklib_progname.$(OBJEXT) \ + lzmadec-tuklib_mbstr_nonprint.$(OBJEXT) \ + lzmadec-tuklib_exit.$(OBJEXT) $(am__objects_1) +lzmadec_OBJECTS = $(am_lzmadec_OBJECTS) +am__DEPENDENCIES_1 = +am__DEPENDENCIES_2 = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__append_3) $(am__DEPENDENCIES_1) +lzmadec_DEPENDENCIES = $(am__DEPENDENCIES_2) +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 = +lzmadec_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(lzmadec_LDFLAGS) $(LDFLAGS) -o $@ +am__xzdec_SOURCES_DIST = xzdec.c ../common/tuklib_progname.c \ + ../common/tuklib_mbstr_nonprint.c ../common/tuklib_exit.c \ + xzdec_w32res.rc +@COND_W32_TRUE@am__objects_2 = xzdec_w32res.$(OBJEXT) +am_xzdec_OBJECTS = xzdec-xzdec.$(OBJEXT) \ + xzdec-tuklib_progname.$(OBJEXT) \ + xzdec-tuklib_mbstr_nonprint.$(OBJEXT) \ + xzdec-tuklib_exit.$(OBJEXT) $(am__objects_2) +xzdec_OBJECTS = $(am_xzdec_OBJECTS) +xzdec_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__append_3) $(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@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/lzmadec-tuklib_exit.Po \ + ./$(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Po \ + ./$(DEPDIR)/lzmadec-tuklib_progname.Po \ + ./$(DEPDIR)/lzmadec-xzdec.Po ./$(DEPDIR)/xzdec-tuklib_exit.Po \ + ./$(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Po \ + ./$(DEPDIR)/xzdec-tuklib_progname.Po \ + ./$(DEPDIR)/xzdec-xzdec.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 = $(lzmadec_SOURCES) $(xzdec_SOURCES) +DIST_SOURCES = $(am__lzmadec_SOURCES_DIST) $(am__xzdec_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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 ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(dist_man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# 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__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ +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@ +FILECMD = @FILECMD@ +GETOPT_H = @GETOPT_H@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LINKER_FLAG_UNDEFINED_VERSION = @LINKER_FLAG_UNDEFINED_VERSION@ +LIPO = @LIPO@ +LN_EXEEXT = @LN_EXEEXT@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +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@ +POSIX_SHELL = @POSIX_SHELL@ +POSUB = @POSUB@ +PREFERABLY_POSIX_SHELL = @PREFERABLY_POSIX_SHELL@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +RC = @RC@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +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__rm_f_notfound = @am__rm_f_notfound@ +am__tar = @am__tar@ +am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ +ax_pthread_config = @ax_pthread_config@ +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@ +enable_path_for_scripts = @enable_path_for_scripts@ +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@ +localedir_c = @localedir_c@ +localedir_c_make = @localedir_c_make@ +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@ +xz = @xz@ +xzdec_SOURCES = xzdec.c ../common/tuklib_progname.c \ + ../common/tuklib_mbstr_nonprint.c ../common/tuklib_exit.c \ + $(am__append_1) +xzdec_CPPFLAGS = -DTUKLIB_GETTEXT=0 -I$(top_srcdir)/src/common \ + -I$(top_srcdir)/src/liblzma/api $(am__append_2) +xzdec_LDADD = $(top_builddir)/src/liblzma/liblzma.la $(am__append_3) \ + $(LTLIBINTL) +lzmadec_SOURCES = xzdec.c ../common/tuklib_progname.c \ + ../common/tuklib_mbstr_nonprint.c ../common/tuklib_exit.c \ + $(am__append_4) +lzmadec_CPPFLAGS = $(xzdec_CPPFLAGS) -DLZMADEC +lzmadec_LDFLAGS = $(xzdec_LDFLAGS) +lzmadec_LDADD = $(xzdec_LDADD) +lzmadecmanlink = $(am__append_7) +@COND_XZDEC_TRUE@dist_man_MANS = xzdec.1 +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj .rc +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/xzdec/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/xzdec/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +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)" && $(am__rm_f) $$files + +clean-binPROGRAMS: + $(am__rm_f) $(bin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) + +lzmadec$(EXEEXT): $(lzmadec_OBJECTS) $(lzmadec_DEPENDENCIES) $(EXTRA_lzmadec_DEPENDENCIES) + @rm -f lzmadec$(EXEEXT) + $(AM_V_CCLD)$(lzmadec_LINK) $(lzmadec_OBJECTS) $(lzmadec_LDADD) $(LIBS) + +xzdec$(EXEEXT): $(xzdec_OBJECTS) $(xzdec_DEPENDENCIES) $(EXTRA_xzdec_DEPENDENCIES) + @rm -f xzdec$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(xzdec_OBJECTS) $(xzdec_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzmadec-tuklib_exit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzmadec-tuklib_progname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzmadec-xzdec.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xzdec-tuklib_exit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xzdec-tuklib_progname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xzdec-xzdec.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @: >>$@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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 $@ $< + +lzmadec-xzdec.o: xzdec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzmadec-xzdec.o -MD -MP -MF $(DEPDIR)/lzmadec-xzdec.Tpo -c -o lzmadec-xzdec.o `test -f 'xzdec.c' || echo '$(srcdir)/'`xzdec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lzmadec-xzdec.Tpo $(DEPDIR)/lzmadec-xzdec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xzdec.c' object='lzmadec-xzdec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzmadec-xzdec.o `test -f 'xzdec.c' || echo '$(srcdir)/'`xzdec.c + +lzmadec-xzdec.obj: xzdec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzmadec-xzdec.obj -MD -MP -MF $(DEPDIR)/lzmadec-xzdec.Tpo -c -o lzmadec-xzdec.obj `if test -f 'xzdec.c'; then $(CYGPATH_W) 'xzdec.c'; else $(CYGPATH_W) '$(srcdir)/xzdec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lzmadec-xzdec.Tpo $(DEPDIR)/lzmadec-xzdec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xzdec.c' object='lzmadec-xzdec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzmadec-xzdec.obj `if test -f 'xzdec.c'; then $(CYGPATH_W) 'xzdec.c'; else $(CYGPATH_W) '$(srcdir)/xzdec.c'; fi` + +lzmadec-tuklib_progname.o: ../common/tuklib_progname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzmadec-tuklib_progname.o -MD -MP -MF $(DEPDIR)/lzmadec-tuklib_progname.Tpo -c -o lzmadec-tuklib_progname.o `test -f '../common/tuklib_progname.c' || echo '$(srcdir)/'`../common/tuklib_progname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lzmadec-tuklib_progname.Tpo $(DEPDIR)/lzmadec-tuklib_progname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_progname.c' object='lzmadec-tuklib_progname.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzmadec-tuklib_progname.o `test -f '../common/tuklib_progname.c' || echo '$(srcdir)/'`../common/tuklib_progname.c + +lzmadec-tuklib_progname.obj: ../common/tuklib_progname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzmadec-tuklib_progname.obj -MD -MP -MF $(DEPDIR)/lzmadec-tuklib_progname.Tpo -c -o lzmadec-tuklib_progname.obj `if test -f '../common/tuklib_progname.c'; then $(CYGPATH_W) '../common/tuklib_progname.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_progname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lzmadec-tuklib_progname.Tpo $(DEPDIR)/lzmadec-tuklib_progname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_progname.c' object='lzmadec-tuklib_progname.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzmadec-tuklib_progname.obj `if test -f '../common/tuklib_progname.c'; then $(CYGPATH_W) '../common/tuklib_progname.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_progname.c'; fi` + +lzmadec-tuklib_mbstr_nonprint.o: ../common/tuklib_mbstr_nonprint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzmadec-tuklib_mbstr_nonprint.o -MD -MP -MF $(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Tpo -c -o lzmadec-tuklib_mbstr_nonprint.o `test -f '../common/tuklib_mbstr_nonprint.c' || echo '$(srcdir)/'`../common/tuklib_mbstr_nonprint.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Tpo $(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_mbstr_nonprint.c' object='lzmadec-tuklib_mbstr_nonprint.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzmadec-tuklib_mbstr_nonprint.o `test -f '../common/tuklib_mbstr_nonprint.c' || echo '$(srcdir)/'`../common/tuklib_mbstr_nonprint.c + +lzmadec-tuklib_mbstr_nonprint.obj: ../common/tuklib_mbstr_nonprint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzmadec-tuklib_mbstr_nonprint.obj -MD -MP -MF $(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Tpo -c -o lzmadec-tuklib_mbstr_nonprint.obj `if test -f '../common/tuklib_mbstr_nonprint.c'; then $(CYGPATH_W) '../common/tuklib_mbstr_nonprint.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_mbstr_nonprint.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Tpo $(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_mbstr_nonprint.c' object='lzmadec-tuklib_mbstr_nonprint.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzmadec-tuklib_mbstr_nonprint.obj `if test -f '../common/tuklib_mbstr_nonprint.c'; then $(CYGPATH_W) '../common/tuklib_mbstr_nonprint.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_mbstr_nonprint.c'; fi` + +lzmadec-tuklib_exit.o: ../common/tuklib_exit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzmadec-tuklib_exit.o -MD -MP -MF $(DEPDIR)/lzmadec-tuklib_exit.Tpo -c -o lzmadec-tuklib_exit.o `test -f '../common/tuklib_exit.c' || echo '$(srcdir)/'`../common/tuklib_exit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lzmadec-tuklib_exit.Tpo $(DEPDIR)/lzmadec-tuklib_exit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_exit.c' object='lzmadec-tuklib_exit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzmadec-tuklib_exit.o `test -f '../common/tuklib_exit.c' || echo '$(srcdir)/'`../common/tuklib_exit.c + +lzmadec-tuklib_exit.obj: ../common/tuklib_exit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lzmadec-tuklib_exit.obj -MD -MP -MF $(DEPDIR)/lzmadec-tuklib_exit.Tpo -c -o lzmadec-tuklib_exit.obj `if test -f '../common/tuklib_exit.c'; then $(CYGPATH_W) '../common/tuklib_exit.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_exit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lzmadec-tuklib_exit.Tpo $(DEPDIR)/lzmadec-tuklib_exit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_exit.c' object='lzmadec-tuklib_exit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lzmadec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lzmadec-tuklib_exit.obj `if test -f '../common/tuklib_exit.c'; then $(CYGPATH_W) '../common/tuklib_exit.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_exit.c'; fi` + +xzdec-xzdec.o: xzdec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xzdec-xzdec.o -MD -MP -MF $(DEPDIR)/xzdec-xzdec.Tpo -c -o xzdec-xzdec.o `test -f 'xzdec.c' || echo '$(srcdir)/'`xzdec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xzdec-xzdec.Tpo $(DEPDIR)/xzdec-xzdec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xzdec.c' object='xzdec-xzdec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xzdec-xzdec.o `test -f 'xzdec.c' || echo '$(srcdir)/'`xzdec.c + +xzdec-xzdec.obj: xzdec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xzdec-xzdec.obj -MD -MP -MF $(DEPDIR)/xzdec-xzdec.Tpo -c -o xzdec-xzdec.obj `if test -f 'xzdec.c'; then $(CYGPATH_W) 'xzdec.c'; else $(CYGPATH_W) '$(srcdir)/xzdec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xzdec-xzdec.Tpo $(DEPDIR)/xzdec-xzdec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xzdec.c' object='xzdec-xzdec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xzdec-xzdec.obj `if test -f 'xzdec.c'; then $(CYGPATH_W) 'xzdec.c'; else $(CYGPATH_W) '$(srcdir)/xzdec.c'; fi` + +xzdec-tuklib_progname.o: ../common/tuklib_progname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xzdec-tuklib_progname.o -MD -MP -MF $(DEPDIR)/xzdec-tuklib_progname.Tpo -c -o xzdec-tuklib_progname.o `test -f '../common/tuklib_progname.c' || echo '$(srcdir)/'`../common/tuklib_progname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xzdec-tuklib_progname.Tpo $(DEPDIR)/xzdec-tuklib_progname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_progname.c' object='xzdec-tuklib_progname.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xzdec-tuklib_progname.o `test -f '../common/tuklib_progname.c' || echo '$(srcdir)/'`../common/tuklib_progname.c + +xzdec-tuklib_progname.obj: ../common/tuklib_progname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xzdec-tuklib_progname.obj -MD -MP -MF $(DEPDIR)/xzdec-tuklib_progname.Tpo -c -o xzdec-tuklib_progname.obj `if test -f '../common/tuklib_progname.c'; then $(CYGPATH_W) '../common/tuklib_progname.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_progname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xzdec-tuklib_progname.Tpo $(DEPDIR)/xzdec-tuklib_progname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_progname.c' object='xzdec-tuklib_progname.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xzdec-tuklib_progname.obj `if test -f '../common/tuklib_progname.c'; then $(CYGPATH_W) '../common/tuklib_progname.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_progname.c'; fi` + +xzdec-tuklib_mbstr_nonprint.o: ../common/tuklib_mbstr_nonprint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xzdec-tuklib_mbstr_nonprint.o -MD -MP -MF $(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Tpo -c -o xzdec-tuklib_mbstr_nonprint.o `test -f '../common/tuklib_mbstr_nonprint.c' || echo '$(srcdir)/'`../common/tuklib_mbstr_nonprint.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Tpo $(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_mbstr_nonprint.c' object='xzdec-tuklib_mbstr_nonprint.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xzdec-tuklib_mbstr_nonprint.o `test -f '../common/tuklib_mbstr_nonprint.c' || echo '$(srcdir)/'`../common/tuklib_mbstr_nonprint.c + +xzdec-tuklib_mbstr_nonprint.obj: ../common/tuklib_mbstr_nonprint.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xzdec-tuklib_mbstr_nonprint.obj -MD -MP -MF $(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Tpo -c -o xzdec-tuklib_mbstr_nonprint.obj `if test -f '../common/tuklib_mbstr_nonprint.c'; then $(CYGPATH_W) '../common/tuklib_mbstr_nonprint.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_mbstr_nonprint.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Tpo $(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_mbstr_nonprint.c' object='xzdec-tuklib_mbstr_nonprint.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xzdec-tuklib_mbstr_nonprint.obj `if test -f '../common/tuklib_mbstr_nonprint.c'; then $(CYGPATH_W) '../common/tuklib_mbstr_nonprint.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_mbstr_nonprint.c'; fi` + +xzdec-tuklib_exit.o: ../common/tuklib_exit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xzdec-tuklib_exit.o -MD -MP -MF $(DEPDIR)/xzdec-tuklib_exit.Tpo -c -o xzdec-tuklib_exit.o `test -f '../common/tuklib_exit.c' || echo '$(srcdir)/'`../common/tuklib_exit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xzdec-tuklib_exit.Tpo $(DEPDIR)/xzdec-tuklib_exit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_exit.c' object='xzdec-tuklib_exit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xzdec-tuklib_exit.o `test -f '../common/tuklib_exit.c' || echo '$(srcdir)/'`../common/tuklib_exit.c + +xzdec-tuklib_exit.obj: ../common/tuklib_exit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xzdec-tuklib_exit.obj -MD -MP -MF $(DEPDIR)/xzdec-tuklib_exit.Tpo -c -o xzdec-tuklib_exit.obj `if test -f '../common/tuklib_exit.c'; then $(CYGPATH_W) '../common/tuklib_exit.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_exit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xzdec-tuklib_exit.Tpo $(DEPDIR)/xzdec-tuklib_exit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../common/tuklib_exit.c' object='xzdec-tuklib_exit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xzdec_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xzdec-tuklib_exit.obj `if test -f '../common/tuklib_exit.c'; then $(CYGPATH_W) '../common/tuklib_exit.c'; else $(CYGPATH_W) '$(srcdir)/../common/tuklib_exit.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(dist_man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_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='$(dist_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) + +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" +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 + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @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 +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: 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: + +clean-generic: + +distclean-generic: + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@COND_XZDEC_FALSE@install-data-hook: +@COND_XZDEC_FALSE@uninstall-hook: +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/lzmadec-tuklib_exit.Po + -rm -f ./$(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Po + -rm -f ./$(DEPDIR)/lzmadec-tuklib_progname.Po + -rm -f ./$(DEPDIR)/lzmadec-xzdec.Po + -rm -f ./$(DEPDIR)/xzdec-tuklib_exit.Po + -rm -f ./$(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Po + -rm -f ./$(DEPDIR)/xzdec-tuklib_progname.Po + -rm -f ./$(DEPDIR)/xzdec-xzdec.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 + +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 ./$(DEPDIR)/lzmadec-tuklib_exit.Po + -rm -f ./$(DEPDIR)/lzmadec-tuklib_mbstr_nonprint.Po + -rm -f ./$(DEPDIR)/lzmadec-tuklib_progname.Po + -rm -f ./$(DEPDIR)/lzmadec-xzdec.Po + -rm -f ./$(DEPDIR)/xzdec-tuklib_exit.Po + -rm -f ./$(DEPDIR)/xzdec-tuklib_mbstr_nonprint.Po + -rm -f ./$(DEPDIR)/xzdec-tuklib_progname.Po + -rm -f ./$(DEPDIR)/xzdec-xzdec.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-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +uninstall-man: uninstall-man1 + +.MAKE: install-am install-data-am install-strip uninstall-am + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-data-hook install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man1 install-pdf install-pdf-am 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 tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-hook \ + uninstall-man uninstall-man1 + +.PRECIOUS: Makefile + + +# Windows resource compiler support. It's fine to use xz_CPPFLAGS +# also for lzmadec. +.rc.o: + $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(xzdec_CPPFLAGS) $(CPPFLAGS) $(RCFLAGS) -i $< -o $@ + +# The installation of translated man pages abuses Automake internals +# by calling "install-man" with redefined dist_man_MANS and man_MANS. +# If this breaks some day, don't blame Automake developers. +@COND_XZDEC_TRUE@install-data-hook: +@COND_XZDEC_TRUE@ languages= ; \ +@COND_XZDEC_TRUE@ if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \ +@COND_XZDEC_TRUE@ languages=`ls "$(top_srcdir)/po4a/man"`; \ +@COND_XZDEC_TRUE@ fi; \ +@COND_XZDEC_TRUE@ target=`echo xzdec | sed '$(transform)'` && \ +@COND_XZDEC_TRUE@ link=`echo lzmadec | sed '$(transform)'` && \ +@COND_XZDEC_TRUE@ for lang in . $$languages; do \ +@COND_XZDEC_TRUE@ man="$(top_srcdir)/po4a/man/$$lang/xzdec.1" ; \ +@COND_XZDEC_TRUE@ if test -f "$$man"; then \ +@COND_XZDEC_TRUE@ $(MAKE) dist_man_MANS="$$man" man_MANS= \ +@COND_XZDEC_TRUE@ mandir="$(mandir)/$$lang" install-man; \ +@COND_XZDEC_TRUE@ fi; \ +@COND_XZDEC_TRUE@ man1dir="$(DESTDIR)$(mandir)/$$lang/man1" && \ +@COND_XZDEC_TRUE@ if test -f "$$man1dir/$$target.1"; then \ +@COND_XZDEC_TRUE@ if test -n "$(lzmadecmanlink)"; then ( \ +@COND_XZDEC_TRUE@ cd "$$man1dir" && \ +@COND_XZDEC_TRUE@ rm -f "$$link.1" && \ +@COND_XZDEC_TRUE@ $(LN_S) "$$target.1" "$$link.1" \ +@COND_XZDEC_TRUE@ ); fi; \ +@COND_XZDEC_TRUE@ fi; \ +@COND_XZDEC_TRUE@ done + +@COND_XZDEC_TRUE@uninstall-hook: +@COND_XZDEC_TRUE@ languages= ; \ +@COND_XZDEC_TRUE@ if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \ +@COND_XZDEC_TRUE@ languages=`ls "$(top_srcdir)/po4a/man"`; \ +@COND_XZDEC_TRUE@ fi; \ +@COND_XZDEC_TRUE@ for lang in . $$languages; do \ +@COND_XZDEC_TRUE@ for name in xzdec $(lzmadecmanlink); do \ +@COND_XZDEC_TRUE@ name=`echo $$name | sed '$(transform)'` && \ +@COND_XZDEC_TRUE@ rm -f "$(DESTDIR)$(mandir)/$$lang/man1/$$name.1"; \ +@COND_XZDEC_TRUE@ done; \ +@COND_XZDEC_TRUE@ done + +# 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: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/cpp/third_party/xz-5.8.3/src/xzdec/lzmadec_w32res.rc b/cpp/third_party/xz-5.8.3/src/xzdec/lzmadec_w32res.rc new file mode 100644 index 000000000..b4b89b1f3 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/src/xzdec/lzmadec_w32res.rc @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: 0BSD */ + +/* + * Author: Lasse Collin + */ + +#define MY_TYPE VFT_APP +#define MY_NAME "lzmadec" +#define MY_SUFFIX ".exe" +#define MY_DESC "lzmadec decompression tool for .lzma files" +#include "common_w32res.rc" diff --git a/cpp/third_party/xz-5.8.3/src/xzdec/xzdec.1 b/cpp/third_party/xz-5.8.3/src/xzdec/xzdec.1 new file mode 100644 index 000000000..5198efb46 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/src/xzdec/xzdec.1 @@ -0,0 +1,144 @@ +.\" SPDX-License-Identifier: 0BSD +.\" +.\" Author: Lasse Collin +.\" +.TH XZDEC 1 "2024-04-08" "Tukaani" "XZ Utils" +.SH NAME +xzdec, lzmadec \- Small .xz and .lzma decompressors +.SH SYNOPSIS +.B xzdec +.RI [ option... ] +.RI [ file... ] +.br +.B lzmadec +.RI [ option... ] +.RI [ file... ] +.SH DESCRIPTION +.B xzdec +is a liblzma-based decompression-only tool for +.B .xz +(and only +.BR .xz ) +files. +.B xzdec +is intended to work as a drop-in replacement for +.BR xz (1) +in the most common situations where a script +has been written to use +.B "xz \-\-decompress \-\-stdout" +(and possibly a few other commonly used options) to decompress +.B .xz +files. +.B lzmadec +is identical to +.B xzdec +except that +.B lzmadec +supports +.B .lzma +files instead of +.B .xz +files. +.PP +To reduce the size of the executable, +.B xzdec +doesn't support multithreading or localization, +and doesn't read options from +.B XZ_DEFAULTS +and +.B XZ_OPT +environment variables. +.B xzdec +doesn't support displaying intermediate progress information: sending +.B SIGINFO +to +.B xzdec +does nothing, but sending +.B SIGUSR1 +terminates the process instead of displaying progress information. +.SH OPTIONS +.TP +.BR \-d ", " \-\-decompress ", " \-\-uncompress +Ignored for +.BR xz (1) +compatibility. +.B xzdec +supports only decompression. +.TP +.BR \-k ", " \-\-keep +Ignored for +.BR xz (1) +compatibility. +.B xzdec +never creates or removes any files. +.TP +.BR \-c ", " \-\-stdout ", " \-\-to-stdout +Ignored for +.BR xz (1) +compatibility. +.B xzdec +always writes the decompressed data to standard output. +.TP +.BR \-q ", " \-\-quiet +Specifying this once does nothing since +.B xzdec +never displays any warnings or notices. +Specify this twice to suppress errors. +.TP +.BR \-Q ", " \-\-no-warn +Ignored for +.BR xz (1) +compatibility. +.B xzdec +never uses the exit status 2. +.TP +.BR \-h ", " \-\-help +Display a help message and exit successfully. +.TP +.BR \-V ", " \-\-version +Display the version number of +.B xzdec +and liblzma. +.SH "EXIT STATUS" +.TP +.B 0 +All was good. +.TP +.B 1 +An error occurred. +.PP +.B xzdec +doesn't have any warning messages like +.BR xz (1) +has, thus the exit status 2 is not used by +.BR xzdec . +.SH NOTES +Use +.BR xz (1) +instead of +.B xzdec +or +.B lzmadec +for normal everyday use. +.B xzdec +or +.B lzmadec +are meant only for situations where it is important to have +a smaller decompressor than the full-featured +.BR xz (1). +.PP +.B xzdec +and +.B lzmadec +are not really that small. +The size can be reduced further by dropping +features from liblzma at compile time, +but that shouldn't usually be done for executables distributed +in typical non-embedded operating system distributions. +If you need a truly small +.B .xz +decompressor, consider using XZ Embedded. +.SH "SEE ALSO" +.BR xz (1) +.PP +XZ Embedded: diff --git a/cpp/third_party/xz-5.8.3/src/xzdec/xzdec.c b/cpp/third_party/xz-5.8.3/src/xzdec/xzdec.c new file mode 100644 index 000000000..e1e274491 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/src/xzdec/xzdec.c @@ -0,0 +1,489 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file xzdec.c +/// \brief Simple single-threaded tool to uncompress .xz or .lzma files +// +// Author: Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include "sysdefs.h" +#include "lzma.h" + +#include +#include +#include +#include + +#ifndef _MSC_VER +# include +#endif + +#ifdef HAVE_CAP_RIGHTS_LIMIT +# include +#endif + +#ifdef HAVE_LINUX_LANDLOCK +# include "my_landlock.h" +#endif + +#if defined(HAVE_CAP_RIGHTS_LIMIT) || defined(HAVE_PLEDGE) \ + || defined(HAVE_LINUX_LANDLOCK) +# define ENABLE_SANDBOX 1 +#endif + +#include "getopt.h" +#include "tuklib_progname.h" +#include "tuklib_mbstr_nonprint.h" +#include "tuklib_exit.h" + +#ifdef TUKLIB_DOSLIKE +# include +# include +# ifdef _MSC_VER +# define fileno _fileno +# define setmode _setmode +# endif +#endif + + +#ifdef LZMADEC +# define TOOL_FORMAT "lzma" +#else +# define TOOL_FORMAT "xz" +#endif + + +/// Error messages are suppressed if this is zero, which is the case when +/// --quiet has been given at least twice. +static int display_errors = 2; + + +lzma_attribute((__format__(__printf__, 1, 2))) +static void +my_errorf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + if (display_errors) { + fprintf(stderr, "%s: ", progname); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + } + + va_end(ap); + return; +} + + +tuklib_attr_noreturn +static void +help(void) +{ + printf( +"Usage: %s [OPTION]... [FILE]...\n" +"Decompress files in the ." TOOL_FORMAT " format to standard output.\n" +"\n" +" -d, --decompress (ignored, only decompression is supported)\n" +" -k, --keep (ignored, files are never deleted)\n" +" -c, --stdout (ignored, output is always written to standard output)\n" +" -q, --quiet specify *twice* to suppress errors\n" +" -Q, --no-warn (ignored, the exit status 2 is never used)\n" +" -h, --help display this help and exit\n" +" -V, --version display the version number and exit\n" +"\n" +"With no FILE, or when FILE is -, read standard input.\n" +"\n" +"Report bugs to <" PACKAGE_BUGREPORT "> (in English or Finnish).\n" +PACKAGE_NAME " home page: <" PACKAGE_URL ">\n", progname); + + tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, display_errors); +} + + +tuklib_attr_noreturn +static void +version(void) +{ + printf(TOOL_FORMAT "dec (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n" + "liblzma %s\n", lzma_version_string()); + + tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, display_errors); +} + + +/// Parses command line options. +static void +parse_options(int argc, char **argv) +{ + static const char short_opts[] = "cdkhqQV"; + static const struct option long_opts[] = { + { "stdout", no_argument, NULL, 'c' }, + { "to-stdout", no_argument, NULL, 'c' }, + { "decompress", no_argument, NULL, 'd' }, + { "uncompress", no_argument, NULL, 'd' }, + { "keep", no_argument, NULL, 'k' }, + { "quiet", no_argument, NULL, 'q' }, + { "no-warn", no_argument, NULL, 'Q' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } + }; + + int c; + + while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) + != -1) { + switch (c) { + case 'c': + case 'd': + case 'k': + case 'Q': + break; + + case 'q': + if (display_errors > 0) + --display_errors; + + break; + + case 'h': + help(); + + case 'V': + version(); + + default: + exit(EXIT_FAILURE); + } + } + + return; +} + + +static void +uncompress(lzma_stream *strm, FILE *file, const char *filename) +{ + lzma_ret ret; + + // Initialize the decoder +#ifdef LZMADEC + ret = lzma_alone_decoder(strm, UINT64_MAX); +#else + ret = lzma_stream_decoder(strm, UINT64_MAX, LZMA_CONCATENATED); +#endif + + // The only reasonable error here is LZMA_MEM_ERROR. + if (ret != LZMA_OK) { + my_errorf("%s", ret == LZMA_MEM_ERROR ? strerror(ENOMEM) + : "Internal error (bug)"); + exit(EXIT_FAILURE); + } + + // Input and output buffers + uint8_t in_buf[BUFSIZ]; + uint8_t out_buf[BUFSIZ]; + + strm->avail_in = 0; + strm->next_out = out_buf; + strm->avail_out = BUFSIZ; + + lzma_action action = LZMA_RUN; + + while (true) { + if (strm->avail_in == 0) { + strm->next_in = in_buf; + strm->avail_in = fread(in_buf, 1, BUFSIZ, file); + + if (ferror(file)) { + // POSIX says that fread() sets errno if + // an error occurred. ferror() doesn't + // touch errno. + my_errorf("%s: Error reading input file: %s", + tuklib_mask_nonprint(filename), + strerror(errno)); + exit(EXIT_FAILURE); + } + +#ifndef LZMADEC + // When using LZMA_CONCATENATED, we need to tell + // liblzma when it has got all the input. + if (feof(file)) + action = LZMA_FINISH; +#endif + } + + ret = lzma_code(strm, action); + + // Write and check write error before checking decoder error. + // This way as much data as possible gets written to output + // even if decoder detected an error. + if (strm->avail_out == 0 || ret != LZMA_OK) { + const size_t write_size = BUFSIZ - strm->avail_out; + + if (fwrite(out_buf, 1, write_size, stdout) + != write_size) { + // Wouldn't be a surprise if writing to stderr + // would fail too but at least try to show an + // error message. +#if defined(_WIN32) && !defined(__CYGWIN__) + // On native Windows, broken pipe is reported + // as EINVAL. Don't show an error message + // in this case. + if (errno != EINVAL) +#endif + { + my_errorf("Cannot write to " + "standard output: " + "%s", strerror(errno)); + } + exit(EXIT_FAILURE); + } + + strm->next_out = out_buf; + strm->avail_out = BUFSIZ; + } + + if (ret != LZMA_OK) { + if (ret == LZMA_STREAM_END) { +#ifdef LZMADEC + // Check that there's no trailing garbage. + if (strm->avail_in != 0 + || fread(in_buf, 1, 1, file) + != 0 + || !feof(file)) + ret = LZMA_DATA_ERROR; + else + return; +#else + // lzma_stream_decoder() already guarantees + // that there's no trailing garbage. + assert(strm->avail_in == 0); + assert(action == LZMA_FINISH); + assert(feof(file)); + return; +#endif + } + + const char *msg; + switch (ret) { + case LZMA_MEM_ERROR: + msg = strerror(ENOMEM); + break; + + case LZMA_FORMAT_ERROR: + msg = "File format not recognized"; + break; + + case LZMA_OPTIONS_ERROR: + // FIXME: Better message? + msg = "Unsupported compression options"; + break; + + case LZMA_DATA_ERROR: + msg = "File is corrupt"; + break; + + case LZMA_BUF_ERROR: + msg = "Unexpected end of input"; + break; + + default: + msg = "Internal error (bug)"; + break; + } + + my_errorf("%s: %s", tuklib_mask_nonprint(filename), + msg); + exit(EXIT_FAILURE); + } + } +} + + +#ifdef ENABLE_SANDBOX +static void +sandbox_enter(int src_fd) +{ +#if defined(HAVE_CAP_RIGHTS_LIMIT) + // Capsicum needs FreeBSD 10.2 or later. + cap_rights_t rights; + + if (cap_enter()) + goto error; + + if (cap_rights_limit(src_fd, cap_rights_init(&rights, CAP_READ))) + goto error; + + // If not reading from stdin, remove all capabilities from it. + if (src_fd != STDIN_FILENO && cap_rights_limit( + STDIN_FILENO, cap_rights_init(&rights))) + goto error; + + if (cap_rights_limit(STDOUT_FILENO, cap_rights_init(&rights, + CAP_WRITE))) + goto error; + + if (cap_rights_limit(STDERR_FILENO, cap_rights_init(&rights, + CAP_WRITE))) + goto error; + +#elif defined(HAVE_PLEDGE) + // pledge() was introduced in OpenBSD 5.9. + if (pledge("stdio", "")) + goto error; + + (void)src_fd; + +#elif defined(HAVE_LINUX_LANDLOCK) + struct landlock_ruleset_attr attr; + if (my_landlock_ruleset_attr_forbid_all(&attr) > 0) { + const int ruleset_fd = my_landlock_create_ruleset( + &attr, sizeof(attr), 0); + if (ruleset_fd < 0) + goto error; + + // All files we need should have already been opened. Thus, + // we don't need to add any rules using landlock_add_rule(2) + // before activating the sandbox. + if (my_landlock_restrict_self(ruleset_fd, 0) != 0) + goto error; + + (void)close(ruleset_fd); + } + + (void)src_fd; + +#else +# error ENABLE_SANDBOX is defined but no sandboxing method was found. +#endif + + return; + +error: +#ifdef HAVE_CAP_RIGHTS_LIMIT + // If a kernel is configured without capability mode support or + // used in an emulator that does not implement the capability + // system calls, then the Capsicum system calls will fail and set + // errno to ENOSYS. In that case xzdec will silently run without + // the sandbox. + if (errno == ENOSYS) + return; +#endif + + my_errorf("Failed to enable the sandbox"); + exit(EXIT_FAILURE); +} +#endif + + +int +main(int argc, char **argv) +{ + // Initialize progname which will be used in error messages. + tuklib_progname_init(argv); + +#ifdef HAVE_PLEDGE + // OpenBSD's pledge(2) sandbox. + // Initially enable the sandbox slightly more relaxed so that + // the process can still open files. This allows the sandbox to + // be enabled when parsing command line arguments and decompressing + // all files (the more strict sandbox only restricts the last file + // that is decompressed). + if (pledge("stdio rpath", "")) { + my_errorf("Failed to enable the sandbox"); + exit(EXIT_FAILURE); + } +#endif + +#ifdef HAVE_LINUX_LANDLOCK + // Prevent the process from gaining new privileges. This must be done + // before landlock_restrict_self(2) but since we will never need new + // privileges, this call can be done here already. + // + // This is supported since Linux 3.5. Ignore the return value to + // keep compatibility with old kernels. landlock_restrict_self(2) + // will fail if the no_new_privs attribute isn't set, thus if prctl() + // fails here the error will still be detected when it matters. + (void)prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); +#endif + + // We need to set the locale even though we don't have any + // translated messages: + // + // - tuklib_mask_nonprint() has locale-specific behavior (LC_CTYPE). + // + // - This is needed on Windows to make non-ASCII filenames display + // properly when the active code page has been set to UTF-8 + // in the application manifest. + setlocale(LC_ALL, ""); + + // Parse the command line options. + parse_options(argc, argv); + + // The same lzma_stream is used for all files that we decode. This way + // we don't need to reallocate memory for every file if they use same + // compression settings. + lzma_stream strm = LZMA_STREAM_INIT; + + // Some systems require setting stdin and stdout to binary mode. +#ifdef TUKLIB_DOSLIKE + setmode(fileno(stdin), O_BINARY); + setmode(fileno(stdout), O_BINARY); +#endif + + if (optind == argc) { + // No filenames given, decode from stdin. +#ifdef ENABLE_SANDBOX + sandbox_enter(STDIN_FILENO); +#endif + uncompress(&strm, stdin, "(stdin)"); + } else { + // Loop through the filenames given on the command line. + do { + FILE *src_file; + const char *src_name; + + // "-" indicates stdin. + if (strcmp(argv[optind], "-") == 0) { + src_file = stdin; + src_name = "(stdin)"; + } else { + src_name = argv[optind]; + src_file = fopen(src_name, "rb"); + if (src_file == NULL) { + my_errorf("%s: %s", + tuklib_mask_nonprint( + src_name), + strerror(errno)); + exit(EXIT_FAILURE); + } + } +#ifdef ENABLE_SANDBOX + // Enable the strict sandbox for the last file. + // Then the process can no longer open additional + // files. The typical xzdec use case is to decompress + // a single file so this way the strictest sandboxing + // is used in most cases. + if (optind == argc - 1) + sandbox_enter(fileno(src_file)); +#endif + uncompress(&strm, src_file, src_name); + + if (src_file != stdin) + (void)fclose(src_file); + } while (++optind < argc); + } + +#ifndef NDEBUG + // Free the memory only when debugging. Freeing wastes some time, + // but allows detecting possible memory leaks with Valgrind. + lzma_end(&strm); +#endif + + tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, display_errors); +} diff --git a/cpp/third_party/xz-5.8.3/src/xzdec/xzdec_w32res.rc b/cpp/third_party/xz-5.8.3/src/xzdec/xzdec_w32res.rc new file mode 100644 index 000000000..fdbb10243 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/src/xzdec/xzdec_w32res.rc @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: 0BSD */ + +/* + * Author: Lasse Collin + */ + +#define MY_TYPE VFT_APP +#define MY_NAME "xzdec" +#define MY_SUFFIX ".exe" +#define MY_DESC "xzdec decompression tool for .xz files" +#include "common_w32res.rc" diff --git a/cpp/third_party/xz-5.8.3/tests/Makefile.am b/cpp/third_party/xz-5.8.3/tests/Makefile.am new file mode 100644 index 000000000..15dc16a8e --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/Makefile.am @@ -0,0 +1,83 @@ +## SPDX-License-Identifier: 0BSD +## Author: Lasse Collin + +EXTRA_DIST = \ + files \ + ossfuzz \ + tests.cmake \ + tuktest.h \ + tests.h \ + tests_w32res.rc \ + test_files.sh \ + test_compress.sh \ + test_compress_generated_abc \ + test_compress_generated_random \ + test_compress_generated_text \ + test_scripts.sh \ + test_suffix.sh \ + xzgrep_expected_output + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/common \ + -I$(top_srcdir)/src/liblzma/api \ + -I$(top_srcdir)/src/liblzma + +LDADD = $(top_builddir)/src/liblzma/liblzma.la + +LDADD += $(LTLIBINTL) + +# Windows resource compiler support +.rc.o: + $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(RCFLAGS) -i $< -o $@ + +if COND_W32 +LDADD += tests_w32res.o +endif + +check_PROGRAMS = \ + create_compress_files \ + test_check \ + test_hardware \ + test_stream_flags \ + test_filter_flags \ + test_filter_str \ + test_block_header \ + test_index \ + test_index_hash \ + test_bcj_exact_size \ + test_memlimit \ + test_lzip_decoder \ + test_vli + +TESTS = \ + test_check \ + test_hardware \ + test_stream_flags \ + test_filter_flags \ + test_filter_str \ + test_block_header \ + test_index \ + test_index_hash \ + test_bcj_exact_size \ + test_memlimit \ + test_lzip_decoder \ + test_vli \ + test_files.sh \ + test_suffix.sh \ + test_compress_generated_abc \ + test_compress_generated_random \ + test_compress_generated_text + +if COND_MICROLZMA +check_PROGRAMS += test_microlzma +TESTS += test_microlzma +endif + +if COND_SCRIPTS +TESTS += test_scripts.sh +endif + +clean-local: + -rm -f compress_generated_* \ + xzgrep_test_output xzgrep_test_1.xz xzgrep_test_2.xz diff --git a/cpp/third_party/xz-5.8.3/tests/Makefile.in b/cpp/third_party/xz-5.8.3/tests/Makefile.in new file mode 100644 index 000000000..ae3927e07 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/Makefile.in @@ -0,0 +1,1414 @@ +# Makefile.in generated by automake 1.18.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2025 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)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) +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@ +@COND_W32_TRUE@am__append_1 = tests_w32res.o +check_PROGRAMS = create_compress_files$(EXEEXT) test_check$(EXEEXT) \ + test_hardware$(EXEEXT) test_stream_flags$(EXEEXT) \ + test_filter_flags$(EXEEXT) test_filter_str$(EXEEXT) \ + test_block_header$(EXEEXT) test_index$(EXEEXT) \ + test_index_hash$(EXEEXT) test_bcj_exact_size$(EXEEXT) \ + test_memlimit$(EXEEXT) test_lzip_decoder$(EXEEXT) \ + test_vli$(EXEEXT) $(am__EXEEXT_1) +TESTS = test_check$(EXEEXT) test_hardware$(EXEEXT) \ + test_stream_flags$(EXEEXT) test_filter_flags$(EXEEXT) \ + test_filter_str$(EXEEXT) test_block_header$(EXEEXT) \ + test_index$(EXEEXT) test_index_hash$(EXEEXT) \ + test_bcj_exact_size$(EXEEXT) test_memlimit$(EXEEXT) \ + test_lzip_decoder$(EXEEXT) test_vli$(EXEEXT) test_files.sh \ + test_suffix.sh test_compress_generated_abc \ + test_compress_generated_random test_compress_generated_text \ + $(am__EXEEXT_1) $(am__append_4) +@COND_MICROLZMA_TRUE@am__append_2 = test_microlzma +@COND_MICROLZMA_TRUE@am__append_3 = test_microlzma +@COND_SCRIPTS_TRUE@am__append_4 = test_scripts.sh +subdir = tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/build-to-host.m4 $(top_srcdir)/m4/getopt.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/host-cpu-c-abi.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/posix-shell.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/tuklib_common.m4 \ + $(top_srcdir)/m4/tuklib_cpucores.m4 \ + $(top_srcdir)/m4/tuklib_integer.m4 \ + $(top_srcdir)/m4/tuklib_mbstr.m4 \ + $(top_srcdir)/m4/tuklib_physmem.m4 \ + $(top_srcdir)/m4/tuklib_progname.m4 \ + $(top_srcdir)/m4/visibility.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@COND_MICROLZMA_TRUE@am__EXEEXT_1 = test_microlzma$(EXEEXT) +create_compress_files_SOURCES = create_compress_files.c +create_compress_files_OBJECTS = create_compress_files.$(OBJEXT) +create_compress_files_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +create_compress_files_DEPENDENCIES = \ + $(top_builddir)/src/liblzma/liblzma.la $(am__DEPENDENCIES_1) \ + $(am__append_1) +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 = +test_bcj_exact_size_SOURCES = test_bcj_exact_size.c +test_bcj_exact_size_OBJECTS = test_bcj_exact_size.$(OBJEXT) +test_bcj_exact_size_LDADD = $(LDADD) +test_bcj_exact_size_DEPENDENCIES = \ + $(top_builddir)/src/liblzma/liblzma.la $(am__DEPENDENCIES_1) \ + $(am__append_1) +test_block_header_SOURCES = test_block_header.c +test_block_header_OBJECTS = test_block_header.$(OBJEXT) +test_block_header_LDADD = $(LDADD) +test_block_header_DEPENDENCIES = \ + $(top_builddir)/src/liblzma/liblzma.la $(am__DEPENDENCIES_1) \ + $(am__append_1) +test_check_SOURCES = test_check.c +test_check_OBJECTS = test_check.$(OBJEXT) +test_check_LDADD = $(LDADD) +test_check_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__DEPENDENCIES_1) $(am__append_1) +test_filter_flags_SOURCES = test_filter_flags.c +test_filter_flags_OBJECTS = test_filter_flags.$(OBJEXT) +test_filter_flags_LDADD = $(LDADD) +test_filter_flags_DEPENDENCIES = \ + $(top_builddir)/src/liblzma/liblzma.la $(am__DEPENDENCIES_1) \ + $(am__append_1) +test_filter_str_SOURCES = test_filter_str.c +test_filter_str_OBJECTS = test_filter_str.$(OBJEXT) +test_filter_str_LDADD = $(LDADD) +test_filter_str_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__DEPENDENCIES_1) $(am__append_1) +test_hardware_SOURCES = test_hardware.c +test_hardware_OBJECTS = test_hardware.$(OBJEXT) +test_hardware_LDADD = $(LDADD) +test_hardware_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__DEPENDENCIES_1) $(am__append_1) +test_index_SOURCES = test_index.c +test_index_OBJECTS = test_index.$(OBJEXT) +test_index_LDADD = $(LDADD) +test_index_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__DEPENDENCIES_1) $(am__append_1) +test_index_hash_SOURCES = test_index_hash.c +test_index_hash_OBJECTS = test_index_hash.$(OBJEXT) +test_index_hash_LDADD = $(LDADD) +test_index_hash_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__DEPENDENCIES_1) $(am__append_1) +test_lzip_decoder_SOURCES = test_lzip_decoder.c +test_lzip_decoder_OBJECTS = test_lzip_decoder.$(OBJEXT) +test_lzip_decoder_LDADD = $(LDADD) +test_lzip_decoder_DEPENDENCIES = \ + $(top_builddir)/src/liblzma/liblzma.la $(am__DEPENDENCIES_1) \ + $(am__append_1) +test_memlimit_SOURCES = test_memlimit.c +test_memlimit_OBJECTS = test_memlimit.$(OBJEXT) +test_memlimit_LDADD = $(LDADD) +test_memlimit_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__DEPENDENCIES_1) $(am__append_1) +test_microlzma_SOURCES = test_microlzma.c +test_microlzma_OBJECTS = test_microlzma.$(OBJEXT) +test_microlzma_LDADD = $(LDADD) +test_microlzma_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__DEPENDENCIES_1) $(am__append_1) +test_stream_flags_SOURCES = test_stream_flags.c +test_stream_flags_OBJECTS = test_stream_flags.$(OBJEXT) +test_stream_flags_LDADD = $(LDADD) +test_stream_flags_DEPENDENCIES = \ + $(top_builddir)/src/liblzma/liblzma.la $(am__DEPENDENCIES_1) \ + $(am__append_1) +test_vli_SOURCES = test_vli.c +test_vli_OBJECTS = test_vli.$(OBJEXT) +test_vli_LDADD = $(LDADD) +test_vli_DEPENDENCIES = $(top_builddir)/src/liblzma/liblzma.la \ + $(am__DEPENDENCIES_1) $(am__append_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@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/create_compress_files.Po \ + ./$(DEPDIR)/test_bcj_exact_size.Po \ + ./$(DEPDIR)/test_block_header.Po ./$(DEPDIR)/test_check.Po \ + ./$(DEPDIR)/test_filter_flags.Po \ + ./$(DEPDIR)/test_filter_str.Po ./$(DEPDIR)/test_hardware.Po \ + ./$(DEPDIR)/test_index.Po ./$(DEPDIR)/test_index_hash.Po \ + ./$(DEPDIR)/test_lzip_decoder.Po ./$(DEPDIR)/test_memlimit.Po \ + ./$(DEPDIR)/test_microlzma.Po ./$(DEPDIR)/test_stream_flags.Po \ + ./$(DEPDIR)/test_vli.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 = create_compress_files.c test_bcj_exact_size.c \ + test_block_header.c test_check.c test_filter_flags.c \ + test_filter_str.c test_hardware.c test_index.c \ + test_index_hash.c test_lzip_decoder.c test_memlimit.c \ + test_microlzma.c test_stream_flags.c test_vli.c +DIST_SOURCES = create_compress_files.c test_bcj_exact_size.c \ + test_block_header.c test_check.c test_filter_flags.c \ + test_filter_str.c test_hardware.c test_index.c \ + test_index_hash.c test_lzip_decoder.c test_memlimit.c \ + test_microlzma.c test_stream_flags.c test_vli.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# 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__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__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 ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ + } +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" \ + $$am__collect_skipped_logs \ + --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 '$(IGNORE_SKIPPED_LOGS)'; then \ + am__collect_skipped_logs='--collect-skipped-logs no'; \ +else \ + am__collect_skipped_logs=''; \ +fi; \ +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) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/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-aux/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp \ + $(top_srcdir)/build-aux/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ +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@ +FILECMD = @FILECMD@ +GETOPT_H = @GETOPT_H@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LINKER_FLAG_UNDEFINED_VERSION = @LINKER_FLAG_UNDEFINED_VERSION@ +LIPO = @LIPO@ +LN_EXEEXT = @LN_EXEEXT@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +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@ +POSIX_SHELL = @POSIX_SHELL@ +POSUB = @POSUB@ +PREFERABLY_POSIX_SHELL = @PREFERABLY_POSIX_SHELL@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +RC = @RC@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +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__rm_f_notfound = @am__rm_f_notfound@ +am__tar = @am__tar@ +am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ +ax_pthread_config = @ax_pthread_config@ +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@ +enable_path_for_scripts = @enable_path_for_scripts@ +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@ +localedir_c = @localedir_c@ +localedir_c_make = @localedir_c_make@ +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@ +xz = @xz@ +EXTRA_DIST = \ + files \ + ossfuzz \ + tests.cmake \ + tuktest.h \ + tests.h \ + tests_w32res.rc \ + test_files.sh \ + test_compress.sh \ + test_compress_generated_abc \ + test_compress_generated_random \ + test_compress_generated_text \ + test_scripts.sh \ + test_suffix.sh \ + xzgrep_expected_output + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/common \ + -I$(top_srcdir)/src/liblzma/api \ + -I$(top_srcdir)/src/liblzma + +LDADD = $(top_builddir)/src/liblzma/liblzma.la $(LTLIBINTL) \ + $(am__append_1) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .rc .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + $(am__rm_f) $(check_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(check_PROGRAMS:$(EXEEXT)=) + +create_compress_files$(EXEEXT): $(create_compress_files_OBJECTS) $(create_compress_files_DEPENDENCIES) $(EXTRA_create_compress_files_DEPENDENCIES) + @rm -f create_compress_files$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(create_compress_files_OBJECTS) $(create_compress_files_LDADD) $(LIBS) + +test_bcj_exact_size$(EXEEXT): $(test_bcj_exact_size_OBJECTS) $(test_bcj_exact_size_DEPENDENCIES) $(EXTRA_test_bcj_exact_size_DEPENDENCIES) + @rm -f test_bcj_exact_size$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_bcj_exact_size_OBJECTS) $(test_bcj_exact_size_LDADD) $(LIBS) + +test_block_header$(EXEEXT): $(test_block_header_OBJECTS) $(test_block_header_DEPENDENCIES) $(EXTRA_test_block_header_DEPENDENCIES) + @rm -f test_block_header$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_block_header_OBJECTS) $(test_block_header_LDADD) $(LIBS) + +test_check$(EXEEXT): $(test_check_OBJECTS) $(test_check_DEPENDENCIES) $(EXTRA_test_check_DEPENDENCIES) + @rm -f test_check$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_check_OBJECTS) $(test_check_LDADD) $(LIBS) + +test_filter_flags$(EXEEXT): $(test_filter_flags_OBJECTS) $(test_filter_flags_DEPENDENCIES) $(EXTRA_test_filter_flags_DEPENDENCIES) + @rm -f test_filter_flags$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_filter_flags_OBJECTS) $(test_filter_flags_LDADD) $(LIBS) + +test_filter_str$(EXEEXT): $(test_filter_str_OBJECTS) $(test_filter_str_DEPENDENCIES) $(EXTRA_test_filter_str_DEPENDENCIES) + @rm -f test_filter_str$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_filter_str_OBJECTS) $(test_filter_str_LDADD) $(LIBS) + +test_hardware$(EXEEXT): $(test_hardware_OBJECTS) $(test_hardware_DEPENDENCIES) $(EXTRA_test_hardware_DEPENDENCIES) + @rm -f test_hardware$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_hardware_OBJECTS) $(test_hardware_LDADD) $(LIBS) + +test_index$(EXEEXT): $(test_index_OBJECTS) $(test_index_DEPENDENCIES) $(EXTRA_test_index_DEPENDENCIES) + @rm -f test_index$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_index_OBJECTS) $(test_index_LDADD) $(LIBS) + +test_index_hash$(EXEEXT): $(test_index_hash_OBJECTS) $(test_index_hash_DEPENDENCIES) $(EXTRA_test_index_hash_DEPENDENCIES) + @rm -f test_index_hash$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_index_hash_OBJECTS) $(test_index_hash_LDADD) $(LIBS) + +test_lzip_decoder$(EXEEXT): $(test_lzip_decoder_OBJECTS) $(test_lzip_decoder_DEPENDENCIES) $(EXTRA_test_lzip_decoder_DEPENDENCIES) + @rm -f test_lzip_decoder$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_lzip_decoder_OBJECTS) $(test_lzip_decoder_LDADD) $(LIBS) + +test_memlimit$(EXEEXT): $(test_memlimit_OBJECTS) $(test_memlimit_DEPENDENCIES) $(EXTRA_test_memlimit_DEPENDENCIES) + @rm -f test_memlimit$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_memlimit_OBJECTS) $(test_memlimit_LDADD) $(LIBS) + +test_microlzma$(EXEEXT): $(test_microlzma_OBJECTS) $(test_microlzma_DEPENDENCIES) $(EXTRA_test_microlzma_DEPENDENCIES) + @rm -f test_microlzma$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_microlzma_OBJECTS) $(test_microlzma_LDADD) $(LIBS) + +test_stream_flags$(EXEEXT): $(test_stream_flags_OBJECTS) $(test_stream_flags_DEPENDENCIES) $(EXTRA_test_stream_flags_DEPENDENCIES) + @rm -f test_stream_flags$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_stream_flags_OBJECTS) $(test_stream_flags_LDADD) $(LIBS) + +test_vli$(EXEEXT): $(test_vli_OBJECTS) $(test_vli_DEPENDENCIES) $(EXTRA_test_vli_DEPENDENCIES) + @rm -f test_vli$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_vli_OBJECTS) $(test_vli_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/create_compress_files.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bcj_exact_size.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_block_header.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_check.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_filter_flags.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_filter_str.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_hardware.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_index.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_index_hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lzip_decoder.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_memlimit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_microlzma.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_stream_flags.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_vli.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @: >>$@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.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 $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +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" +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 + +# 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"; \ + }; \ + output_system_information () \ + { \ + echo; \ + { uname -a | $(AWK) '{ \ + printf "System information (uname -a):"; \ + for (i = 1; i < NF; ++i) \ + { \ + if (i != 2) \ + printf " %s", $$i; \ + } \ + printf "\n"; \ +}'; } 2>&1; \ + if test -r /etc/os-release; then \ + echo "Distribution information (/etc/os-release):"; \ + sed 8q /etc/os-release; \ + elif test -r /etc/issue; then \ + echo "Distribution information (/etc/issue):"; \ + cat /etc/issue; \ + fi; \ + }; \ + please_report () \ + { \ +echo "Some test(s) failed. Please report this to $(PACKAGE_BUGREPORT),"; \ +echo "together with the test-suite.log file (gzipped) and your system"; \ +echo "information. Thanks."; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + output_system_information; \ + 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) for debugging.$${std}";\ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) + @$(am__rm_f) $(RECHECK_LOGS) + @$(am__rm_f) $(RECHECK_LOGS:.log=.trs) + @$(am__rm_f) $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @$(am__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 $$? +test_check.log: test_check$(EXEEXT) + @p='test_check$(EXEEXT)'; \ + b='test_check'; \ + $(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_hardware.log: test_hardware$(EXEEXT) + @p='test_hardware$(EXEEXT)'; \ + b='test_hardware'; \ + $(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_stream_flags.log: test_stream_flags$(EXEEXT) + @p='test_stream_flags$(EXEEXT)'; \ + b='test_stream_flags'; \ + $(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_filter_flags.log: test_filter_flags$(EXEEXT) + @p='test_filter_flags$(EXEEXT)'; \ + b='test_filter_flags'; \ + $(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_filter_str.log: test_filter_str$(EXEEXT) + @p='test_filter_str$(EXEEXT)'; \ + b='test_filter_str'; \ + $(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_block_header.log: test_block_header$(EXEEXT) + @p='test_block_header$(EXEEXT)'; \ + b='test_block_header'; \ + $(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_index.log: test_index$(EXEEXT) + @p='test_index$(EXEEXT)'; \ + b='test_index'; \ + $(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_index_hash.log: test_index_hash$(EXEEXT) + @p='test_index_hash$(EXEEXT)'; \ + b='test_index_hash'; \ + $(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_bcj_exact_size.log: test_bcj_exact_size$(EXEEXT) + @p='test_bcj_exact_size$(EXEEXT)'; \ + b='test_bcj_exact_size'; \ + $(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_memlimit.log: test_memlimit$(EXEEXT) + @p='test_memlimit$(EXEEXT)'; \ + b='test_memlimit'; \ + $(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_lzip_decoder.log: test_lzip_decoder$(EXEEXT) + @p='test_lzip_decoder$(EXEEXT)'; \ + b='test_lzip_decoder'; \ + $(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_vli.log: test_vli$(EXEEXT) + @p='test_vli$(EXEEXT)'; \ + b='test_vli'; \ + $(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_files.sh.log: test_files.sh + @p='test_files.sh'; \ + b='test_files.sh'; \ + $(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_suffix.sh.log: test_suffix.sh + @p='test_suffix.sh'; \ + b='test_suffix.sh'; \ + $(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_compress_generated_abc.log: test_compress_generated_abc + @p='test_compress_generated_abc'; \ + b='test_compress_generated_abc'; \ + $(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_compress_generated_random.log: test_compress_generated_random + @p='test_compress_generated_random'; \ + b='test_compress_generated_random'; \ + $(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_compress_generated_text.log: test_compress_generated_text + @p='test_compress_generated_text'; \ + b='test_compress_generated_text'; \ + $(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_microlzma.log: test_microlzma$(EXEEXT) + @p='test_microlzma$(EXEEXT)'; \ + b='test_microlzma'; \ + $(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_scripts.sh.log: test_scripts.sh + @p='test_scripts.sh'; \ + b='test_scripts.sh'; \ + $(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) + @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 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: 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: + -$(am__rm_f) $(TEST_LOGS) + -$(am__rm_f) $(TEST_LOGS:.log=.trs) + -$(am__rm_f) $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/create_compress_files.Po + -rm -f ./$(DEPDIR)/test_bcj_exact_size.Po + -rm -f ./$(DEPDIR)/test_block_header.Po + -rm -f ./$(DEPDIR)/test_check.Po + -rm -f ./$(DEPDIR)/test_filter_flags.Po + -rm -f ./$(DEPDIR)/test_filter_str.Po + -rm -f ./$(DEPDIR)/test_hardware.Po + -rm -f ./$(DEPDIR)/test_index.Po + -rm -f ./$(DEPDIR)/test_index_hash.Po + -rm -f ./$(DEPDIR)/test_lzip_decoder.Po + -rm -f ./$(DEPDIR)/test_memlimit.Po + -rm -f ./$(DEPDIR)/test_microlzma.Po + -rm -f ./$(DEPDIR)/test_stream_flags.Po + -rm -f ./$(DEPDIR)/test_vli.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +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 ./$(DEPDIR)/create_compress_files.Po + -rm -f ./$(DEPDIR)/test_bcj_exact_size.Po + -rm -f ./$(DEPDIR)/test_block_header.Po + -rm -f ./$(DEPDIR)/test_check.Po + -rm -f ./$(DEPDIR)/test_filter_flags.Po + -rm -f ./$(DEPDIR)/test_filter_str.Po + -rm -f ./$(DEPDIR)/test_hardware.Po + -rm -f ./$(DEPDIR)/test_index.Po + -rm -f ./$(DEPDIR)/test_index_hash.Po + -rm -f ./$(DEPDIR)/test_lzip_decoder.Po + -rm -f ./$(DEPDIR)/test_memlimit.Po + -rm -f ./$(DEPDIR)/test_microlzma.Po + -rm -f ./$(DEPDIR)/test_stream_flags.Po + -rm -f ./$(DEPDIR)/test_vli.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: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ + clean-local cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am 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 + +.PRECIOUS: Makefile + + +# Windows resource compiler support +.rc.o: + $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(RCFLAGS) -i $< -o $@ + +clean-local: + -rm -f compress_generated_* \ + xzgrep_test_output xzgrep_test_1.xz xzgrep_test_2.xz + +# 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: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/cpp/third_party/xz-5.8.3/tests/create_compress_files.c b/cpp/third_party/xz-5.8.3/tests/create_compress_files.c new file mode 100644 index 000000000..2106ac813 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/create_compress_files.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file create_compress_files.c +/// \brief Creates bunch of test files to be compressed +/// +/// Using a test file generator program saves space in the source code +/// package considerably. +// +// Author: Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include "sysdefs.h" +#include + + +// If a command-line argument was given, only create the file if its +// name was specified on the command line. If no args were given then +// all files are created. +// +// Avoid re-creating the test files every time the tests are run. +#define maybe_create_test(argc, argv, name) \ +do { \ + if ((argc < 2 || strcmp(argv[1], "compress_generated_" #name) == 0) \ + && !file_exists("compress_generated_" #name)) { \ + FILE *file = file_create("compress_generated_" #name); \ + write_ ## name(file); \ + file_finish(file, "compress_generated_" #name); \ + } \ +} while (0) + + +static bool +file_exists(const char *filename) +{ + // Trying to be somewhat portable by avoiding stat(). + FILE *file = fopen(filename, "rb"); + bool ret; + + if (file != NULL) { + fclose(file); + ret = true; + } else { + ret = false; + } + + return ret; +} + + +static FILE * +file_create(const char *filename) +{ + FILE *file = fopen(filename, "wb"); + + if (file == NULL) { + perror(filename); + exit(EXIT_FAILURE); + } + + return file; +} + + +static void +file_finish(FILE *file, const char *filename) +{ + const bool ferror_fail = ferror(file); + const bool fclose_fail = fclose(file); + + if (ferror_fail || fclose_fail) { + perror(filename); + exit(EXIT_FAILURE); + } +} + + +// File that repeats "abc\n" a few thousand times. This is targeted +// especially at Subblock filter's run-length encoder. +static void +write_abc(FILE *file) +{ + for (size_t i = 0; i < 12345; ++i) + if (fwrite("abc\n", 4, 1, file) != 1) + exit(EXIT_FAILURE); +} + + +// File that doesn't compress. We always use the same random seed to +// generate identical files on all systems. +static void +write_random(FILE *file) +{ + uint32_t n = 5; + + for (size_t i = 0; i < 123456; ++i) { + n = 101771 * n + 71777; + + putc((uint8_t)(n), file); + putc((uint8_t)(n >> 8), file); + putc((uint8_t)(n >> 16), file); + putc((uint8_t)(n >> 24), file); + } +} + + +// Text file +static void +write_text(FILE *file) +{ + static const char *lorem[] = { + "Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", + "adipisicing", "elit,", "sed", "do", "eiusmod", "tempor", + "incididunt", "ut", "labore", "et", "dolore", "magna", + "aliqua.", "Ut", "enim", "ad", "minim", "veniam,", "quis", + "nostrud", "exercitation", "ullamco", "laboris", "nisi", + "ut", "aliquip", "ex", "ea", "commodo", "consequat.", + "Duis", "aute", "irure", "dolor", "in", "reprehenderit", + "in", "voluptate", "velit", "esse", "cillum", "dolore", + "eu", "fugiat", "nulla", "pariatur.", "Excepteur", "sint", + "occaecat", "cupidatat", "non", "proident,", "sunt", "in", + "culpa", "qui", "officia", "deserunt", "mollit", "anim", + "id", "est", "laborum." + }; + + // Let the first paragraph be the original text. + for (size_t w = 0; w < ARRAY_SIZE(lorem); ++w) { + fprintf(file, "%s ", lorem[w]); + + if (w % 7 == 6) + fprintf(file, "\n"); + } + + // The rest shall be (hopefully) meaningless combinations of + // the same words. + uint32_t n = 29; + + for (size_t p = 0; p < 500; ++p) { + fprintf(file, "\n\n"); + + for (size_t w = 0; w < ARRAY_SIZE(lorem); ++w) { + n = 101771 * n + 71777; + + fprintf(file, "%s ", lorem[n % ARRAY_SIZE(lorem)]); + + if (w % 7 == 6) + fprintf(file, "\n"); + } + } +} + + +int +main(int argc, char **argv) +{ + maybe_create_test(argc, argv, abc); + maybe_create_test(argc, argv, random); + maybe_create_test(argc, argv, text); + return EXIT_SUCCESS; +} diff --git a/cpp/third_party/xz-5.8.3/tests/files/README b/cpp/third_party/xz-5.8.3/tests/files/README new file mode 100644 index 000000000..584e6ba42 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/files/README @@ -0,0 +1,415 @@ + +.xz, .lzma, and .lz Test Files +------------------------------ + +0. Introduction + + This directory contains bunch of files to test handling of .xz, + .lzma (LZMA_Alone), and .lz (lzip) files in decoder implementations. + Many of the files have been created by hand with a hex editor, thus + there is no better "source code" than the files themselves. All the + test files and this README may be distributed under the terms of + the BSD Zero Clause License (0BSD). + + +1. File Types + + Good files (good-*) must decode successfully without requiring + a lot of CPU time or RAM. + + Unsupported files (unsupported-*) are good files, but headers + indicate features not supported by the current file format + specification. + + Bad files (bad-*) must cause the decoder to give an error. Like + with the good files, these files must not require a lot of CPU + time or RAM before they get detected to be broken. + + +2. Descriptions of Individual .xz Files + +2.1. Good Files + + good-0-empty.xz has one Stream with no Blocks. + + good-0pad-empty.xz has one Stream with no Blocks followed by + four-byte Stream Padding. + + good-0cat-empty.xz has two zero-Block Streams concatenated without + Stream Padding. + + good-0catpad-empty.xz has two zero-Block Streams concatenated with + four-byte Stream Padding between the Streams. + + good-1-check-none.xz has one Stream with one Block with two + uncompressed LZMA2 chunks and no integrity check. + + good-1-check-crc32.xz has one Stream with one Block with two + uncompressed LZMA2 chunks and CRC32 check. + + good-1-check-crc64.xz is like good-1-check-crc32.xz but with CRC64. + + good-1-check-sha256.xz is like good-1-check-crc32.xz but with + SHA256. + + good-2-lzma2.xz has one Stream with two Blocks with one uncompressed + LZMA2 chunk in each Block. + + good-1-block_header-1.xz has both Compressed Size and Uncompressed + Size in the Block Header. This has also four extra bytes of Header + Padding. + + good-1-block_header-2.xz has known Compressed Size. + + good-1-block_header-3.xz has known Uncompressed Size. + + good-1-delta-lzma2.tiff.xz is an image file that compresses + better with Delta+LZMA2 than with plain LZMA2. + + good-1-arm64-lzma2-1.xz uses the ARM64 filter and LZMA2. The + uncompressed data is constructed so that it tests integer + wrap around and sign extension. To recreate the file, compress + using XZ Utils 5.4.x (newer may or may not work too): + + ./debug/testfilegen-arm64 \ + | xz -T1 -Ccrc32 --arm64 \ + --lzma2=dict=64KiB,lp=2,lc=2 \ + > good-1-arm64-lzma2-1.xz + + good-1-arm64-lzma2-2.xz is like good-1-arm64-lzma2-1.xz but with + non-zero start offset. XZ Embedded doesn't support this file. + To recreate the file, compress using XZ Utils 5.4.x (newer may or + may not work too): + + ./debug/testfilegen-arm64 \ + | xz -T1 -Ccrc32 --arm64=start=4294963200 \ + --lzma2=dict=64KiB,lp=2,lc=2 \ + > good-1-arm64-lzma2-2.xz + + good-1-lzma2-1.xz has two LZMA2 chunks, of which the second sets + new properties. + + good-1-lzma2-2.xz has two LZMA2 chunks, of which the second resets + the state without specifying new properties. + + good-1-lzma2-3.xz has two LZMA2 chunks, of which the first is + uncompressed and the second is LZMA. The first chunk resets dictionary + and the second sets new properties. + + good-1-lzma2-4.xz has three LZMA2 chunks: First is LZMA, second is + uncompressed with dictionary reset, and third is LZMA with new + properties but without dictionary reset. + + good-1-lzma2-5.xz has an empty LZMA2 stream with only the end of + payload marker. XZ Utils 5.0.1 and older incorrectly see this file + as corrupt. + + good-1-3delta-lzma2.xz has three Delta filters and LZMA2. + + good-1-empty-bcj-lzma2.xz has an empty Block that uses PowerPC BCJ + and LZMA2. liblzma from XZ Utils 5.0.1 and older may incorrectly + return LZMA_BUF_ERROR in some cases. See commit message + d8db706acb8316f9861abd432cfbe001dd6d0c5c for the details. + + +2.2. Unsupported Files + + unsupported-check.xz uses Check ID 0x02 which isn't supported by + the current version of the file format. It is implementation-defined + how this file handled (it may reject it, or decode it possibly with + a warning). + + unsupported-block_header.xz has a non-null byte in Header Padding, + which may indicate presence of a new unsupported field. + + unsupported-filter_flags-1.xz has unsupported Filter ID 0x7F. + + unsupported-filter_flags-2.xz specifies only Delta filter in the + List of Filter Flags, but Delta isn't allowed as the last filter in + the chain. It could be a little more correct to detect this file as + corrupt instead of unsupported, but saying it is unsupported is + simpler in case of liblzma. + + unsupported-filter_flags-3.xz specifies two LZMA2 filters in the + List of Filter Flags. LZMA2 is allowed only as the last filter in the + chain. It could be a little more correct to detect this file as + corrupt instead of unsupported, but saying it is unsupported is + simpler in case of liblzma. + + +2.3. Bad Files + + bad-0pad-empty.xz has one Stream with no Blocks followed by + five-byte Stream Padding. Stream Padding must be a multiple of four + bytes, thus this file is corrupt. + + bad-0catpad-empty.xz has two zero-Block Streams concatenated with + five-byte Stream Padding between the Streams. + + bad-0cat-alone.xz is good-0-empty.xz concatenated with an empty + LZMA_Alone file. + + bad-0cat-header_magic.xz is good-0cat-empty.xz but with one byte + wrong in the Header Magic Bytes field of the second Stream. liblzma + gives LZMA_DATA_ERROR for this. (LZMA_FORMAT_ERROR is used only if + the first Stream of a file has invalid Header Magic Bytes.) + + bad-0-header_magic.xz is good-0-empty.xz but with one byte wrong + in the Header Magic Bytes field. liblzma gives LZMA_FORMAT_ERROR for + this. + + bad-0-footer_magic.xz is good-0-empty.xz but with one byte wrong + in the Footer Magic Bytes field. liblzma gives LZMA_DATA_ERROR for + this. + + bad-0-empty-truncated.xz is good-0-empty.xz without the last byte + of the file. + + bad-0-nonempty_index.xz has no Blocks but Index claims that there is + one Block. + + bad-0-backward_size.xz has wrong Backward Size in Stream Footer. + + bad-1-stream_flags-1.xz has different Stream Flags in Stream Header + and Stream Footer. + + bad-1-stream_flags-2.xz has wrong CRC32 in Stream Header. + + bad-1-stream_flags-3.xz has wrong CRC32 in Stream Footer. + + bad-1-vli-1.xz has two-byte variable-length integer in the + Uncompressed Size field in Block Header while one-byte would be enough + for that value. It's important that the file gets rejected due to too + big integer encoding instead of due to Uncompressed Size not matching + the value stored in the Block Header. That is, the decoder must not + try to decode the Compressed Data field. + + bad-1-vli-2.xz has ten-byte variable-length integer as Uncompressed + Size in Block Header. It's important that the file gets rejected due + to too big integer encoding instead of due to Uncompressed Size not + matching the value stored in the Block Header. That is, the decoder + must not try to decode the Compressed Data field. + + bad-1-block_header-1.xz has Block Header that ends in the middle of + the Filter Flags field. + + bad-1-block_header-2.xz has Block Header that has Compressed Size and + Uncompressed Size but no List of Filter Flags field. + + bad-1-block_header-3.xz has wrong CRC32 in Block Header. + + bad-1-block_header-4.xz has too big Compressed Size in Block Header + (2^63 - 1 bytes while maximum is a little less, because the whole + Block must stay smaller than 2^63). It's important that the file + gets rejected due to invalid Compressed Size value; the decoder + must not try decoding the Compressed Data field. + + bad-1-block_header-5.xz has zero as Compressed Size in Block Header. + + bad-1-block_header-6.xz has corrupt Block Header which may crash + xz -lvv in XZ Utils 5.0.3 and earlier. It was fixed in the commit + c0297445064951807803457dca1611b3c47e7f0f. + + bad-2-index-1.xz has wrong Unpadded Sizes in Index. + + bad-2-index-2.xz has wrong Uncompressed Sizes in Index. + + bad-2-index-3.xz has non-null byte in Index Padding. + + bad-2-index-4.xz wrong CRC32 in Index. + + bad-2-index-5.xz has zero as Unpadded Size. It is important that the + file gets rejected specifically due to Unpadded Size having an invalid + value. + + bad-3-index-uncomp-overflow.xz has Index whose Uncompressed Size + fields have huge values whose sum exceeds the maximum allowed size + of 2^63 - 1 bytes. In this file the sum is exactly 2^64. + lzma_index_append() in liblzma <= 5.2.6 lacks the integer overflow + check for the uncompressed size and thus doesn't catch the error + when decoding the Index field in this file. This makes "xz -l" + not detect the error and will display 0 as the uncompressed size. + Note that regular decompression isn't affected by this bug because + it uses lzma_index_hash_append() instead. + + bad-2-compressed_data_padding.xz has non-null byte in the padding of + the Compressed Data field of the first Block. + + bad-1-check-crc32.xz has wrong Check (CRC32). + + bad-1-check-crc32-2.xz has Compressed Size and Uncompressed Size in + Block Header but wrong Check (CRC32) in the actual data. This file + differs by one byte from good-1-block_header-1.xz: the last byte of + the Check field is wrong. This file is useful for testing error + detection in the threaded decoder when a worker thread is configured + to pass input one byte at a time to the Block decoder. + + bad-1-check-crc64.xz has wrong Check (CRC64). + + bad-1-check-sha256.xz has wrong Check (SHA-256). + + bad-1-lzma2-1.xz has LZMA2 stream whose first chunk (uncompressed) + doesn't reset the dictionary. + + bad-1-lzma2-2.xz has two LZMA2 chunks, of which the second chunk + indicates dictionary reset, but the LZMA compressed data tries to + repeat data from the previous chunk. + + bad-1-lzma2-3.xz sets new invalid properties (lc=8, lp=0, pb=0) in + the middle of Block. + + bad-1-lzma2-4.xz has two LZMA2 chunks, of which the first is + uncompressed and the second is LZMA. The first chunk resets dictionary + as it should, but the second chunk tries to reset state without + specifying properties for LZMA. + + bad-1-lzma2-5.xz is like bad-1-lzma2-4.xz but doesn't try to reset + anything in the header of the second chunk. + + bad-1-lzma2-6.xz has reserved LZMA2 control byte value (0x03). + + bad-1-lzma2-7.xz has EOPM at LZMA level. + + bad-1-lzma2-8.xz is like good-1-lzma2-4.xz but doesn't set new + properties in the third LZMA2 chunk. + + bad-1-lzma2-9.xz has LZMA2 stream that is truncated at the end of + a LZMA2 chunk (no end marker). The uncompressed size of the partial + LZMA2 stream exceeds the value stored in the Block Header. + + bad-1-lzma2-10.xz has LZMA2 stream that, from point of view of a + LZMA2 decoder, extends past the end of Block (and even the end of + the file). Uncompressed Size in Block Header is bigger than the + invalid LZMA2 stream may produce (even if a decoder reads until + the end of the file). The Check type is None to nullify certain + simple size-based sanity checks in a Block decoder. + + bad-1-lzma2-11.xz has LZMA2 stream that lacks the end of + payload marker. When Compressed Size bytes have been decoded, + Uncompressed Size bytes of output will have been produced but + the LZMA2 decoder doesn't indicate end of stream. + + +3. Descriptions of Individual .lzma Files + +3.1. Good Files + + good-unknown_size-with_eopm.lzma has unknown size in the header + and end of payload marker at the end. + + good-known_size-without_eopm.lzma has a known size in the header + and no end of payload marker at the end. + + good-known_size-with_eopm.lzma has a known size in the header + and end of payload marker at the end. XZ Utils 5.2.5 and older + will give an error at the end of the file after producing the + correct uncompressed output. + + +3.2. Bad Files + + bad-unknown_size-without_eopm.lzma has unknown size in the header + but no end of payload marker at the end. This file might be seen + by a decoder as if it were truncated. + + bad-too_big_size-with_eopm.lzma has too big uncompressed size in + the header and the end of payload marker will be detected before + the specified number of bytes have been decoded. + + bad-too_small_size-without_eopm-1.lzma has too small uncompressed + size in the header. The decoder will look for end of payload marker + but instead find a literal that would produce more output. + + bad-too_small_size-without_eopm-2.lzma is like -1 above but instead + of a literal the problem occurs with a short repeated match. + + bad-too_small_size-without_eopm-3.lzma is like -1 above but instead + of a literal the problem occurs in the middle of a match. + + +4. Descriptions of Individual .lz (lzip) Files + +4.1. Good Files + + good-1-v0.lz contains a single version 0 member. lzip 1.17 and + *older* can decompress this; support for version 0 was removed + in lzip 1.18. + + good-1-v0-trailing-1.lz is like good-1-v0.lz but contains + trailing data that the decompressor must ignore. + + good-1-v1.lz contains a single version 1 member. lzip 1.3 and + newer can decompress this. + + good-1-v1-trailing-1.lz is like good-1-v1.lz but contains + trailing data that the decompressor must ignore. + + good-1-v1-trailing-2.lz is like good-1-v1.lz but contains + trailing data whose first three bytes match the .lz magic bytes. + With lzip >= 1.20 this file results in an error unless one uses + the command line option --loose-trailing. lzip 1.3 to 1.19 decode + this file successfully by default. XZ Utils uses the old behavior + because it allows lzma_code() to stop at the first byte of the + trailing data as long as the first byte isn't 0x4C (L in US-ASCII); + otherwise the first 1-3 bytes that equal to the magic bytes are + consumed and lost in lzma_code(), and this is visible in xz too: + + $ ( xz -dc ; cat ) < good-1-v1-trailing-2.lz + Hello + World! + Trailing garbage + + $ ( xz -dc --single-stream ; cat ) < good-1-v1-trailing-2.lz + Hello + World! + LZITrailing garbage + + good-2-v0-v1.lz contains two members of which the first is + version 0 and the second version 1. lzip versions 1.3 to 1.17 + (inclusive) can decompress this. + + good-2-v1-v0.lz contains two members of which the first is + version 1 and the second version 0. lzip versions 1.3 to 1.17 + (inclusive) can decompress this. + + good-2-v1-v1.lz contains two version 1 members. lzip versions 1.3 + and newer can decompress this. + + +4.2. Unsupported Files + + unsupported-1-v234.lz is like good-1-v1.lz except the version + field has been set to 234 (0xEA) which, as of writing, isn't + defined or supported by any .lz implementation. + + +4.3. Bad Files + + bad-1-v1-magic-1.lz is like good-1-v1.lz but the first magic byte + is wrong. + + bad-1-v1-magic-2.lz is like good-1-v1.lz but the last (fourth) + magic byte is wrong. + + bad-1-v1-dict-1.lz has too low value in the dictionary size field. + + bad-1-v1-dict-2.lz has too high value in the dictionary size field. + + bad-1-v1-crc32.lz has wrong CRC32 value. + + bad-1-v0-uncomp-size.lz is version 0 format with incorrect value + in the uncompressed size field. + + bad-1-v1-uncomp-size.lz is version 1 format with incorrect value + in the uncompressed size field. + + bad-1-v1-member-size.lz has incorrect value in the member size + field. + + bad-1-v1-trailing-magic.lz has the four .lz magic bytes as trailing + data. This should be detected as a truncated file and thus result + in an error. That is, the last four bytes of the file should not be + ignored as trailing garbage. lzip >= 1.18 matches this behavior + while older versions ignore the last four bytes and don't indicate + an error. + diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-0-backward_size.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-0-backward_size.xz new file mode 100644 index 0000000000000000000000000000000000000000..2b46fa937b3e6e770f12973398f01d124f9220f4 GIT binary patch literal 32 kcmexsUKJ6=z`&TPbkB?d2xRWND4I?@dJM#7V2q3c0GX-?W&i*H literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-0-empty-truncated.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-0-empty-truncated.xz new file mode 100644 index 0000000000000000000000000000000000000000..f879af84ac473517a186f80510091273d9ea9676 GIT binary patch literal 31 jcmexsUKJ6=z`&TPbkB?d2xRWNC{A#i$;$}hFh&9ZipmEx literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-0-footer_magic.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-0-footer_magic.xz new file mode 100644 index 0000000000000000000000000000000000000000..5d9e3894bc2d112e987aee4788bde03f26ef98b6 GIT binary patch literal 32 kcmexsUKJ6=z`&TPbkB?d2xRWNC{A#i$;$}hFh)iI0FqV*i~s-t literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-0-header_magic.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-0-header_magic.xz new file mode 100644 index 0000000000000000000000000000000000000000..5984a453bf873ee0cbadc55efa71f26f0fa3da24 GIT binary patch literal 32 kcmexsUKJ6^z`&TPbkB?d2xRWNC{A#i$;$}hFh)iJ0FpchjQ{`u literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-0-nonempty_index.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-0-nonempty_index.xz new file mode 100644 index 0000000000000000000000000000000000000000..ed6e81fa0465f28bd06c400814c08d88e28d16b6 GIT binary patch literal 32 lcmexsUKJ6=z`&TPbkB@|k%2*bYn#FZr$N&V4kx>8{+z+q- literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-2.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-2.xz new file mode 100644 index 0000000000000000000000000000000000000000..ae42ecf0f9be468d902c4d8aecef27b541169b7d GIT binary patch literal 64 zcmexsUKJ6=z`&TPbkB_O01I!!^e!Pr23C*MoSb|vCI+_f{Gyx`MJ@*C#fwB47*%); SH14mT;53t$kpT!8BclLH;1H(( literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-3.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-3.xz new file mode 100644 index 0000000000000000000000000000000000000000..606cbd20e25534d911005f29c6842963f81810e4 GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^5L6MPzfq~%$zp^nS1FJ`BPEI}-69Zd#eo;<}A{T@6;zgni Xj4Hea8u!;vaGJ@>2vp0!7#RfsB{>g^ literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-4.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-block_header-4.xz new file mode 100644 index 0000000000000000000000000000000000000000..e72dfbfc39468dee45f7c6b3981a072d56241f82 GIT binary patch literal 76 zcmexsUKJ6=z`&TPbkB^%;Xf4AD>8C0FeE>+Dqv*b@kq_d$>$2sFUm<#UL?xE VsLER?d1TuJr{OqX52m61D&U literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-check-crc32.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-check-crc32.xz new file mode 100644 index 0000000000000000000000000000000000000000..1ebe1310b5ae5e6cfce37b469772eb73e2ce6acf GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^5L6MPzfq~%$zp^kR1FJ`BPEI}-69Zd#eo;<}A{T@6;zc41 Xj4Hea8u!;vaGJ@>2vp0!7#RfsAA}ET literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-check-crc64.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-check-crc64.xz new file mode 100644 index 0000000000000000000000000000000000000000..cdb77093db1c301b8978b5b2b79ad9d4093ae3fd GIT binary patch literal 72 zcmexsUKJ6=z`*kC+7>q^21P~=1_p*3{K~?N46GihIXU@UObl${`9(P?id+ou^*RLS b+D|*pz^K7%lb*#azwL7^BTzj9OJo!P#6=R> literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-check-sha256.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-check-sha256.xz new file mode 100644 index 0000000000000000000000000000000000000000..def7bff174f11dc55521bae849b28beb3310add5 GIT binary patch literal 96 zcmexsUKJ6=z`*tJH_t*Q21P~=1_p*3{K~?N46GihIXU@UObl${`9(P?id+nRk*3cd z8fToH*72|3W5Lv*$>~{4qDc`tbuGQ?AKGtlXJB;To!sWPPGYwAEJmO?3|x^>0G}8h Au>b%7 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-1.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-1.xz new file mode 100644 index 0000000000000000000000000000000000000000..640f592e80359e942a1ec60fc64b274770b353cf GIT binary patch literal 64 zcmexsUKJ6=z`*cd=%ynRgCZjbkbQ$+S(u4|)gv`0C!dRnfh|10C?`dci-Cbrf!E~i R=F@CN^Qstu>KGUzqX7MX4<-Nr literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-10.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-10.xz new file mode 100644 index 0000000000000000000000000000000000000000..246515eaf5b43e63c1ee576136548d6f82e51495 GIT binary patch literal 60 zcmexsUKJ6=z`*cd=%ypn0RaO=Mh=E&S1V>P{{Qchnv;{y6`o&|lcLDQz$jyI>xRYy PwxW4ej6n4a43SX)k_Z$2 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-11.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-11.xz new file mode 100644 index 0000000000000000000000000000000000000000..ce857b67b8a989dceb009cfba6bb6b5a56de1eea GIT binary patch literal 64 zcmexsUKJ6=z`*cd=%yp{0Rdh`MjjxKfg${R)_g_=9*@+VoP34w{Gyx`MJ@(L1zwZ4 Qn@_V9&8uPrtBQ;Q084}sRsaA1 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-2.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-2.xz new file mode 100644 index 0000000000000000000000000000000000000000..69ab07d4577b6ff71f7521fe53759c6543192a2a GIT binary patch literal 424 zcmV;Z0ayP0H+ooF0004LBHlIv03iVg0002k4vH<%0_2e@^`p>hS)*d z1vSlsrF;^l1>2ClFBH>pa+auyeS}tVjcOv8tDZfOfGx*f3=&e)KL-eV9He*i6Sx<^ z?va5xvxo5i0JCaRLG3QE@?@8!nx12!t{HRDzhLwWI`Eq@>)$`vuccLzMg>?R36H2?2n(a>KD@LR+sC7#z!udM zry}St=(Nyx7sZR@^1Ex+@0x)$P95CrHs(ZfzbUmm1uvH<%0_2e@^`p>hS)*d z1vSlsrF;^l1>2ClFBH>pa+auyeS}tVjcOv8tDZfOfGx*f3=&e)KL-eV9He*i6Sx<^ z?va5xvxo5i0JCaRLG3QE@?@8!nx12!t{HRDzhLwWI`Eq@>)$`vuccLzMg>?R36H2?2n(a>KD@LR+sC7#z!udM zry}St=(Nyx7sZR@^1Ex+@0x)$P95CrHs(ZfzbUmm1ufCOZ6IWCY;STP zb7^!SVQpn}EFfcVZgXX0bY*mPav))3X>e(CX=7<_XCMlo0h0kF05Y2iY*g1Sm2CO< zH`N^CMgoF$`$=|T@N9l2BVfO zx0jsod;a1Qj4e^{+je(-qH7ud^_P!g>Dw^7v~WEZcmsDji+a_#_(~@w^^U3} z6s9RCYcF%)p>ec(q<~OB%J18>mHoTHjE-QJ+sl6;?Z6Om8hy*n3DDX9ZGgaMeLu#O z&s*J55z))kAlEB|PN+q@LU6C literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-5.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-5.xz new file mode 100644 index 0000000000000000000000000000000000000000..700464d51efa1e813c04e52263f6692aff20afd4 GIT binary patch literal 408 zcmV;J0cZaGH+ooF0004LBHlIv03iVg0002k4fCOZ6IWCY;STP zb7^!SVQpn}EFfcVZgXX0bY*mPav))3X>e(CX=7<_XCMlI0h0kF05Y2iY*g1Sm2CO< zH`N^CMgoF$`$=|T@N9l2BVfO zx0jsod;a1Qj4e^{+je(-qH7ud^_P!g>Dw^7v~WEZcmsDji+a_#_(~@w^^U3} z6s9RCYcF%)p>ec(q<~OB%J18>mHoTHjE-QJ+sl6;?Z6Om8hy*n3DDX9ZGgaMeLu#O z&s*J55z))kAlEB|PN+q@LU2vp0!7#RfsAG{B2 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-7.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-7.xz new file mode 100644 index 0000000000000000000000000000000000000000..8cc711c19ed67c7416a811fe0fdf71210487c23a GIT binary patch literal 408 zcmV;J0cZaGH+ooF000E$*0e?f03iVg0002k4vH<%0_2e@^`p>hS)*d z1vSlsrF;^l1>2ClFBH>p5`0a~5vk*40WO9~hLS=uQj{(bU$>5r{q-BhCIRrXySr}1 zdY0ke$TY+CPlE<1QGsOnfNF6^(Bh`n4P-ITiZEjPb2Um31;ozpwEokDHsI-J!0@%9 z9#U9T-9T3OoAX)m*5G;uRy;ku6@j}t>xB*ysa{hlP)@$!-3+>l!|)^*_VDD)+r1|%x2wUGVz9q}m8b{;f6>+}ca0ow&ZXJfUDM`^ zwdZ+3rqiB%C%j3Sg$wZxMIQSq_ty@5&+zn8NEmw&OYym>f$1j-H^WuEv{l=!x8Hf6 zMzxhod3zDrEfeDi)uDu-K|5{{(>D2fRa6k)2H{NCS4q8QX?+`@;e%)h9iaU*hMo<< zARA?M-8)}%%EE*H|LAH_*Z=^s2Sn)?GfRX30rLXM0{{Tu^N=I4#Ao{g000001X)@# C3&N=Y literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-8.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-8.xz new file mode 100644 index 0000000000000000000000000000000000000000..f21a71b63f38651fb1b520670337785589e2afd1 GIT binary patch literal 464 zcmV;>0WbdjH+ooF000E$*0e?f03iVg0002k4vH<%0_2e@^`p>hS)*d z1vSlsrF;^l1>2ClFBH>pa+auyeS}tVjcOv8tDZfOfGx*f3=&e)KL-eV9He*i6Sx<^ z?vZoKywB@2W~@k?Y1xwpuFg=eXbCS{h#$fTqAXZNu>WES>+aiQPjBG!AI}mun3hiV z^0NDGuS5dkBHq>JG?zJ}MK7+IFL`N?={Jc;{>*;rsVJ?(=G?j3suq3$048i%TbRc1DX>oOFa3E!PAZ1}7V{dJ3Z)9&E3ZMYx0KEV)o5~r*RP44?=dpdn zSDtK%tx9bc*gOT45Ehv@A)~p)fdBmN)YU)TjMqJncI=3%GOK0OIPdrQiof^xrB>H% z*FS{|o zgXk%sXUJwcebRwi>Q{oBCCdBuhzgtEK?808000282Sn)?GfRX30jdMZ0{{R}gK;&n#Ao{g00000 G1X)^h4%Vsw literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-9.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-lzma2-9.xz new file mode 100644 index 0000000000000000000000000000000000000000..0553905a0b5589bab4b5eb89455372dcb3dd7fef GIT binary patch literal 72 zcmexsUKJ6=z`&TPbkB_WfC#T5BL@QrSc?kqGBWUZq~_%0bA{&@<)kQbG5!Bv;k2vp0!7#RfsE!hvN literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-stream_flags-3.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-stream_flags-3.xz new file mode 100644 index 0000000000000000000000000000000000000000..a9b1f98365fda585c356b1e7c2db47a44b54c596 GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^5L6MPzfq~%$zp^kR1FJ`BPEI}-69Zd#eo;<}A{T@6;zgni Xj4Hea8u!;vaGJr(2vp0!7#RfsACC`e literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-v0-uncomp-size.lz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-v0-uncomp-size.lz new file mode 100644 index 0000000000000000000000000000000000000000..6bf4c6c7cadc9888693e145cde6e65fe2a1cabfb GIT binary patch literal 42 wcmeZ?@(f_$VNj9uoRQBes;+6951J literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-dict-1.lz b/cpp/third_party/xz-5.8.3/tests/files/bad-1-v1-dict-1.lz new file mode 100644 index 0000000000000000000000000000000000000000..20768d5f80f103849d65b87cceec318537b56227 GIT binary patch literal 50 wcmeZ?@(f_)W>AszoRQBes;@_XJp{UL?xE VsLER?d1TuJr$2sFUm<# h^6te`!3<1NY|`uu3~YCv$J!b2b~6FZU|@`l0swRj64d|z literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-2-index-1.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-2-index-1.xz new file mode 100644 index 0000000000000000000000000000000000000000..f51ed214d16b9652b2c1522561d481eac75ea390 GIT binary patch literal 92 zcmexsUKJ6=z`&TPbkB^5L6MPzfq~%$zp^kR1FJ`BPEI}-kS}IB%@9?NEj+&{Cq)q` gdH3R}UHYs)nhGQA*dUgi9-Aq6|42+Rc0BU9u5dZ)H literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-2-index-2.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-2-index-2.xz new file mode 100644 index 0000000000000000000000000000000000000000..d7d00ff343fea9fd49896c2ef605a71023f06249 GIT binary patch literal 92 zcmexsUKJ6=z`&TPbkB^5L6MPzfq~%$zp^kR1FJ`BPEI}-kS}IB%@9?NEj+&{Cq)q` fdH3R}UglDb_x>W literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-2-index-3.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-2-index-3.xz new file mode 100644 index 0000000000000000000000000000000000000000..62428b87223690e63b08a793bed03d02762fa300 GIT binary patch literal 92 zcmexsUKJ6=z`&TPbkB^5L6MPzfq~%$zp^kR1FJ`BPEI}-kS}IB%@9?NEj+&{Cq)q` hdH3R}UFfc|&0RVb?6Ey$; literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-2-index-4.xz b/cpp/third_party/xz-5.8.3/tests/files/bad-2-index-4.xz new file mode 100644 index 0000000000000000000000000000000000000000..9cf2df65da5ffed8efae5a28128d4408088f89b7 GIT binary patch literal 92 zcmexsUKJ6=z`&TPbkB^5L6MPzfq~%$zp^kR1FJ`BPEI}-kS}IB%@9?NEj+&{Cq)q` gdH3R}U literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-too_small_size-without_eopm-2.lzma b/cpp/third_party/xz-5.8.3/tests/files/bad-too_small_size-without_eopm-2.lzma new file mode 100644 index 0000000000000000000000000000000000000000..e37cab14d6a43ddb6588927c09e9d30d75d136bb GIT binary patch literal 31 gcma!L5MW?nW`F_}NzWPitfK1byk!*^G-VYS05fw0mjD0& literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-too_small_size-without_eopm-3.lzma b/cpp/third_party/xz-5.8.3/tests/files/bad-too_small_size-without_eopm-3.lzma new file mode 100644 index 0000000000000000000000000000000000000000..67a1af34570be3920d7e5184ef040efdfa3015e2 GIT binary patch literal 36 mcma!L5MW^7WPkz{NzWPitfGetG}y&2mi{-rGQ-_3fdK$zQ3!GX literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/bad-unknown_size-without_eopm.lzma b/cpp/third_party/xz-5.8.3/tests/files/bad-unknown_size-without_eopm.lzma new file mode 100644 index 0000000000000000000000000000000000000000..b3d7a52162dd8102f861159ec434f8e580fc769d GIT binary patch literal 31 hcma!L5MW^V4+RV=lAbg2Sw+>=dCMv;Xv!)u008E342%E( literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-0-empty.xz b/cpp/third_party/xz-5.8.3/tests/files/good-0-empty.xz new file mode 100644 index 0000000000000000000000000000000000000000..83b95e05bc814cb60f759a30e89d243960797b60 GIT binary patch literal 32 kcmexsUKJ6=z`&TPbkB?d2xRWNC{A#i$;$}hFh)iJ0Fqb-jsO4v literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-0cat-empty.xz b/cpp/third_party/xz-5.8.3/tests/files/good-0cat-empty.xz new file mode 100644 index 0000000000000000000000000000000000000000..e6fc31461db459ae9075e704581317d910b4afee GIT binary patch literal 64 ncmexsUKJ6=z`&TPbkB?d2xRWNC{A#i$;$}hFh)lGB_Iy~7H$t4 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-0catpad-empty.xz b/cpp/third_party/xz-5.8.3/tests/files/good-0catpad-empty.xz new file mode 100644 index 0000000000000000000000000000000000000000..4f86b7d152d477b0da914aff1590000e89bf1183 GIT binary patch literal 68 qcmexsUKJ6=z`&TPbkB?d2xRWNC{A#i$;$}hFh&BU7#RK%Py+xorVkqc literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-0pad-empty.xz b/cpp/third_party/xz-5.8.3/tests/files/good-0pad-empty.xz new file mode 100644 index 0000000000000000000000000000000000000000..c51e3a69c0de7e68ad78338a6c86cb2980eb1a2f GIT binary patch literal 36 mcmexsUKJ6=z`&TPbkB?d2xRWNC{A#i$;$}hFh&BU7#IMskOz(c literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-3delta-lzma2.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-3delta-lzma2.xz new file mode 100644 index 0000000000000000000000000000000000000000..a0be1d007a206f8a7849400b1343c67784dc4809 GIT binary patch literal 528 zcmV+r0`L9(H+ooF000E$*0e?h0|Nm70|5a80RkZb2mk=Q6=lW&0mw`vw}j#eaZmcX zq4!Z^2&}I1SV9eE?x+FHU@nMQ*KXTACIAKT`>!--7r>uC`TPwI1El7!X|ZCSN0&px zFGr)J^#oeLn>_){TRQr)!c3h{SN*%MQ~w74^`}u@q?}{4v|{&1pipkF;|o&5r#HY< zNddXE|2tmwZ8yUJ^Q+|Uc32$NxO8Zp-%n0rcCj_ zRA%p_tx+K35AF;Cq+>h(sK-_Uuiddw!DshN@3dM+2De|MO{(J;WxJ>_2DMUPr}Xg` z75PD}w>lNL>YrxEQPE);?FhX8TXFGkdS{LWrd678{+yx&U10mCw(?F7M=dFx>EAL@10)4R_I;( z1fpA0{kN)Hu{Krk>y9EkKRQZh;&ACC{yaY4=000282Sn)?GfRX30qFzD0{{S$ S`@Oue#Ao{g000001X)_0Yy40E literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-arm64-lzma2-1.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-arm64-lzma2-1.xz new file mode 100644 index 0000000000000000000000000000000000000000..78169f14e55bab6df64b171e02d275d1c878f095 GIT binary patch literal 512 zcmV+b0{{K}H+ooF0004LBHlIv0SW*i0SEx1*naWgA%6kGZU6viBZzTh!jDr5=CR+< zimn@>uz0H|Lla(qI_!Jbnq4vWOm!4B`dTUMI zf2*~D8PbQdj#Sbkr5HuKm#?*r6OD!0ixJf`b2ir4#$zA@8waxQC$A18F-0{2}WS>SKs z-OTxr%O_c&qi>dTg3nEHAs$Y@&(JBd&sJ_BkH~kG>uT>j+yHj4lw)v=lwW@zgZUrM zWKTuC_!C-q3>x3$3*5Q~Gwf5T`!VIr!-tiS^^=YQ?&DUb`O~9#r3fUv9xADscuVNJ zb4Shy3|axs;l-VW+|(IawLP!(q|as&{agMDdhYjOfeHo*UCR)~Z)i{L?U%o#3}QZ7oP3 zjDb;5VDF&-aoOXwPyJW64*Wn!(*OXVeBsmp0owzBLjV9n$BAP;Fb#_W000000a;o` ChV}3O literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-arm64-lzma2-2.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-arm64-lzma2-2.xz new file mode 100644 index 0000000000000000000000000000000000000000..e0302fe99e994db8e02e58b5deebb0059c90bdf4 GIT binary patch literal 488 zcmV)t{1c60fMoJHkN$TUSJebxP_`X z7)fn4$7IFT8LOEEk7OxZIpYez9Oh~Cddvz2-Q^}z$*Hd|L?S)qmODUDNM`jN-lcN6MFEp*`GzEE0iV*SI z^QXwyBTGKmlwSorwDZJTrl@CHbCSk*q%(OA70=FcM6l&R7n)du1lSNRR40$f3k z48I+C<7lCVHqH*qCcQ{=EvTI;r$8yn=f}iXi>l*~##Di{8U#;nB6plx-xJUP0001> eeBsmp0m1`-LjV8}lu$=LFb#_W000000a;oZ9p=jb literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-1.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-1.xz new file mode 100644 index 0000000000000000000000000000000000000000..fea5ad2f9980d5d9145700561a980e6e106b4e32 GIT binary patch literal 72 zcmexsUKJ6=z`&TPbkB_WfFQ3TBL@Qr)Zepw&B(yxk(!f}&lR3ul#`;!1rm2&yhxOR VQI)q)^2oLcPBVEKL4u5tQ2?t(5zGJp literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-2.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-2.xz new file mode 100644 index 0000000000000000000000000000000000000000..6b5dcb347b24d1a5abf4150b1e3c9039b1b65a0d GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^*K~RyAgMq=yr{f_b1CK{)PEI~ocz#h%iXs;S5I8ShB+9_3 U$Xj}6#ia>OGkF<7f{c+-0BF(?ZvX%Q literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-3.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-block_header-3.xz new file mode 100644 index 0000000000000000000000000000000000000000..156531206342a87baa8029915aae0c940301c5ed GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^bfme}{gMlGXurZR6fyW~?CnujPJijO>MUjgE2%Hx$5@ldi U2vp0!7#RfsADItp literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-check-crc64.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-check-crc64.xz new file mode 100644 index 0000000000000000000000000000000000000000..5a9915d2f9fc4711b26ed2d399027583bf824340 GIT binary patch literal 72 zcmexsUKJ6=z`*kC+7>q^21P~=1_p*3{K~?N46GihIXU@UObl${`9(P?id+ou^*RLS b+D|*hz^K7%lb*#azwL7^BTzj9OJo!P#4r-r literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-check-none.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-check-none.xz new file mode 100644 index 0000000000000000000000000000000000000000..1e85faf3d06eff1bc420925a1af096762b00db51 GIT binary patch literal 64 zcmexsUKJ6=z`*cd=%ynRgCZjbkbQ$+S(uT5)gv`0C!dRnfh|10C?`dci-Cbrf!E~i R=F@CN^Qstu>KGUzqX7L^4~{4qDc`tbuGQ?AKGtlV_0G|UM AumAu6 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-delta-lzma2.tiff.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-delta-lzma2.tiff.xz new file mode 100644 index 0000000000000000000000000000000000000000..1f033bc52b5d3e8950a34ed118b8837c964771b7 GIT binary patch literal 51316 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-1.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-1.xz new file mode 100644 index 0000000000000000000000000000000000000000..d8d6489c872156e67ba5efb74bb5215524017c90 GIT binary patch literal 424 zcmV;Z0ayP0H+ooF0004LBHlIv03iVg0002k4vH<%0_2e@^`p>hS)*d z1vSlsrF;^l1>2ClFBH>pa+auyeS}tVjcOv8tDZfOfGx*f3=&e)KL-eV9He*i6Sx<^ z?va5xvxo5i0JCaRLG3QE@?@8!nx12!t{HRDzhLwWI`Eq@>)$`vuccLzMg>?R36H2?2n(a>KD@LR+sC7#z!udM zry}St=(Nyx7sZR@^1Ex+@0x)$P95CrHs(ZfzbUmm1uvH<%0_2e@^`p>hS)*d z1vSlsrF;^l1>2ClFBH>pa+auyeS}tVjcOv8tDZfOfGx*f3=&e)KL-eV9He*i6Sx<^ z?va5xvxo5i0JCaRLG3QE@?@8!nx12!t{HRF!iN;a*~>rB7^clCOI@hPUjb(*Of2Ng)l#05 z0)7x(^#ie(FDC7VdscrFd03A`5ZT!emgzgcwYb_V;nsoi$p8TRM@ZWM0fPg{0{{T7 S*U}X}Fb#_W000000a;o&?Zkcn literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-3.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-3.xz new file mode 100644 index 0000000000000000000000000000000000000000..c4c72be6561465781670b5a9b6067b1cfa016f7a GIT binary patch literal 408 zcmV;J0cZaGH+ooF0004LBHlIv03iVg0002k4fCOZ6IWCY;STP zb7^!SVQpn}EFfcVZgXX0bY*mPav))3X>e(CX=7<_XCMl|0h0kFT>vth32ao?E|qNg z_czrX;zk03b^A$njdN4B{cYRI+u1}5u`a$7wz{a|^X+w1+(97BzcyPSnOzSdp$4Ot zEw`7P@O%E^5{xZT@Y{BGeWZKSmFfEh=Jl74V(Hs3yR>jU7I*`9I*WSMxcEvZCH0P~ zBowA8C~Gfs;GuD}d!&F+K+5miw3Yq4!HkYzm)pyKA??5raT}jB^kOtXvnab% zHr;v-95y95SO)kNqs|z}{gxhSDFeg3C-diz+jF!lPdHd4zk?Jxesk{r&&s{?A!;aq z$c|ls$GjKNER(eemAVd+f@ZG&xB~$DM@ZWM0rUdN0{{SL!<9ZhFb#_W000000a;q- Ccebnm literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-4.xz b/cpp/third_party/xz-5.8.3/tests/files/good-1-lzma2-4.xz new file mode 100644 index 0000000000000000000000000000000000000000..e0d623a001ce5dbf48b55cff0168d01e1b012272 GIT binary patch literal 464 zcmV;>0WbdjH+ooF000E$*0e?f03iVg0002k4vH<%0_2e@^`p>hS)*d z1vSlsrF;^l1>2ClFBH>pa+auyeS}tVjcOv8tDZfOfGx*f3=&e)KL-eV9He*i6Sx<^ z?vZoKywB@2W~@k?Y1xwpuFg=eXbCS{h#$fTqAXZNu>WES>+aiQPjBG!AI}mun3hiV z^0NDGuS5dkBHq>JG?zJ}MK7+IFL`N?={Jc;{>*;rsVJ?(=G?j3suq3$048i%TbRc1DX>oOFa3E!PAZ1}7V{dJ3Z)9&E3cvv60KHuRF`LR6#Z>IJROhjM z#8;kdiLFX)7T7!mln@q~I3c6C#eo0(?$p&k-Hg{gk9O>csxqr()Hv_=`HH{y_@!3Y zZP!1A3!XpXM`$7l1vR)qa{1f7w~mItLrabgLoY#T-(d{I=r;&T-okbkxJXW(xl>Rd zGlS?Upl8TtI)5S(V*5wry!25I6^KdL$_pinUg+BWIKa+Ka~uEAo9Ilp6Zkio;@X@q zwd%N~jp|o|n{ax?7E&u=k literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-1-v1.lz b/cpp/third_party/xz-5.8.3/tests/files/good-1-v1.lz new file mode 100644 index 0000000000000000000000000000000000000000..4c9565c8175dd05d734cad3f8a1dcbce763bb662 GIT binary patch literal 50 wcmeZ?@(f_)VNj9uoRQBes;`*lTNBS2C literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-2-v1-v1.lz b/cpp/third_party/xz-5.8.3/tests/files/good-2-v1-v1.lz new file mode 100644 index 0000000000000000000000000000000000000000..5381891b9cb1373eb751ad5e510862025088d7ef GIT binary patch literal 86 zcmeZ?@(f_)VNj9uoRQD!u)hBP{|6il3}U9!4A~eUKnqIyKvZhaKIL}z`_T_(yZ`_H TA9;a+;qJv#!R$~qI#3z_0nryV literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-known_size-with_eopm.lzma b/cpp/third_party/xz-5.8.3/tests/files/good-known_size-with_eopm.lzma new file mode 100644 index 0000000000000000000000000000000000000000..1b45307930a582815373a9aa7ba4eda42cfa5fba GIT binary patch literal 37 ncma!L5MW^7Wq<+|NzWPitfK1byk!*^v@*m+|Nk%j!N33jV&({B literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-known_size-without_eopm.lzma b/cpp/third_party/xz-5.8.3/tests/files/good-known_size-without_eopm.lzma new file mode 100644 index 0000000000000000000000000000000000000000..83623fde97dbd6e3f939533875e874c1b6a1353d GIT binary patch literal 31 gcma!L5MW^7Wq<+|NzWPitfK1byk!*^G-VYS05o?5p#T5? literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/good-unknown_size-with_eopm.lzma b/cpp/third_party/xz-5.8.3/tests/files/good-unknown_size-with_eopm.lzma new file mode 100644 index 0000000000000000000000000000000000000000..0f4ff822e94e7314aba944420b0480a5652db340 GIT binary patch literal 37 ncma!L5MW^V4+RV=lAbg2Sw+>=dCMv;Xl00t{{LV4gMk46L~#&L literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/unsupported-1-v234.lz b/cpp/third_party/xz-5.8.3/tests/files/unsupported-1-v234.lz new file mode 100644 index 0000000000000000000000000000000000000000..e571b0fa9e7353882d562e0c449ac4b8e31b4ddc GIT binary patch literal 50 wcmeZ?@(g&z!=NJRIU}D{R9&67tm1-JhPdee|D`_|7@QX`66Ixp03#?30C^1y`v3p{ literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/unsupported-block_header.xz b/cpp/third_party/xz-5.8.3/tests/files/unsupported-block_header.xz new file mode 100644 index 0000000000000000000000000000000000000000..38304429d916e7f7c2fac0b473b3ebbcda62a964 GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^5L6MOI$o8{WNnvDQ^+?Uh$>(BXU<=PL%1Ke=VsKu(NR)w5 Vh1Wpi{`v_{GkF;qfPgVF3IH7?4`cuU literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/unsupported-check.xz b/cpp/third_party/xz-5.8.3/tests/files/unsupported-check.xz new file mode 100644 index 0000000000000000000000000000000000000000..c28355e7474b7350e7297f73a89a197d8ac426c9 GIT binary patch literal 68 zcmexsUKJ6=z`%65`1*P#21P~=1_p*3{K~?N46GihIXU@UObl${`9(P?id+oNix-J9 XFskqxXxv|~B|KpYBTy{^Q)CnXVowl* literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-1.xz b/cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-1.xz new file mode 100644 index 0000000000000000000000000000000000000000..48b93731c52b4c0fb2bc5724a38e16e5ea37b8e6 GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^5p`HN@(u?mhGO&82=H%paF)^@(=NILqC~`44FJ2_dz^KA& SpmBfw1gDw2j3C8~kx>9kA`n^t literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-2.xz b/cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-2.xz new file mode 100644 index 0000000000000000000000000000000000000000..c283359d56204cd1fa673fb54d4642b30cf36155 GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^5ftm3?0|UeF)^ARX46GihIXU@UObl${`9(P?id+oNix-J9 XFskqxXxv{v!D%KhBTy{^V`LNnmDmyA literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-3.xz b/cpp/third_party/xz-5.8.3/tests/files/unsupported-filter_flags-3.xz new file mode 100644 index 0000000000000000000000000000000000000000..26084984f97da6e03bd6e326d6ef4b333cd47045 GIT binary patch literal 68 zcmexsUKJ6=z`&TPbkB^5QIU}Yh)ztDp3TU>>XDk0lh4J(z!sigl#`;!#o)YnkthSB V3a^32{q+-^X7VyJ00CoU6aZ6m5QqQ( literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/Makefile b/cpp/third_party/xz-5.8.3/tests/ossfuzz/Makefile new file mode 100644 index 000000000..742e06361 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/Makefile @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: 0BSD + +FUZZ_TARGET_SRCS = $(wildcard *.c) +FUZZ_TARGET_BINS = $(FUZZ_TARGET_SRCS:.c=) + +all: $(FUZZ_TARGET_BINS) + +%: %.c + $(CC) $(CFLAGS) -c $< -I ../../src/liblzma/api/ ; + $(CXX) $(CXXFLAGS) $(LIB_FUZZING_ENGINE) $(<:.c=.o) -o $(OUT)/$@ \ + ../../src/liblzma/.libs/liblzma.a ; + +# The generated binaries are not removed, just the object files. The +# binaries are created to the $(OUT) directory and must be removed by the +# fuzzing framework. +clean: + rm -f *.o diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_alone.options b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_alone.options new file mode 100644 index 000000000..1351d96c8 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_alone.options @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: 0BSD + +[libfuzzer] +max_len = 4096 +dict = fuzz_lzma.dict diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_stream.options b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_stream.options new file mode 100644 index 000000000..bbf43ac42 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_stream.options @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: 0BSD + +[libfuzzer] +dict = fuzz_xz.dict diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_stream_mt.options b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_stream_mt.options new file mode 100644 index 000000000..bbf43ac42 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_decode_stream_mt.options @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: 0BSD + +[libfuzzer] +dict = fuzz_xz.dict diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_encode_stream.options b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_encode_stream.options new file mode 100644 index 000000000..86d4f0c6b --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_encode_stream.options @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: 0BSD + +[libfuzzer] +max_len = 4096 diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_lzma.dict b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_lzma.dict new file mode 100644 index 000000000..b9d5dff75 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_lzma.dict @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: 0BSD + +# first 5 header bytes of .lzma archives based on the info from +# /doc/lzma-file-format.txt + +# byte 0 is created by encoding LZMA property values (lc, lp, pb) +# using the algorithm described in the documentation above. + +# lc=3, lp=0, pb=2 and dictionary size = 0x00100000 +"\x5d\x00\x00\x10\x00" + +# lc=3, lp=1, pb=3 and dictionary size = 0x00100000 +"\x93\x00\x00\x10\x00" + +# lc=2, lp=2, pb=4 and dictionary size = 0x00100000 +"\xc8\x00\x00\x10\x00" + +# lc=1, lp=3, pb=1 and dictionary size = 0x00200000 +"\x49\x00\x00\x20\x00" + +# lc=0, lp=4, pb=0 and dictionary size = 0x00200000 +"\x24\x00\x00\x20\x00" diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_xz.dict b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_xz.dict new file mode 100644 index 000000000..6ba4f24a1 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/config/fuzz_xz.dict @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: 0BSD + +"\xFD7zXZ\x00" +"YZ" diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_common.h b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_common.h new file mode 100644 index 000000000..b47a3bdf4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_common.h @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file fuzz_common.h +/// \brief Common macros and functions needed by the fuzz targets +// +// Authors: Maksym Vatsyk +// Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "lzma.h" + +// Some header values can make liblzma allocate a lot of RAM +// (up to about 4 GiB with liblzma 5.2.x). We set a limit here to +// prevent extreme allocations when fuzzing. +#define MEM_LIMIT (300 << 20) // 300 MiB + +// Amount of input to pass to lzma_code() per call at most. +#define IN_CHUNK_SIZE 2047 + + +static void +fuzz_code(lzma_stream *stream, const uint8_t *inbuf, size_t inbuf_size) { + // Output buffer for decompressed data. This is write only; nothing + // cares about the actual data written here. + uint8_t outbuf[4096]; + + // Pass half of the input on the first call and then proceed in + // chunks. It's fine that this rounds to 0 when inbuf_size is 1. + stream->next_in = inbuf; + stream->avail_in = inbuf_size / 2; + + lzma_action action = LZMA_RUN; + + lzma_ret ret; + do { + if (stream->avail_in == 0 && inbuf_size > 0) { + const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE + ? inbuf_size : IN_CHUNK_SIZE; + + stream->next_in = inbuf; + stream->avail_in = chunk_size; + + inbuf += chunk_size; + inbuf_size -= chunk_size; + + if (inbuf_size == 0) + action = LZMA_FINISH; + } + + if (stream->avail_out == 0) { + // outbuf became full. We don't care about the + // uncompressed data there, so we simply reuse + // the outbuf and overwrite the old data. + stream->next_out = outbuf; + stream->avail_out = sizeof(outbuf); + } + } while ((ret = lzma_code(stream, action)) == LZMA_OK); + + // LZMA_PROG_ERROR should never happen as long as the code calling + // the liblzma functions is correct. Thus LZMA_PROG_ERROR is a sign + // of a bug in either this function or in liblzma. + if (ret == LZMA_PROG_ERROR) { + fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n"); + abort(); + } +} diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_alone.c b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_alone.c new file mode 100644 index 000000000..1ef2f9e7a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_alone.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file fuzz_decode_alone.c +/// \brief Fuzz test program for liblzma .lzma decoding +// +// Authors: Maksym Vatsyk +// Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "lzma.h" +#include "fuzz_common.h" + + +extern int +LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size) +{ + lzma_stream strm = LZMA_STREAM_INIT; + // Initialize a LZMA alone decoder using the memory usage limit + // defined in fuzz_common.h + lzma_ret ret = lzma_alone_decoder(&strm, MEM_LIMIT); + + if (ret != LZMA_OK) { + // This should never happen unless the system has + // no free memory or address space to allow the small + // allocations that the initialization requires. + fprintf(stderr, "lzma_alone_decoder() failed (%d)\n", ret); + abort(); + } + + fuzz_code(&strm, inbuf, inbuf_size); + + // Free the allocated memory. + lzma_end(&strm); + return 0; +} diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_stream.c b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_stream.c new file mode 100644 index 000000000..d7860611a --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_stream.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file fuzz_decode_stream.c +/// \brief Fuzz test program for single threaded .xz decoding +// +// Authors: Lasse Collin +// Maksym Vatsyk +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "lzma.h" +#include "fuzz_common.h" + + +extern int +LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size) +{ + lzma_stream strm = LZMA_STREAM_INIT; + // Initialize a .xz decoder using the memory usage limit + // defined in fuzz_common.h + // + // Enable support for concatenated .xz files which is used when + // decompressing regular .xz files (instead of data embedded inside + // some other file format). Integrity checks on the uncompressed + // data are ignored to make fuzzing more effective (incorrect check + // values won't prevent the decoder from processing more input). + // + // The flag LZMA_IGNORE_CHECK doesn't disable verification of + // header CRC32 values. Those checks are disabled when liblzma is + // built with the #define FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION. + lzma_ret ret = lzma_stream_decoder(&strm, MEM_LIMIT, + LZMA_CONCATENATED | LZMA_IGNORE_CHECK); + + if (ret != LZMA_OK) { + // This should never happen unless the system has + // no free memory or address space to allow the small + // allocations that the initialization requires. + fprintf(stderr, "lzma_stream_decoder() failed (%d)\n", ret); + abort(); + } + + fuzz_code(&strm, inbuf, inbuf_size); + + // Free the allocated memory. + lzma_end(&strm); + + return 0; +} diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_stream_mt.c b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_stream_mt.c new file mode 100644 index 000000000..23ea97657 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_decode_stream_mt.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file fuzz_decode_stream_mt.c +/// \brief Fuzz test program for multithreaded .xz decoding +// +// Author: Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "lzma.h" +#include "fuzz_common.h" + + +extern int +LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size) +{ + lzma_stream strm = LZMA_STREAM_INIT; + + lzma_mt mt = { + .flags = LZMA_CONCATENATED | LZMA_IGNORE_CHECK, + .threads = 2, + .timeout = 0, + .memlimit_threading = MEM_LIMIT / 2, + .memlimit_stop = MEM_LIMIT, + }; + + lzma_ret ret = lzma_stream_decoder_mt(&strm, &mt); + + if (ret != LZMA_OK) { + // This should never happen unless the system has + // no free memory or address space to allow the small + // allocations that the initialization requires. + fprintf(stderr, "lzma_stream_decoder_mt() failed (%d)\n", ret); + abort(); + } + + fuzz_code(&strm, inbuf, inbuf_size); + + lzma_end(&strm); + + return 0; +} diff --git a/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_encode_stream.c b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_encode_stream.c new file mode 100644 index 000000000..9438263f3 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/ossfuzz/fuzz_encode_stream.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file fuzz_encode_stream.c +/// \brief Fuzz test program for .xz encoding +// +// Authors: Maksym Vatsyk +// Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "lzma.h" +#include "fuzz_common.h" + + +extern int +LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size) +{ + if (inbuf_size == 0) { + fprintf(stderr, "no input data provided\n"); + return 0; + } + + // Set the LZMA options based on the first input byte. The fuzzer + // will learn through its mutational genetic algorithm with the + // code coverage feedback that the first byte must be one of the + // values with a switch case label. This allows us to have one fuzz + // target cover many critical code paths so the fuzz resources can + // be used efficiently. + uint32_t preset_level; + const uint8_t decider = inbuf[0]; + + switch (decider) { + case 0: + case 1: + case 5: + preset_level = (uint32_t)decider; + break; + case 6: + preset_level = 0 | LZMA_PRESET_EXTREME; + break; + case 7: + preset_level = 3 | LZMA_PRESET_EXTREME; + break; + default: + return 0; + } + + // Initialize lzma_options with the above preset level + lzma_options_lzma opt_lzma; + if (lzma_lzma_preset(&opt_lzma, preset_level)){ + fprintf(stderr, "lzma_lzma_preset() failed\n"); + abort(); + } + + // Set the filter chain as only LZMA2. + lzma_filter filters[2] = { + { + .id = LZMA_FILTER_LZMA2, + .options = &opt_lzma, + }, { + .id = LZMA_VLI_UNKNOWN, + } + }; + + // initialize empty LZMA stream + lzma_stream strm = LZMA_STREAM_INIT; + + // Initialize the stream encoder using the above + // stream, filter chain and CRC64. + lzma_ret ret = lzma_stream_encoder(&strm, filters, LZMA_CHECK_CRC64); + if (ret != LZMA_OK) { + fprintf(stderr, "lzma_stream_encoder() failed (%d)\n", ret); + abort(); + } + + fuzz_code(&strm, inbuf + 1, inbuf_size - 1); + + // Free the allocated memory. + lzma_end(&strm); + return 0; +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_bcj_exact_size.c b/cpp/third_party/xz-5.8.3/tests/test_bcj_exact_size.c new file mode 100644 index 000000000..c73560ca4 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_bcj_exact_size.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_bcj_exact_size.c +/// \brief Tests BCJ decoding when the output size is known +/// +/// These tests fail with XZ Utils 5.0.3 and earlier. +// +// Author: Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + + +static void +test_exact_size(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + if (!lzma_filter_encoder_is_supported(LZMA_FILTER_POWERPC) + || !lzma_filter_decoder_is_supported( + LZMA_FILTER_POWERPC)) + assert_skip("PowerPC BCJ encoder and/or decoder " + "is disabled"); + + // Something to be compressed + const uint8_t in[16] = "0123456789ABCDE"; + + // in[] after compression + uint8_t compressed[1024]; + size_t compressed_size = 0; + + // Output buffer for decompressing compressed[] + uint8_t out[sizeof(in)]; + + // Compress with PowerPC BCJ and LZMA2. PowerPC BCJ is used because + // it has fixed 4-byte alignment which makes triggering the potential + // bug easy. + lzma_options_lzma opt_lzma2; + assert_false(lzma_lzma_preset(&opt_lzma2, 0)); + + lzma_filter filters[3] = { + { .id = LZMA_FILTER_POWERPC, .options = NULL }, + { .id = LZMA_FILTER_LZMA2, .options = &opt_lzma2 }, + { .id = LZMA_VLI_UNKNOWN, .options = NULL }, + }; + + assert_lzma_ret(lzma_stream_buffer_encode( + filters, LZMA_CHECK_CRC32, NULL, + in, sizeof(in), + compressed, &compressed_size, sizeof(compressed)), + LZMA_OK); + + // Decompress so that we won't give more output space than + // the Stream will need. + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_stream_decoder(&strm, 10 << 20, 0), LZMA_OK); + + strm.next_in = compressed; + strm.next_out = out; + + while (true) { + if (strm.total_in < compressed_size) + strm.avail_in = 1; + + const lzma_ret ret = lzma_code(&strm, LZMA_RUN); + if (ret == LZMA_STREAM_END) { + assert_uint_eq(strm.total_in, compressed_size); + assert_uint_eq(strm.total_out, sizeof(in)); + lzma_end(&strm); + return; + } + + assert_lzma_ret(ret, LZMA_OK); + + if (strm.total_out < sizeof(in)) + strm.avail_out = 1; + } +#endif +} + + +static void +test_empty_block(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + if (!lzma_filter_decoder_is_supported(LZMA_FILTER_POWERPC)) + assert_skip("PowerPC BCJ decoder is disabled"); + + // An empty file with one Block using PowerPC BCJ and LZMA2. + size_t in_size; + uint8_t *empty_bcj_lzma2 = tuktest_file_from_srcdir( + "files/good-1-empty-bcj-lzma2.xz", &in_size); + + // Decompress without giving any output space. + uint64_t memlimit = 1 << 20; + uint8_t out[1]; + size_t in_pos = 0; + size_t out_pos = 0; + assert_lzma_ret(lzma_stream_buffer_decode(&memlimit, 0, NULL, + empty_bcj_lzma2, &in_pos, in_size, out, &out_pos, 0), + LZMA_OK); + assert_uint_eq(in_pos, in_size); + assert_uint_eq(out_pos, 0); +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + + tuktest_run(test_exact_size); + tuktest_run(test_empty_block); + + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_block_header.c b/cpp/third_party/xz-5.8.3/tests/test_block_header.c new file mode 100644 index 000000000..a9d669cdb --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_block_header.c @@ -0,0 +1,519 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_block_header.c +/// \brief Tests Block Header coders +// +// Authors: Lasse Collin +// Jia Tan +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + + +static lzma_options_lzma opt_lzma; + + +// Used in test_lzma_block_header_decode() between tests to ensure +// no artifacts are leftover in the block struct that could influence +// later tests. +#define RESET_BLOCK(block, buf) \ +do { \ + lzma_filter *filters_ = (block).filters; \ + lzma_filters_free(filters_, NULL); \ + memzero((buf), sizeof((buf))); \ + memzero(&(block), sizeof(lzma_block)); \ + (block).filters = filters_; \ + (block).check = LZMA_CHECK_CRC32; \ +} while (0) + + +#ifdef HAVE_ENCODERS +static lzma_filter filters_none[1] = { + { + .id = LZMA_VLI_UNKNOWN, + }, +}; + + +static lzma_filter filters_one[2] = { + { + .id = LZMA_FILTER_LZMA2, + .options = &opt_lzma, + }, { + .id = LZMA_VLI_UNKNOWN, + } +}; + + +// These filters are only used in test_lzma_block_header_decode() +// which only runs if encoders and decoders are configured. +#ifdef HAVE_DECODERS +static lzma_filter filters_four[5] = { + { + .id = LZMA_FILTER_X86, + .options = NULL, + }, { + .id = LZMA_FILTER_X86, + .options = NULL, + }, { + .id = LZMA_FILTER_X86, + .options = NULL, + }, { + .id = LZMA_FILTER_LZMA2, + .options = &opt_lzma, + }, { + .id = LZMA_VLI_UNKNOWN, + } +}; +#endif + + +static lzma_filter filters_five[6] = { + { + .id = LZMA_FILTER_X86, + .options = NULL, + }, { + .id = LZMA_FILTER_X86, + .options = NULL, + }, { + .id = LZMA_FILTER_X86, + .options = NULL, + }, { + .id = LZMA_FILTER_X86, + .options = NULL, + }, { + .id = LZMA_FILTER_LZMA2, + .options = &opt_lzma, + }, { + .id = LZMA_VLI_UNKNOWN, + } +}; +#endif + + +static void +test_lzma_block_header_size(void) +{ +#ifndef HAVE_ENCODERS + assert_skip("Encoder support disabled"); +#else + if (!lzma_filter_encoder_is_supported(LZMA_FILTER_X86)) + assert_skip("x86 BCJ encoder is disabled"); + + lzma_block block = { + .version = 0, + .filters = filters_one, + .compressed_size = LZMA_VLI_UNKNOWN, + .uncompressed_size = LZMA_VLI_UNKNOWN, + .check = LZMA_CHECK_CRC32 + }; + + // Test that all initial options are valid + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN); + assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX); + assert_uint_eq(block.header_size % 4, 0); + + // Test invalid version number + for (uint32_t i = 2; i < 20; i++) { + block.version = i; + assert_lzma_ret(lzma_block_header_size(&block), + LZMA_OPTIONS_ERROR); + } + + block.version = 1; + + // Test invalid compressed size + block.compressed_size = 0; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR); + + block.compressed_size = LZMA_VLI_MAX + 1; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR); + block.compressed_size = LZMA_VLI_UNKNOWN; + + // Test invalid uncompressed size + block.uncompressed_size = LZMA_VLI_MAX + 1; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR); + block.uncompressed_size = LZMA_VLI_MAX; + + // Test invalid filters + block.filters = NULL; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR); + + block.filters = filters_none; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR); + + block.filters = filters_five; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_PROG_ERROR); + + block.filters = filters_one; + + // Test setting compressed_size to something valid + block.compressed_size = 4096; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN); + assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX); + assert_uint_eq(block.header_size % 4, 0); + + // Test setting uncompressed_size to something valid + block.uncompressed_size = 4096; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN); + assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX); + assert_uint_eq(block.header_size % 4, 0); + + // This should pass, but header_size will be an invalid value + // because the total block size will not be able to fit in a valid + // lzma_vli. This way a temporary value can be used to reserve + // space for the header and later the actual value can be set. + block.compressed_size = LZMA_VLI_MAX; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN); + assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX); + assert_uint_eq(block.header_size % 4, 0); + + // Use an invalid value for a filter option. This should still pass + // because the size of the LZMA2 properties is known by liblzma + // without reading any of the options so it doesn't validate them. + lzma_options_lzma bad_ops; + assert_false(lzma_lzma_preset(&bad_ops, 1)); + bad_ops.pb = 0x1000; + + lzma_filter bad_filters[2] = { + { + .id = LZMA_FILTER_LZMA2, + .options = &bad_ops + }, + { + .id = LZMA_VLI_UNKNOWN, + .options = NULL + } + }; + + block.filters = bad_filters; + + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN); + assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX); + assert_uint_eq(block.header_size % 4, 0); + + // Use an invalid block option. The check type isn't stored in + // the Block Header and so _header_size ignores it. + block.check = INVALID_LZMA_CHECK_ID; + block.ignore_check = false; + + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_uint(block.header_size, >=, LZMA_BLOCK_HEADER_SIZE_MIN); + assert_uint(block.header_size, <=, LZMA_BLOCK_HEADER_SIZE_MAX); + assert_uint_eq(block.header_size % 4, 0); +#endif +} + + +static void +test_lzma_block_header_encode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + + if (!lzma_filter_encoder_is_supported(LZMA_FILTER_X86) + || !lzma_filter_decoder_is_supported(LZMA_FILTER_X86)) + assert_skip("x86 BCJ encoder and/or decoder " + "is disabled"); + + lzma_block block = { + .version = 1, + .filters = filters_one, + .compressed_size = LZMA_VLI_UNKNOWN, + .uncompressed_size = LZMA_VLI_UNKNOWN, + .check = LZMA_CHECK_CRC32, + }; + + // Ensure all block options are valid before changes are tested + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + + uint8_t out[LZMA_BLOCK_HEADER_SIZE_MAX]; + + // Test invalid block version + for (uint32_t i = 2; i < 20; i++) { + block.version = i; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + } + + block.version = 1; + + // Test invalid header size (< min, > max, % 4 != 0) + block.header_size = LZMA_BLOCK_HEADER_SIZE_MIN - 4; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + block.header_size = LZMA_BLOCK_HEADER_SIZE_MIN + 2; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + block.header_size = LZMA_BLOCK_HEADER_SIZE_MAX + 4; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + + // Test invalid compressed_size + block.compressed_size = 0; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + block.compressed_size = LZMA_VLI_MAX + 1; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + + // This test passes test_lzma_block_header_size, but should + // fail here because there is not enough space to encode the + // proper block size because the total size is too big to fit + // in an lzma_vli + block.compressed_size = LZMA_VLI_MAX; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + block.compressed_size = LZMA_VLI_UNKNOWN; + + // Test invalid uncompressed size + block.uncompressed_size = LZMA_VLI_MAX + 1; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + block.uncompressed_size = LZMA_VLI_UNKNOWN; + + // Test invalid block check + block.check = INVALID_LZMA_CHECK_ID; + block.ignore_check = false; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + block.check = LZMA_CHECK_CRC32; + + // Test invalid filters + block.filters = NULL; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + + block.filters = filters_none; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + + block.filters = filters_five; + block.header_size = LZMA_BLOCK_HEADER_SIZE_MAX - 4; + assert_lzma_ret(lzma_block_header_encode(&block, out), + LZMA_PROG_ERROR); + + // Test valid encoding and verify bytes of block header. + // More complicated tests for encoding headers are included + // in test_lzma_block_header_decode. + block.filters = filters_one; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK); + + // First read block header size from out and verify + // that it == (encoded size + 1) * 4 + uint32_t header_size = (out[0] + 1U) * 4; + assert_uint_eq(header_size, block.header_size); + + // Next read block flags + uint8_t flags = out[1]; + + // Should have number of filters = 1 + assert_uint_eq((flags & 0x3) + 1U, 1); + + // Bits 2-7 must be empty not set + assert_uint_eq(flags & (0xFF - 0x3), 0); + + // Verify filter flags + // Decode Filter ID + lzma_vli filter_id = 0; + size_t pos = 2; + assert_lzma_ret(lzma_vli_decode(&filter_id, NULL, out, + &pos, header_size), LZMA_OK); + assert_uint_eq(filter_id, filters_one[0].id); + + // Decode Size of Properties + lzma_vli prop_size = 0; + assert_lzma_ret(lzma_vli_decode(&prop_size, NULL, out, + &pos, header_size), LZMA_OK); + + // LZMA2 has 1 byte prop size + assert_uint_eq(prop_size, 1); + uint8_t expected_filter_props = 0; + assert_lzma_ret(lzma_properties_encode(filters_one, + &expected_filter_props), LZMA_OK); + assert_uint_eq(out[pos], expected_filter_props); + pos++; + + // Check null-padding + for (size_t i = pos; i < header_size - 4; i++) + assert_uint_eq(out[i], 0); + + // Check CRC32 + assert_uint_eq(read32le(&out[header_size - 4]), lzma_crc32(out, + header_size - 4, 0)); +#endif +} + + +#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS) +// Helper function to compare two lzma_block structures field by field +static void +compare_blocks(lzma_block *block_expected, lzma_block *block_actual) +{ + assert_uint_eq(block_actual->version, block_expected->version); + assert_uint_eq(block_actual->compressed_size, + block_expected->compressed_size); + assert_uint_eq(block_actual->uncompressed_size, + block_expected->uncompressed_size); + assert_uint_eq(block_actual->check, block_expected->check); + assert_uint_eq(block_actual->header_size, block_expected->header_size); + + // Compare filter IDs + assert_true(block_expected->filters && block_actual->filters); + lzma_filter expected_filter = block_expected->filters[0]; + uint32_t filter_count = 0; + while (expected_filter.id != LZMA_VLI_UNKNOWN) { + assert_uint_eq(block_actual->filters[filter_count].id, + expected_filter.id); + expected_filter = block_expected->filters[++filter_count]; + } + + assert_uint_eq(block_actual->filters[filter_count].id, + LZMA_VLI_UNKNOWN); +} +#endif + + +static void +test_lzma_block_header_decode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + if (!lzma_filter_encoder_is_supported(LZMA_FILTER_X86) + || !lzma_filter_decoder_is_supported(LZMA_FILTER_X86)) + assert_skip("x86 BCJ encoder and/or decoder " + "is disabled"); + + lzma_block block = { + .filters = filters_one, + .compressed_size = LZMA_VLI_UNKNOWN, + .uncompressed_size = LZMA_VLI_UNKNOWN, + .check = LZMA_CHECK_CRC32, + .version = 0 + }; + + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + + // Encode block header with simple options + uint8_t out[LZMA_BLOCK_HEADER_SIZE_MAX]; + assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK); + + // Decode block header and check that the options match + lzma_filter decoded_filters[LZMA_FILTERS_MAX + 1]; + lzma_block decoded_block = { + .version = 0, + .filters = decoded_filters, + .check = LZMA_CHECK_CRC32 + }; + decoded_block.header_size = lzma_block_header_size_decode(out[0]); + + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_OK); + compare_blocks(&block, &decoded_block); + + // Reset output buffer and decoded_block + RESET_BLOCK(decoded_block, out); + + // Test with compressed size set + block.compressed_size = 4096; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK); + decoded_block.header_size = lzma_block_header_size_decode(out[0]); + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_OK); + compare_blocks(&block, &decoded_block); + + RESET_BLOCK(decoded_block, out); + + // Test with uncompressed size set + block.uncompressed_size = 4096; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK); + decoded_block.header_size = lzma_block_header_size_decode(out[0]); + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_OK); + compare_blocks(&block, &decoded_block); + + RESET_BLOCK(decoded_block, out); + + // Test with multiple filters + block.filters = filters_four; + assert_lzma_ret(lzma_block_header_size(&block), LZMA_OK); + assert_lzma_ret(lzma_block_header_encode(&block, out), LZMA_OK); + decoded_block.header_size = lzma_block_header_size_decode(out[0]); + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_OK); + compare_blocks(&block, &decoded_block); + + lzma_filters_free(decoded_filters, NULL); + + // Test with too high version. The decoder will set it to a version + // that it supports. + decoded_block.version = 2; + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_OK); + assert_uint_eq(decoded_block.version, 1); + + // Free the filters for the last time since all other cases should + // result in an error. + lzma_filters_free(decoded_filters, NULL); + + // Test bad check type + decoded_block.check = INVALID_LZMA_CHECK_ID; + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_PROG_ERROR); + decoded_block.check = LZMA_CHECK_CRC32; + + // Test bad check value + out[decoded_block.header_size - 1] -= 10; + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_DATA_ERROR); + out[decoded_block.header_size - 1] += 10; + + // Test non-NULL padding + out[decoded_block.header_size - 5] = 1; + + // Recompute CRC32 + write32le(&out[decoded_block.header_size - 4], lzma_crc32(out, + decoded_block.header_size - 4, 0)); + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_OPTIONS_ERROR); + + // Test unsupported flags + out[1] = 0xFF; + + // Recompute CRC32 + write32le(&out[decoded_block.header_size - 4], lzma_crc32(out, + decoded_block.header_size - 4, 0)); + assert_lzma_ret(lzma_block_header_decode(&decoded_block, NULL, out), + LZMA_OPTIONS_ERROR); +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + + if (lzma_lzma_preset(&opt_lzma, 1)) + tuktest_error("lzma_lzma_preset() failed"); + + tuktest_run(test_lzma_block_header_size); + tuktest_run(test_lzma_block_header_encode); + tuktest_run(test_lzma_block_header_decode); + + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_check.c b/cpp/third_party/xz-5.8.3/tests/test_check.c new file mode 100644 index 000000000..f45ccdeb0 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_check.c @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_check.c +/// \brief Tests integrity checks +// +// Authors: Lasse Collin +// Jia Tan +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" +#include "mythread.h" + + +// These must be specified as numbers so that the test works on EBCDIC +// systems too. +// static const uint8_t test_string[9] = "123456789"; +// static const uint8_t test_unaligned[12] = "xxx123456789"; +static const uint8_t test_string[9] = { 49, 50, 51, 52, 53, 54, 55, 56, 57 }; +static const uint8_t test_unaligned[12] + = { 120, 120, 120, 49, 50, 51, 52, 53, 54, 55, 56, 57 }; + +// 2 MB is more than enough for the tests. Actually a tiny value would +// work because we don't actually decompress the files, we only test +// decoding of the Stream Header fields. +#define TEST_CHECK_MEMLIMIT (2U << 20) + +static size_t no_check_size; +static uint8_t *no_check_xz_data; + +static size_t unsupported_check_size; +static uint8_t *unsupported_check_xz_data; + +#ifdef HAVE_CHECK_CRC32 +static size_t crc32_size; +static uint8_t *crc32_xz_data; +#endif + +#ifdef HAVE_CHECK_CRC64 +static size_t crc64_size; +static uint8_t *crc64_xz_data; +#endif + +#ifdef HAVE_CHECK_SHA256 +static size_t sha256_size; +static uint8_t *sha256_xz_data; +#endif + + +#if defined(HAVE_CHECK_CRC32) || defined(HAVE_CHECK_CRC64) +static const uint8_t * +get_random256(uint32_t *seed) +{ + static uint8_t buf[256]; + + for (size_t i = 0; i < sizeof(buf); ++i) { + *seed = *seed * 1103515245 + 12345; + buf[i] = (uint8_t)(*seed >> 22); + } + + return buf; +} +#endif + + +static void +test_lzma_crc32(void) +{ + // CRC32 is always enabled. + assert_true(lzma_check_is_supported(LZMA_CHECK_CRC32)); + + const uint32_t test_vector = 0xCBF43926; + + // Test 1 + assert_uint_eq(lzma_crc32(test_string, sizeof(test_string), 0), + test_vector); + + // Test 2 + assert_uint_eq(lzma_crc32(test_unaligned + 3, sizeof(test_string), 0), + test_vector); + + // Test 3 + uint32_t crc = 0; + for (size_t i = 0; i < sizeof(test_string); ++i) + crc = lzma_crc32(test_string + i, 1, crc); + assert_uint_eq(crc, test_vector); + + // Test 4: Test combination of different start and end alignments + // and different buffer lengths. + uint32_t seed = 23; + crc = 0x760CD032; // Random initial value + for (size_t start = 0; start < 32; ++start) + for (size_t size = 1; size < 256 - 32; ++size) + crc = lzma_crc32(get_random256(&seed), size, crc); + + assert_uint_eq(crc, 0x924E35FD); +} + + +static void +test_lzma_crc64(void) +{ + // CRC64 can be disabled. + if (!lzma_check_is_supported(LZMA_CHECK_CRC64)) + assert_skip("CRC64 support is disabled"); + + // If CRC64 is disabled then lzma_crc64() will be missing. + // Using an ifdef here avoids a linker error. +#ifdef HAVE_CHECK_CRC64 + const uint64_t test_vector = 0x995DC9BBDF1939FA; + + // Test 1 + assert_uint_eq(lzma_crc64(test_string, sizeof(test_string), 0), + test_vector); + + // Test 2 + assert_uint_eq(lzma_crc64(test_unaligned + 3, sizeof(test_string), 0), + test_vector); + + // Test 3 + uint64_t crc = 0; + for (size_t i = 0; i < sizeof(test_string); ++i) + crc = lzma_crc64(test_string + i, 1, crc); + assert_uint_eq(crc, test_vector); + + // Test 4: Test combination of different start and end alignments + // and different buffer lengths. + uint32_t seed = 29; + crc = 0x96E30D5184B7FA2C; // Random initial value + for (size_t start = 0; start < 32; ++start) + for (size_t size = 1; size < 256 - 32; ++size) + crc = lzma_crc64(get_random256(&seed), size, crc); + + assert_uint_eq(crc, 0x23AB787177231C9F); +#endif +} + + +static void +test_lzma_supported_checks(void) +{ + static const lzma_check expected_check_ids[] = { + LZMA_CHECK_NONE, +#ifdef HAVE_CHECK_CRC32 + LZMA_CHECK_CRC32, +#endif +#ifdef HAVE_CHECK_CRC64 + LZMA_CHECK_CRC64, +#endif +#ifdef HAVE_CHECK_SHA256 + LZMA_CHECK_SHA256, +#endif + }; + + for (lzma_check i = 0; i <= LZMA_CHECK_ID_MAX + 1; i++) { + bool matched = false; + for (unsigned int j = 0; j < ARRAY_SIZE(expected_check_ids); + j++) { + if (expected_check_ids[j] == i) { + matched = true; + break; + } + } + + if (matched) + assert_true(lzma_check_is_supported(i)); + else + assert_false(lzma_check_is_supported(i)); + } +} + + +static void +test_lzma_check_size(void) +{ + // Expected check sizes taken from src/liblzma/api/lzma/check.h + static const uint32_t expected_check_sizes[] = { + 0, 4, 4, 4, 8, 8, 8, 16, 16, 16, + 32, 32, 32, 64, 64, 64 + }; + + for (lzma_check i = 0; i < ARRAY_SIZE(expected_check_sizes); i++) + assert_uint_eq(expected_check_sizes[i], lzma_check_size(i)); + + assert_uint_eq(lzma_check_size(INVALID_LZMA_CHECK_ID), UINT32_MAX); +} + + +// Test the single threaded decoder for lzma_get_check +static void +test_lzma_get_check_st(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + const uint32_t flags = LZMA_TELL_ANY_CHECK | + LZMA_TELL_UNSUPPORTED_CHECK | + LZMA_TELL_NO_CHECK; + + uint8_t outbuf[128]; + lzma_stream strm = LZMA_STREAM_INIT; + + // Test a file with no integrity check: + assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT, + flags), LZMA_OK); + strm.next_in = no_check_xz_data; + strm.avail_in = no_check_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_NO_CHECK); + assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_NONE); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); + + // Test a file with an unsupported integrity check type: + assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT, + flags), LZMA_OK); + strm.next_in = unsupported_check_xz_data; + strm.avail_in = unsupported_check_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_UNSUPPORTED_CHECK); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); + + // Test a file with CRC32 as the integrity check: +#ifdef HAVE_CHECK_CRC32 + assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT, + flags), LZMA_OK); + strm.next_in = crc32_xz_data; + strm.avail_in = crc32_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK); + assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_CRC32); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); +#endif + + // Test a file with CRC64 as the integrity check: +#ifdef HAVE_CHECK_CRC64 + assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT, + flags), LZMA_OK); + strm.next_in = crc64_xz_data; + strm.avail_in = crc64_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK); + assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_CRC64); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); +#endif + + // Test a file with SHA-256 as the integrity check: +#ifdef HAVE_CHECK_SHA256 + assert_lzma_ret(lzma_stream_decoder(&strm, TEST_CHECK_MEMLIMIT, + flags), LZMA_OK); + strm.next_in = sha256_xz_data; + strm.avail_in = sha256_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK); + assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_SHA256); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); +#endif + + lzma_end(&strm); +#endif +} + + +static void +test_lzma_get_check_mt(void) +{ +#ifndef MYTHREAD_ENABLED + assert_skip("Threading support disabled"); +#elif !defined(HAVE_DECODERS) + assert_skip("Decoder support disabled"); +#else + const uint32_t flags = LZMA_TELL_ANY_CHECK | + LZMA_TELL_UNSUPPORTED_CHECK | + LZMA_TELL_NO_CHECK; + + const lzma_mt options = { + .flags = flags, + .threads = 2, + .timeout = 0, + .memlimit_threading = TEST_CHECK_MEMLIMIT, + .memlimit_stop = TEST_CHECK_MEMLIMIT + }; + + uint8_t outbuf[128]; + lzma_stream strm = LZMA_STREAM_INIT; + + // Test a file with no integrity check: + assert_lzma_ret(lzma_stream_decoder_mt(&strm, &options), LZMA_OK); + strm.next_in = no_check_xz_data; + strm.avail_in = no_check_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_NO_CHECK); + assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_NONE); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); + + // Test a file with an unsupported integrity check type: + assert_lzma_ret(lzma_stream_decoder_mt(&strm, &options), LZMA_OK); + strm.next_in = unsupported_check_xz_data; + strm.avail_in = unsupported_check_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_UNSUPPORTED_CHECK); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); + + // Test a file with CRC32 as the integrity check: +#ifdef HAVE_CHECK_CRC32 + assert_lzma_ret(lzma_stream_decoder_mt(&strm, &options), LZMA_OK); + strm.next_in = crc32_xz_data; + strm.avail_in = crc32_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK); + assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_CRC32); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); +#endif + + // Test a file with CRC64 as the integrity check: +#ifdef HAVE_CHECK_CRC64 + assert_lzma_ret(lzma_stream_decoder_mt(&strm, &options), LZMA_OK); + strm.next_in = crc64_xz_data; + strm.avail_in = crc64_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK); + assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_CRC64); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); +#endif + + // Test a file with SHA-256 as the integrity check: +#ifdef HAVE_CHECK_SHA256 + assert_lzma_ret(lzma_stream_decoder_mt(&strm,&options), LZMA_OK); + strm.next_in = sha256_xz_data; + strm.avail_in = sha256_size; + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_GET_CHECK); + assert_lzma_check(lzma_get_check(&strm), LZMA_CHECK_SHA256); + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); +#endif + + lzma_end(&strm); +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + + no_check_xz_data = tuktest_file_from_srcdir( + "files/good-1-check-none.xz", &no_check_size); + + unsupported_check_xz_data = tuktest_file_from_srcdir( + "files/unsupported-check.xz", + &unsupported_check_size); + +#ifdef HAVE_CHECK_CRC32 + crc32_xz_data = tuktest_file_from_srcdir( + "files/good-1-check-crc32.xz", &crc32_size); +#endif + +#ifdef HAVE_CHECK_CRC64 + crc64_xz_data = tuktest_file_from_srcdir( + "files/good-1-check-crc64.xz", &crc64_size); +#endif + +#ifdef HAVE_CHECK_SHA256 + sha256_xz_data = tuktest_file_from_srcdir( + "files/good-1-check-sha256.xz", &sha256_size); +#endif + + tuktest_run(test_lzma_crc32); + tuktest_run(test_lzma_crc64); + tuktest_run(test_lzma_supported_checks); + tuktest_run(test_lzma_check_size); + tuktest_run(test_lzma_get_check_st); + tuktest_run(test_lzma_get_check_mt); + + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_compress.sh b/cpp/third_party/xz-5.8.3/tests/test_compress.sh new file mode 100755 index 000000000..36a9ef945 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_compress.sh @@ -0,0 +1,166 @@ +#!/bin/sh +# SPDX-License-Identifier: 0BSD + +############################################################################### +# +# Author: Lasse Collin +# +############################################################################### + +# Mandatory argument: +# $1 = test filename: compress_generated_ or compress_prepared_ +# +# Optional argument: +# $2 = directory of the xz and xzdec executables + +XZ=${2:-../src/xz}/xz +XZDEC=${2:-../src/xzdec}/xzdec + +# If xz wasn't built, this test is skipped. +if test ! -x "$XZ"; then + echo "xz was not built, skipping this test." + exit 77 +fi + +# xzdec isn't mandatory for this script. +test -x "$XZDEC" || XZDEC= + +# If compression or decompression support is missing, this test is skipped. +# This isn't perfect as if only some compressors or decompressors are disabled +# then this script can still fail because for now this doesn't check the +# availability of each filter. +if test ! -f ../config.h ; then + : +elif grep 'define HAVE_ENCODERS' ../config.h > /dev/null \ + && grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then + : +else + echo "Compression or decompression support is disabled, skipping this test." + exit 77 +fi + +# Find out if our shell supports functions. +eval 'unset foo ; foo() { return 42; } ; foo' +if test $? != 42 ; then + echo "/bin/sh doesn't support functions, skipping this test." + exit 77 +fi + +test_xz() { + if $XZ -c "$@" "$FILE" > "$TMP_COMP"; then + : + else + echo "Compressing failed: $* $FILE" + exit 1 + fi + + if $XZ -cd "$TMP_COMP" > "$TMP_UNCOMP" ; then + : + else + echo "Decompressing failed: $* $FILE" + exit 1 + fi + + if cmp "$TMP_UNCOMP" "$FILE" ; then + : + else + echo "Decompressed file does not match" \ + "the original: $* $FILE" + exit 1 + fi + + if test -n "$XZDEC" ; then + if $XZDEC "$TMP_COMP" > "$TMP_UNCOMP" ; then + : + else + echo "Decompressing failed: $* $FILE" + exit 1 + fi + + if cmp "$TMP_UNCOMP" "$FILE" ; then + : + else + echo "Decompressed file does not match" \ + "the original: $* $FILE" + exit 1 + fi + fi +} + +# Set memory usage limit for xz. xzdec has no memory usage limiter. +# Force single-threaded mode as the test files are small +# (so more than one thread wouldn't be used anyway) and +# the tests are usually run in parallel. +XZ="$XZ --memlimit-compress=48MiB --memlimit-decompress=5MiB \ + --no-adjust --threads=1" + +# Create the required input file if needed. +# +# Derive temporary filenames for compressed and uncompressed outputs +# from the input filename. This is needed when multiple tests are +# run in parallel. +FILE=$1 +TMP_COMP="tmp_comp_$FILE" +TMP_UNCOMP="tmp_uncomp_$FILE" + +case $FILE in + # compress_generated files will be created in the build directory + # in the /tests/ sub-directory. + compress_generated_*) + if ./create_compress_files "$FILE" ; then + : + else + rm -f "$FILE" + echo "Failed to create the file '$FILE'." + exit 1 + fi + ;; + # compress_prepared files exist in the source directory since they + # do not need to be copied or regenerated. + compress_prepared_*) + FILE="$srcdir/$FILE" + ;; + '') + echo "No test file was specified." + exit 1 + ;; +esac + +# Remove temporary now (in case they are something weird), and on exit. +rm -f "$TMP_COMP" "$TMP_UNCOMP" +trap 'rm -f "$TMP_COMP" "$TMP_UNCOMP"' 0 + +# Compress and decompress the file with various filter configurations. +# +# Don't test with empty arguments; it breaks some ancient +# proprietary /bin/sh versions due to $@ used in test_xz(). +test_xz -1 +test_xz -2 +test_xz -3 +test_xz -4 + +test_filter() +{ + if test -f ../config.h ; then + grep "define HAVE_ENCODER_$1[ 1]*\$" ../config.h > /dev/null \ + || return + grep "define HAVE_DECODER_$1[ 1]*\$" ../config.h > /dev/null \ + || return + fi + shift + test_xz --filters="$* lzma2:dict=64KiB,nice=32,mode=fast" +} + +test_filter DELTA delta:dist=1 +test_filter DELTA delta:dist=4 +test_filter DELTA delta:dist=256 +test_filter X86 x86 +test_filter POWERPC powerpc +test_filter IA64 ia64 +test_filter ARM arm +test_filter ARMTHUMB armthumb +test_filter ARM64 arm64 +test_filter SPARC sparc +test_filter RISCV riscv + +exit 0 diff --git a/cpp/third_party/xz-5.8.3/tests/test_compress_generated_abc b/cpp/third_party/xz-5.8.3/tests/test_compress_generated_abc new file mode 100755 index 000000000..b31d631c7 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_compress_generated_abc @@ -0,0 +1,4 @@ +#!/bin/sh +# SPDX-License-Identifier: 0BSD + +exec "$srcdir/test_compress.sh" compress_generated_abc diff --git a/cpp/third_party/xz-5.8.3/tests/test_compress_generated_random b/cpp/third_party/xz-5.8.3/tests/test_compress_generated_random new file mode 100755 index 000000000..c20f3dac6 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_compress_generated_random @@ -0,0 +1,4 @@ +#!/bin/sh +# SPDX-License-Identifier: 0BSD + +exec "$srcdir/test_compress.sh" compress_generated_random diff --git a/cpp/third_party/xz-5.8.3/tests/test_compress_generated_text b/cpp/third_party/xz-5.8.3/tests/test_compress_generated_text new file mode 100755 index 000000000..2c8c17103 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_compress_generated_text @@ -0,0 +1,4 @@ +#!/bin/sh +# SPDX-License-Identifier: 0BSD + +exec "$srcdir/test_compress.sh" compress_generated_text diff --git a/cpp/third_party/xz-5.8.3/tests/test_files.sh b/cpp/third_party/xz-5.8.3/tests/test_files.sh new file mode 100755 index 000000000..894130c18 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_files.sh @@ -0,0 +1,208 @@ +#!/bin/sh +# SPDX-License-Identifier: 0BSD + +############################################################################### +# +# Author: Lasse Collin +# +############################################################################### + +# Optional argument: +# $1 = directory of the xz executable + +# If both xz and xzdec were not built, skip this test. +XZ=${1:-../src/xz}/xz +XZDEC=${2:-../src/xzdec}/xzdec +test -x "$XZ" || XZ= +test -x "$XZDEC" || XZDEC= +if test -z "$XZ$XZDEC"; then + echo "xz and xzdec were not built, skipping this test." + exit 77 +fi + +# If decompression support is missing, this test is skipped. +# This isn't perfect as if only some decompressors are disabled +# then some good files might not decompress and the test fails +# for a (kind of) wrong reason. +if test ! -f ../config.h ; then + : +elif grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then + : +else + echo "Decompression support is disabled, skipping this test." + exit 77 +fi + +# If a feature was disabled at build time, make it possible to skip +# some of the test files. Use exit status 77 if any files were skipped. +EXIT_STATUS=0 +have_feature() +{ + test -f ../config.h || return 0 + grep "define HAVE_$1[ 1]*\$" ../config.h > /dev/null && return 0 + printf '%s: Skipping because HAVE_%s is not enabled\n' "$2" "$1" + EXIT_STATUS=77 + return 1 +} + + +####### +# .xz # +####### + +# If these integrity check types were disabled at build time, +# allow the tests to pass still. +NO_WARN= +if test -f ../config.h ; then + grep 'define HAVE_CHECK_CRC64' ../config.h > /dev/null || NO_WARN=-qQ + grep 'define HAVE_CHECK_SHA256' ../config.h > /dev/null || NO_WARN=-qQ +fi + +for I in "$srcdir"/files/good-*.xz +do + # If features were disabled at build time, keep this still working. + case $I in + */good-1-*delta-lzma2*.xz) + have_feature DECODER_DELTA "$I" || continue + ;; + esac + case $I in + */good-1-empty-bcj-lzma2.xz) + have_feature DECODER_POWERPC "$I" || continue + ;; + esac + case $I in + */good-1-sparc-lzma2.xz) + have_feature DECODER_SPARC "$I" || continue + ;; + esac + case $I in + */good-1-x86-lzma2.xz) + have_feature DECODER_X86 "$I" || continue + ;; + esac + case $I in + */good-1-arm64-lzma2-*.xz) + have_feature DECODER_ARM64 "$I" || continue + ;; + esac + case $I in + */good-1-riscv-lzma2-*.xz) + have_feature DECODER_RISCV "$I" || continue + ;; + esac + + if test -z "$XZ" || "$XZ" $NO_WARN -dc "$I" > /dev/null; then + : + else + echo "Good file failed: $I" + exit 1 + fi + + if test -z "$XZDEC" || "$XZDEC" $NO_WARN "$I" > /dev/null; then + : + else + echo "Good file failed: $I" + exit 1 + fi +done + +for I in "$srcdir"/files/bad-*.xz +do + if test -n "$XZ" && "$XZ" -dc "$I" > /dev/null 2>&1; then + echo "Bad file succeeded: $I" + exit 1 + fi + + # xzdec doesn't warn about unsupported check so skip this if any of + # the check types were disabled at built time (NO_WARN isn't empty). + if test -n "$XZDEC" && test -z "$NO_WARN" \ + && "$XZDEC" "$I" > /dev/null 2>&1; then + echo "Bad file succeeded: $I" + exit 1 + fi +done + +# Testing for the lzma_index_append() bug in <= 5.2.6 needs "xz -l": +I="$srcdir/files/bad-3-index-uncomp-overflow.xz" +if test -n "$XZ" && "$XZ" -l "$I" > /dev/null 2>&1; then + echo "Bad file succeeded with xz -l: $I" + exit 1 +fi + +for I in "$srcdir"/files/unsupported-*.xz +do + # Test these only with xz as unsupported-check.xz will exit + # successfully with xzdec because it doesn't warn about + # unsupported check type. + if test -n "$XZ" && "$XZ" -dc "$I" > /dev/null 2>&1; then + echo "Unsupported file succeeded: $I" + exit 1 + fi +done + +# Test that this passes with --no-warn (-Q). +I="$srcdir/files/unsupported-check.xz" +if test -z "$XZ" || "$XZ" -dcqQ "$I" > /dev/null; then + : +else + echo "Unsupported file failed with xz -Q: $I" + exit 1 +fi + +if test -z "$XZDEC" || "$XZDEC" -qQ "$I" > /dev/null; then + : +else + echo "Unsupported file failed with xzdec -Q: $I" + exit 1 +fi + + +######### +# .lzma # +######### + +for I in "$srcdir"/files/good-*.lzma +do + if test -z "$XZ" || "$XZ" -dc "$I" > /dev/null; then + : + else + echo "Good file failed: $I" + exit 1 + fi +done + +for I in "$srcdir"/files/bad-*.lzma +do + if test -n "$XZ" && "$XZ" -dc "$I" > /dev/null 2>&1; then + echo "Bad file succeeded: $I" + exit 1 + fi +done + + +####### +# .lz # +####### + +if have_feature LZIP_DECODER ".lz files" ; then + for I in "$srcdir"/files/good-*.lz + do + if test -z "$XZ" || "$XZ" -dc "$I" > /dev/null; then + : + else + echo "Good file failed: $I" + exit 1 + fi + done + + for I in "$srcdir"/files/bad-*.lz "$srcdir"/files/unsupported-*.lz + do + if test -n "$XZ" && "$XZ" -dc "$I" > /dev/null 2>&1; then + echo "Bad file succeeded: $I" + exit 1 + fi + done +fi + +exit "$EXIT_STATUS" diff --git a/cpp/third_party/xz-5.8.3/tests/test_filter_flags.c b/cpp/third_party/xz-5.8.3/tests/test_filter_flags.c new file mode 100644 index 000000000..9dfc16e69 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_filter_flags.c @@ -0,0 +1,535 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_filter_flags.c +/// \brief Tests Filter Flags coders +// +// Authors: Jia Tan +// Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + +// FIXME: This is from src/liblzma/common/common.h but it cannot be +// included here. This constant is needed in only a few files, perhaps +// move it to some other internal header or create a new one? +#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62) + + +#if defined(HAVE_ENCODERS) +// No tests are run without encoders, so init the global filters +// only when the encoders are enabled. +static lzma_filter lzma1_filter = { LZMA_FILTER_LZMA1, NULL }; +static lzma_filter lzma2_filter = { LZMA_FILTER_LZMA2, NULL }; +static lzma_filter delta_filter = { LZMA_FILTER_DELTA, NULL }; + +static lzma_filter bcj_filters_encoders[] = { +#ifdef HAVE_ENCODER_X86 + { LZMA_FILTER_X86, NULL }, +#endif +#ifdef HAVE_ENCODER_POWERPC + { LZMA_FILTER_POWERPC, NULL }, +#endif +#ifdef HAVE_ENCODER_IA64 + { LZMA_FILTER_IA64, NULL }, +#endif +#ifdef HAVE_ENCODER_ARM + { LZMA_FILTER_ARM, NULL }, +#endif +#ifdef HAVE_ENCODER_ARM64 + { LZMA_FILTER_ARM64, NULL }, +#endif +#ifdef HAVE_ENCODER_ARMTHUMB + { LZMA_FILTER_ARMTHUMB, NULL }, +#endif +#ifdef HAVE_ENCODER_SPARC + { LZMA_FILTER_SPARC, NULL }, +#endif +#ifdef HAVE_ENCODER_RISCV + { LZMA_FILTER_RISCV, NULL }, +#endif + { LZMA_VLI_UNKNOWN, NULL } +}; + +// HAVE_ENCODERS ifdef not terminated here because decoders are +// only used if encoders are, but encoders can still be used +// even if decoders are not. + +#ifdef HAVE_DECODERS +static lzma_filter bcj_filters_decoders[] = { +#ifdef HAVE_DECODER_X86 + { LZMA_FILTER_X86, NULL }, +#endif +#ifdef HAVE_DECODER_POWERPC + { LZMA_FILTER_POWERPC, NULL }, +#endif +#ifdef HAVE_DECODER_IA64 + { LZMA_FILTER_IA64, NULL }, +#endif +#ifdef HAVE_DECODER_ARM + { LZMA_FILTER_ARM, NULL }, +#endif +#ifdef HAVE_DECODER_ARM64 + { LZMA_FILTER_ARM64, NULL }, +#endif +#ifdef HAVE_DECODER_ARMTHUMB + { LZMA_FILTER_ARMTHUMB, NULL }, +#endif +#ifdef HAVE_DECODER_SPARC + { LZMA_FILTER_SPARC, NULL }, +#endif +#ifdef HAVE_DECODER_RISCV + { LZMA_FILTER_RISCV, NULL }, +#endif + { LZMA_VLI_UNKNOWN, NULL } +}; +#endif +#endif + + +static void +test_lzma_filter_flags_size(void) +{ +#ifndef HAVE_ENCODERS + assert_skip("Encoder support disabled"); +#else + // For each supported filter, test that the size can be calculated + // and that the size calculated is reasonable. A reasonable size + // must be greater than 0, but less than the maximum size for the + // block header. + uint32_t size = 0; + if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA1)) { + // LZMA1 isn't supported in .xz so we get LZMA_PROG_ERROR. + assert_lzma_ret(lzma_filter_flags_size(&size, + &lzma1_filter), LZMA_PROG_ERROR); + } + + if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) { + assert_lzma_ret(lzma_filter_flags_size(&size, + &lzma2_filter), LZMA_OK); + assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX); + } + + for (size_t i = 0; bcj_filters_encoders[i].id != LZMA_VLI_UNKNOWN; + ++i) { + assert_lzma_ret(lzma_filter_flags_size(&size, + &bcj_filters_encoders[i]), LZMA_OK); + assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX); + } + + if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) { + assert_lzma_ret(lzma_filter_flags_size(&size, + &delta_filter), LZMA_OK); + assert_true(size != 0 && size < LZMA_BLOCK_HEADER_SIZE_MAX); + } + + // Test invalid Filter IDs + lzma_filter bad_filter = { 2, NULL }; + + assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter), + LZMA_OPTIONS_ERROR); + bad_filter.id = LZMA_VLI_MAX; + assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter), + LZMA_PROG_ERROR); + bad_filter.id = LZMA_FILTER_RESERVED_START; + assert_lzma_ret(lzma_filter_flags_size(&size, &bad_filter), + LZMA_PROG_ERROR); +#endif +} + + +// Helper function for test_lzma_filter_flags_encode. +// The should_encode parameter represents if the encoding operation +// is expected to fail. +// Avoid data -> encode -> decode -> compare to data. +// Instead create expected encoding and compare to result from +// lzma_filter_flags_encode. +// Filter Flags in .xz are encoded as: +// |Filter ID (VLI)|Size of Properties (VLI)|Filter Properties| +#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS) +static void +verify_filter_flags_encode(lzma_filter *filter, bool should_encode) +{ + uint32_t size = 0; + + // First calculate the size of Filter Flags to know how much + // memory to allocate to hold the encoded Filter Flags + assert_lzma_ret(lzma_filter_flags_size(&size, filter), LZMA_OK); + uint8_t *encoded_out = tuktest_malloc(size); + size_t out_pos = 0; + if (!should_encode) { + assert_false(lzma_filter_flags_encode(filter, encoded_out, + &out_pos, size) == LZMA_OK); + return; + } + + // Next encode the Filter Flags for the provided filter + assert_lzma_ret(lzma_filter_flags_encode(filter, encoded_out, + &out_pos, size), LZMA_OK); + assert_uint_eq(size, out_pos); + + // Next decode the VLI for the Filter ID and verify it matches + // the expected Filter ID + size_t filter_id_vli_size = 0; + lzma_vli filter_id = 0; + assert_lzma_ret(lzma_vli_decode(&filter_id, NULL, encoded_out, + &filter_id_vli_size, size), LZMA_OK); + assert_uint_eq(filter->id, filter_id); + + // Next decode the Size of Properties and ensure it equals + // the expected size. + // Expected size should be: + // total filter flag length - size of filter id VLI + size of + // property size VLI + // Not verifying the contents of Filter Properties since + // that belongs in a different test + size_t size_of_properties_vli_size = 0; + lzma_vli size_of_properties = 0; + assert_lzma_ret(lzma_vli_decode(&size_of_properties, NULL, + encoded_out + filter_id_vli_size, + &size_of_properties_vli_size, size), LZMA_OK); + assert_uint_eq(size - (size_of_properties_vli_size + + filter_id_vli_size), size_of_properties); +} +#endif + + +static void +test_lzma_filter_flags_encode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + // No test for LZMA1 since the .xz format does not support LZMA1 + // and so the flags cannot be encoded for that filter + if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) { + // Test with NULL options that should fail + lzma_options_lzma *options = lzma2_filter.options; + lzma2_filter.options = NULL; + verify_filter_flags_encode(&lzma2_filter, false); + + // Place options back in the filter, and test should pass + lzma2_filter.options = options; + verify_filter_flags_encode(&lzma2_filter, true); + } + + // NOTE: Many BCJ filters require that start_offset is a multiple + // of some power of two. The Filter Flags encoder and decoder don't + // completely validate the options and thus 257 passes the tests + // with all BCJ filters. It would be caught when initializing + // a filter chain encoder or decoder. + lzma_options_bcj bcj_options = { + .start_offset = 257 + }; + + for (size_t i = 0; bcj_filters_encoders[i].id != LZMA_VLI_UNKNOWN; + ++i) { + // NULL options should pass for bcj filters + verify_filter_flags_encode(&bcj_filters_encoders[i], true); + lzma_filter bcj_with_options = { + bcj_filters_encoders[i].id, &bcj_options }; + verify_filter_flags_encode(&bcj_with_options, true); + } + + if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) { + lzma_options_delta delta_opts_below_min = { + .type = LZMA_DELTA_TYPE_BYTE, + .dist = LZMA_DELTA_DIST_MIN - 1 + }; + + lzma_options_delta delta_opts_above_max = { + .type = LZMA_DELTA_TYPE_BYTE, + .dist = LZMA_DELTA_DIST_MAX + 1 + }; + + verify_filter_flags_encode(&delta_filter, true); + + lzma_filter delta_filter_bad_options = { + LZMA_FILTER_DELTA, &delta_opts_below_min }; + + // Next test error case using minimum - 1 delta distance + verify_filter_flags_encode(&delta_filter_bad_options, false); + + // Next test error case using maximum + 1 delta distance + delta_filter_bad_options.options = &delta_opts_above_max; + verify_filter_flags_encode(&delta_filter_bad_options, false); + + // Next test NULL case + delta_filter_bad_options.options = NULL; + verify_filter_flags_encode(&delta_filter_bad_options, false); + } + + // Test expected failing cases + lzma_filter bad_filter = { LZMA_FILTER_RESERVED_START, NULL }; + size_t out_pos = 0; + size_t out_size = LZMA_BLOCK_HEADER_SIZE_MAX; + uint8_t out[LZMA_BLOCK_HEADER_SIZE_MAX]; + + // Filter ID outside of valid range + assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos, + out_size), LZMA_PROG_ERROR); + out_pos = 0; + bad_filter.id = LZMA_VLI_MAX + 1; + assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos, + out_size), LZMA_PROG_ERROR); + out_pos = 0; + + // Invalid Filter ID + bad_filter.id = 2; + assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, &out_pos, + out_size), LZMA_OPTIONS_ERROR); + out_pos = 0; + + // Out size too small + if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) { + uint32_t bad_size = 0; + + // First test with 0 output size + assert_lzma_ret(lzma_filter_flags_encode( + &lzma2_filter, out, &out_pos, 0), + LZMA_PROG_ERROR); + + // Next calculate the size needed to encode and + // use less than that + assert_lzma_ret(lzma_filter_flags_size(&bad_size, + &lzma2_filter), LZMA_OK); + + assert_lzma_ret(lzma_filter_flags_encode( + &lzma2_filter, out, &out_pos, + bad_size - 1), LZMA_PROG_ERROR); + out_pos = 0; + } + + // Invalid options + if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) { + bad_filter.id = LZMA_FILTER_DELTA; + + // First test with NULL options + assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, + &out_pos, out_size), LZMA_PROG_ERROR); + out_pos = 0; + + // Next test with invalid options + lzma_options_delta bad_options = { + .dist = LZMA_DELTA_DIST_MAX + 1, + .type = LZMA_DELTA_TYPE_BYTE + }; + bad_filter.options = &bad_options; + + assert_lzma_ret(lzma_filter_flags_encode(&bad_filter, out, + &out_pos, out_size), LZMA_PROG_ERROR); + } +#endif +} + + +// Helper function for test_lzma_filter_flags_decode. +// Encodes the filter_in without using lzma_filter_flags_encode. +// Leaves the specific assertions of filter_out options to the caller +// because it is agnostic to the type of options used in the call +#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS) +static void +verify_filter_flags_decode(const lzma_filter *filter_in, + lzma_filter *filter_out) +{ + uint32_t total_size = 0; + + assert_lzma_ret(lzma_filter_flags_size(&total_size, filter_in), + LZMA_OK); + assert_uint(total_size, >, 0); + uint8_t *filter_flag_buffer = tuktest_malloc(total_size); + + uint32_t properties_size = 0; + size_t out_pos = 0; + size_t in_pos = 0; + assert_lzma_ret(lzma_properties_size(&properties_size, filter_in), + LZMA_OK); + assert_lzma_ret(lzma_vli_encode(filter_in->id, NULL, + filter_flag_buffer, &out_pos, total_size), LZMA_OK); + assert_lzma_ret(lzma_vli_encode(properties_size, NULL, + filter_flag_buffer, &out_pos, total_size), + LZMA_OK); + assert_lzma_ret(lzma_properties_encode(filter_in, + filter_flag_buffer + out_pos), LZMA_OK); + assert_lzma_ret(lzma_filter_flags_decode(filter_out, NULL, + filter_flag_buffer, &in_pos, total_size), + LZMA_OK); + assert_uint_eq(filter_in->id, filter_out->id); +} +#endif + + +static void +test_lzma_filter_flags_decode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + // For each filter, only run the decoder test if both the encoder + // and decoder are enabled. This is because verify_filter_flags_decode + // uses lzma_filter_flags_size which requires the encoder. + if (lzma_filter_decoder_is_supported(LZMA_FILTER_LZMA2) && + lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) { + lzma_filter lzma2_decoded = { LZMA_FILTER_LZMA2, NULL }; + + verify_filter_flags_decode(&lzma2_filter, &lzma2_decoded); + + lzma_options_lzma *expected = lzma2_filter.options; + lzma_options_lzma *decoded = lzma2_decoded.options; + + // Only the dictionary size is encoded and decoded + // so only compare those + assert_uint_eq(decoded->dict_size, expected->dict_size); + + // The decoded options must be freed by the caller + free(decoded); + } + + for (size_t i = 0; bcj_filters_decoders[i].id != LZMA_VLI_UNKNOWN; + ++i) { + if (lzma_filter_encoder_is_supported( + bcj_filters_decoders[i].id)) { + lzma_filter bcj_decoded = { + bcj_filters_decoders[i].id, NULL }; + + lzma_filter bcj_encoded = { + bcj_filters_decoders[i].id, NULL }; + + // First test without options + verify_filter_flags_decode(&bcj_encoded, + &bcj_decoded); + assert_true(bcj_decoded.options == NULL); + + // Next test with start_offset. + // + // NOTE: The encoder and decoder don't verify if + // the start_offset is valid for the filter. Only + // the encoder or decoder initialization does. + lzma_options_bcj options = { + .start_offset = 257 + }; + + bcj_encoded.options = &options; + verify_filter_flags_decode(&bcj_encoded, + &bcj_decoded); + lzma_options_bcj *decoded_opts = bcj_decoded.options; + assert_uint_eq(decoded_opts->start_offset, + options.start_offset); + free(decoded_opts); + } + } + + if (lzma_filter_decoder_is_supported(LZMA_FILTER_DELTA) && + lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) { + lzma_filter delta_decoded = { LZMA_FILTER_DELTA, NULL }; + + verify_filter_flags_decode(&delta_filter, &delta_decoded); + lzma_options_delta *expected = delta_filter.options; + lzma_options_delta *decoded = delta_decoded.options; + assert_uint_eq(expected->dist, decoded->dist); + assert_uint_eq(expected->type, decoded->type); + + free(decoded); + } + + // Test expected failing cases + uint8_t bad_encoded_filter[LZMA_BLOCK_HEADER_SIZE_MAX]; + lzma_filter bad_filter; + + // Filter ID outside of valid range + lzma_vli bad_filter_id = LZMA_FILTER_RESERVED_START; + size_t bad_encoded_out_pos = 0; + size_t in_pos = 0; + + assert_lzma_ret(lzma_vli_encode(bad_filter_id, NULL, + bad_encoded_filter, &bad_encoded_out_pos, + LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK); + + assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL, + bad_encoded_filter, &in_pos, + LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_DATA_ERROR); + + bad_encoded_out_pos = 0; + in_pos = 0; + + // Invalid Filter ID + bad_filter_id = 2; + bad_encoded_out_pos = 0; + in_pos = 0; + + assert_lzma_ret(lzma_vli_encode(bad_filter_id, NULL, + bad_encoded_filter, &bad_encoded_out_pos, + LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK); + + // Next encode Size of Properties with the value of 0 + assert_lzma_ret(lzma_vli_encode(0, NULL, + bad_encoded_filter, &bad_encoded_out_pos, + LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK); + + // Decode should fail on bad Filter ID + assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL, + bad_encoded_filter, &in_pos, + LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OPTIONS_ERROR); + bad_encoded_out_pos = 0; + in_pos = 0; + + // Outsize too small + // Encode the LZMA2 filter normally, but then set + // the out size when decoding as too small + if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2) && + lzma_filter_decoder_is_supported(LZMA_FILTER_LZMA2)) { + uint32_t filter_flag_size = 0; + assert_lzma_ret(lzma_filter_flags_size(&filter_flag_size, + &lzma2_filter), LZMA_OK); + + assert_lzma_ret(lzma_filter_flags_encode(&lzma2_filter, + bad_encoded_filter, &bad_encoded_out_pos, + LZMA_BLOCK_HEADER_SIZE_MAX), LZMA_OK); + + assert_lzma_ret(lzma_filter_flags_decode(&bad_filter, NULL, + bad_encoded_filter, &in_pos, + filter_flag_size - 1), LZMA_DATA_ERROR); + } +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + +#ifdef HAVE_ENCODERS + // Only init filter options if encoder is supported because decoder + // tests requires encoder support, so the decoder tests will only + // run if for a given filter both the encoder and decoder are enabled. + if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA1)) { + lzma_options_lzma *options = tuktest_malloc( + sizeof(lzma_options_lzma)); + lzma_lzma_preset(options, LZMA_PRESET_DEFAULT); + lzma1_filter.options = options; + } + + if (lzma_filter_encoder_is_supported(LZMA_FILTER_LZMA2)) { + lzma_options_lzma *options = tuktest_malloc( + sizeof(lzma_options_lzma)); + lzma_lzma_preset(options, LZMA_PRESET_DEFAULT); + lzma2_filter.options = options; + } + + if (lzma_filter_encoder_is_supported(LZMA_FILTER_DELTA)) { + lzma_options_delta *options = tuktest_malloc( + sizeof(lzma_options_delta)); + options->dist = LZMA_DELTA_DIST_MIN; + options->type = LZMA_DELTA_TYPE_BYTE; + delta_filter.options = options; + } +#endif + + tuktest_run(test_lzma_filter_flags_size); + tuktest_run(test_lzma_filter_flags_encode); + tuktest_run(test_lzma_filter_flags_decode); + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_filter_str.c b/cpp/third_party/xz-5.8.3/tests/test_filter_str.c new file mode 100644 index 000000000..0deb58999 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_filter_str.c @@ -0,0 +1,685 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_filter_str.c +/// \brief Tests Filter string functions +// +// Author: Jia Tan +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + + +static void +test_lzma_str_to_filters(void) +{ + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + int error_pos; + + // Test with NULL string. + error_pos = -1; + assert_true(lzma_str_to_filters(NULL, &error_pos, filters, 0, + NULL) != NULL); + assert_int_eq(error_pos, 0); + + // Test with NULL filter array. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2", &error_pos, NULL, 0, + NULL) != NULL); + assert_int_eq(error_pos, 0); + + // Test with unsupported flags. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2", &error_pos, filters, + UINT32_MAX, NULL) != NULL); + assert_int_eq(error_pos, 0); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2", &error_pos, filters, + LZMA_STR_NO_SPACES << 1, NULL) != NULL); + assert_int_eq(error_pos, 0); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2", &error_pos, filters, + LZMA_STR_NO_SPACES, NULL) != NULL); + assert_int_eq(error_pos, 0); + + // Test with empty string. + error_pos = -1; + assert_true(lzma_str_to_filters("", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 0); + + // Test with invalid filter name and missing filter name. + error_pos = -1; + assert_true(lzma_str_to_filters("abcd", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 0); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2 abcd", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 6); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2--abcd", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 7); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2--", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 7); + + // Test LZMA_STR_ALL_FILTERS flag (should work with LZMA1 if built). +#if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1) + // Using LZMA1 as a Filter should fail without LZMA_STR_ALL_FILTERS. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma1", &error_pos, filters, + 0, NULL) != NULL); + assert_int_eq(error_pos, 0); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma1", &error_pos, filters, + LZMA_STR_ALL_FILTERS, NULL) == NULL); + assert_int_eq(error_pos, 5); + + // Verify Filters array IDs are correct. The array should contain + // only two elements: + // 1. LZMA1 Filter + // 2. LZMA_VLI_UNKNOWN filter array terminator + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA1); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); +#endif + + // Test LZMA_STR_NO_VALIDATION flag. This should allow having the + // same Filter multiple times in the chain and having a non-last + // Filter like lzma2 appear before another Filter. + // Without the flag, "lzma2 lzma2" must fail. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2 lzma2", &error_pos, filters, + 0, NULL) != NULL); + assert_int_eq(error_pos, 11); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2 lzma2", &error_pos, filters, + LZMA_STR_NO_VALIDATION, NULL) == NULL); + assert_int_eq(error_pos, 11); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[2].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); + + // Should fail with invalid Filter options (lc + lp must be <= 4). + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:lc=3,lp=3", &error_pos, filters, + LZMA_STR_NO_VALIDATION, NULL) != NULL); + assert_int_eq(error_pos, 15); + + // Test invalid option name. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:foo=1,bar=2", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 6); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:pb=1,bar=2", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 11); + + // Test missing option value. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:lc=", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 9); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:=,pb=1", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 6); + + // Test unsupported preset value. + error_pos = -1; + assert_true(lzma_str_to_filters("-10", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 2); + + error_pos = -1; + assert_true(lzma_str_to_filters("-5f", &error_pos, + filters, 0, NULL) != NULL); + assert_int_eq(error_pos, 2); + + // Test filter chain too long. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2 lzma2 lzma2 lzma2 lzma2", + &error_pos, filters, LZMA_STR_NO_VALIDATION, + NULL) != NULL); + assert_int_eq(error_pos, 24); // The fifth is too many. + +#if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1) + // Should fail with a Filter not supported in the .xz format (lzma1). + error_pos = -1; + assert_true(lzma_str_to_filters("lzma1", &error_pos, filters, + LZMA_STR_NO_VALIDATION, NULL) != NULL); + assert_int_eq(error_pos, 0); +#endif + + // Test setting options with the "=" format. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2=dict=4096,lc=2,lp=2,pb=1," + "mode=fast,nice=3,mf=hc3,depth=10", &error_pos, + filters, 0, NULL) == NULL); + assert_int_eq(error_pos, 63); + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_options_lzma *opts = filters[0].options; + assert_uint_eq(opts->dict_size, 4096); + assert_uint_eq(opts->lc, 2); + assert_uint_eq(opts->lp, 2); + assert_uint_eq(opts->pb, 1); + assert_uint_eq(opts->mode, LZMA_MODE_FAST); + assert_uint_eq(opts->nice_len, 3); + assert_uint_eq(opts->mf, LZMA_MF_HC3); + assert_uint_eq(opts->depth, 10); + + lzma_filters_free(filters, NULL); + +#if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86) + // Test BCJ Filter options. + error_pos = -1; + assert_true(lzma_str_to_filters("x86:start=16", &error_pos, filters, + LZMA_STR_NO_VALIDATION, NULL) == NULL); + assert_int_eq(error_pos, 12); + + assert_uint_eq(filters[0].id, LZMA_FILTER_X86); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_options_bcj *bcj_opts = filters[0].options; + assert_uint_eq(bcj_opts->start_offset, 16); + + lzma_filters_free(filters, NULL); +#endif + +#if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA) + // Test Delta Filter options. + error_pos = -1; + assert_true(lzma_str_to_filters("delta:dist=20", &error_pos, filters, + LZMA_STR_NO_VALIDATION, NULL) == NULL); + assert_int_eq(error_pos, 13); + + assert_uint_eq(filters[0].id, LZMA_FILTER_DELTA); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_options_delta *delta_opts = filters[0].options; + assert_uint_eq(delta_opts->dist, 20); + + lzma_filters_free(filters, NULL); +#endif + + // Test skipping leading spaces. + error_pos = -1; + assert_true(lzma_str_to_filters(" lzma2", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 9); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); + + // Test skipping trailing spaces. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2 ", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 9); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); + + // Test with "--" instead of space separating. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2--lzma2", &error_pos, filters, + LZMA_STR_NO_VALIDATION, NULL) == NULL); + assert_int_eq(error_pos, 12); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[2].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); + + // Test preset with and without leading "-", and with "e". + error_pos = -1; + assert_true(lzma_str_to_filters("-3", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 2); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); + + error_pos = -1; + assert_true(lzma_str_to_filters("4", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 1); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); + + error_pos = -1; + assert_true(lzma_str_to_filters("9e", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 2); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); + + // Test using a preset as an lzma2 option. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:preset=9e", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 15); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + lzma_filters_free(filters, NULL); + + // Test setting dictionary size with invalid modifier suffix. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:dict=4096ZiB", &error_pos, filters, + 0, NULL) != NULL); + assert_int_eq(error_pos, 15); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:dict=4096KiBs", &error_pos, filters, + 0, NULL) != NULL); + assert_int_eq(error_pos, 15); + + // Test option that cannot have multiplier modifier. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:pb=1k", &error_pos, filters, + 0, NULL) != NULL); + assert_int_eq(error_pos, 10); + + // Test option value too large. + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:dict=4096GiB", &error_pos, filters, + 0, NULL) != NULL); + assert_int_eq(error_pos, 11); + + // Test valid uses of multiplier modifiers (k,m,g). + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:dict=4096KiB", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 18); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + opts = filters[0].options; + assert_uint_eq(opts->dict_size, 4096 << 10); + + lzma_filters_free(filters, NULL); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:dict=40Mi", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 15); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + opts = filters[0].options; + assert_uint_eq(opts->dict_size, 40 << 20); + + lzma_filters_free(filters, NULL); + + error_pos = -1; + assert_true(lzma_str_to_filters("lzma2:dict=1g", &error_pos, filters, + 0, NULL) == NULL); + assert_int_eq(error_pos, 13); + + assert_uint_eq(filters[0].id, LZMA_FILTER_LZMA2); + assert_uint_eq(filters[1].id, LZMA_VLI_UNKNOWN); + + opts = filters[0].options; + assert_uint_eq(opts->dict_size, 1 << 30); + + lzma_filters_free(filters, NULL); +} + + +static void +test_lzma_str_from_filters(void) +{ + lzma_filter filters[LZMA_FILTERS_MAX]; + filters[0].id = LZMA_VLI_UNKNOWN; + + char *output_str = NULL; + + // Test basic NULL inputs. + assert_lzma_ret(lzma_str_from_filters(NULL, filters, 0, NULL), + LZMA_PROG_ERROR); + + assert_lzma_ret(lzma_str_from_filters(&output_str, NULL, 0, NULL), + LZMA_PROG_ERROR); + + // Test with empty filters array. + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, 0, NULL), + LZMA_OPTIONS_ERROR); + + // Create a simple filter array only containing an LZMA2 Filter. + assert_true(lzma_str_to_filters("lzma2", NULL, filters, 0, NULL) + == NULL); + + // Test with bad flags. + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, + LZMA_STR_ALL_FILTERS, NULL), LZMA_OPTIONS_ERROR); + + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, + LZMA_STR_NO_VALIDATION, NULL), LZMA_OPTIONS_ERROR); + + // Test with no flags. + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, 0, NULL), + LZMA_OK); + + assert_str_eq(output_str, "lzma2"); + free(output_str); + + // Test LZMA_STR_ENCODER flag. + // Only the return value is checked since the actual string + // may change in the future (even though it is unlikely). + // The order of options or the inclusion of new options could + // cause a change in output, so we will avoid hardcoding an + // expected result. + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, + LZMA_STR_ENCODER, NULL), LZMA_OK); + free(output_str); + + // Test LZMA_STR_DECODER flag. + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, + LZMA_STR_DECODER, NULL), LZMA_OK); + free(output_str); + + // Test LZMA_STR_GETOPT_LONG flag. + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, + LZMA_STR_GETOPT_LONG, NULL), LZMA_OK); + free(output_str); + + // Test LZMA_STR_NO_SPACES flag. + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, + LZMA_STR_NO_SPACES, NULL), LZMA_OK); + + // Check to be sure there are no spaces. + assert_true(strchr(output_str, ' ') == NULL); + + free(output_str); + + lzma_filters_free(filters, NULL); + +#if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86) + assert_true(lzma_str_to_filters("x86 lzma2", NULL, filters, 0, NULL) + == NULL); + + // It always allocates the options structure even when it's not + // needed due to start_offset = 0 being the default. + assert_true(filters[0].options != NULL); + + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, 0, NULL), + LZMA_OK); + + assert_str_eq(output_str, "x86 lzma2"); + + free(output_str); + + // Test setting BCJ option to NULL. + free(filters[0].options); + filters[0].options = NULL; + + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, 0, NULL), + LZMA_OK); + + assert_str_eq(output_str, "x86 lzma2"); + + lzma_filters_free(filters, NULL); + free(output_str); +#endif + + lzma_options_lzma opts; + assert_false(lzma_lzma_preset(&opts, LZMA_PRESET_DEFAULT)); + + // Test with too many Filters (array terminated after 4+ filters). + lzma_filter oversized_filters[LZMA_FILTERS_MAX + 2]; + + for (uint32_t i = 0; i < ARRAY_SIZE(oversized_filters) - 1; i++) { + oversized_filters[i].id = LZMA_FILTER_LZMA2; + oversized_filters[i].options = &opts; + } + + oversized_filters[LZMA_FILTERS_MAX + 1].id = LZMA_VLI_UNKNOWN; + oversized_filters[LZMA_FILTERS_MAX + 1].options = NULL; + + assert_lzma_ret(lzma_str_from_filters(&output_str, oversized_filters, + 0, NULL), LZMA_OPTIONS_ERROR); + + // Test with NULL filter options (when they cannot be NULL). + filters[0].id = LZMA_FILTER_LZMA2; + filters[0].options = NULL; + filters[1].id = LZMA_VLI_UNKNOWN; + + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, + LZMA_STR_ENCODER, NULL), LZMA_OPTIONS_ERROR); + + // Test with bad Filter ID. + filters[0].id = LZMA_VLI_UNKNOWN - 1; + assert_lzma_ret(lzma_str_from_filters(&output_str, filters, + LZMA_STR_ENCODER, NULL), LZMA_OPTIONS_ERROR); +} + + +static const char supported_encoders[][9] = { + "lzma2", +#ifdef HAVE_ENCODER_X86 + "x86", +#endif +#ifdef HAVE_ENCODER_POWERPC + "powerpc", +#endif +#ifdef HAVE_ENCODER_IA64 + "ia64", +#endif +#ifdef HAVE_ENCODER_ARM + "arm", +#endif +#ifdef HAVE_ENCODER_ARMTHUMB + "armthumb", +#endif +#ifdef HAVE_ENCODER_SPARC + "sparc", +#endif +#ifdef HAVE_ENCODER_ARM64 + "arm64", +#endif +#ifdef HAVE_ENCODER_RISCV + "riscv", +#endif +#ifdef HAVE_ENCODER_DELTA + "delta", +#endif +}; + +static const char supported_decoders[][9] = { + "lzma2", +#ifdef HAVE_DECODER_X86 + "x86", +#endif +#ifdef HAVE_DECODER_POWERPC + "powerpc", +#endif +#ifdef HAVE_DECODER_IA64 + "ia64", +#endif +#ifdef HAVE_DECODER_ARM + "arm", +#endif +#ifdef HAVE_DECODER_ARMTHUMB + "armthumb", +#endif +#ifdef HAVE_DECODER_SPARC + "sparc", +#endif +#ifdef HAVE_DECODER_ARM64 + "arm64", +#endif +#ifdef HAVE_DECODER_RISCV + "riscv", +#endif +#ifdef HAVE_DECODER_DELTA + "delta", +#endif +}; + +static const char supported_filters[][9] = { + "lzma2", +#if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86) + "x86", +#endif +#if defined(HAVE_ENCODER_POWERPC) || defined(HAVE_DECODER_POWERPC) + "powerpc", +#endif +#if defined(HAVE_ENCODER_IA64) || defined(HAVE_DECODER_IA64) + "ia64", +#endif +#if defined(HAVE_ENCODER_ARM) || defined(HAVE_DECODER_ARM) + "arm", +#endif +#if defined(HAVE_ENCODER_ARMTHUMB) || defined(HAVE_DECODER_ARMTHUMB) + "armthumb", +#endif +#if defined(HAVE_ENCODER_SPARC) || defined(HAVE_DECODER_SPARC) + "sparc", +#endif +#if defined(HAVE_ENCODER_ARM64) || defined(HAVE_DECODER_ARM64) + "arm64", +#endif +#if defined(HAVE_ENCODER_RISCV) || defined(HAVE_DECODER_RISCV) + "riscv", +#endif +#if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA) + "delta", +#endif +}; + + +static void +test_lzma_str_list_filters(void) +{ + // Test with basic NULL inputs. + assert_lzma_ret(lzma_str_list_filters(NULL, LZMA_VLI_UNKNOWN, 0, + NULL), LZMA_PROG_ERROR); + + char *str = NULL; + + // Test with bad flags. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN, + LZMA_STR_NO_VALIDATION , NULL), LZMA_OPTIONS_ERROR); + assert_true(str == NULL); + + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN, + LZMA_STR_NO_SPACES, NULL), LZMA_OPTIONS_ERROR); + assert_true(str == NULL); + + // Test with bad Filter ID. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN - 1, + 0, NULL), LZMA_OPTIONS_ERROR); + assert_true(str == NULL); + + // Test LZMA_STR_ENCODER flag. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN, + LZMA_STR_ENCODER, NULL), LZMA_OK); + + // NOTE: Just checking for "contains" is a bit weak check as + // "arm" matches "armthumb" and "arm64" too. + for (uint32_t i = 0; i < ARRAY_SIZE(supported_encoders); i++) + assert_str_contains(str, supported_encoders[i]); + + free(str); + + // Test LZMA_STR_DECODER flag. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN, + LZMA_STR_DECODER, NULL), LZMA_OK); + + for (uint32_t i = 0; i < ARRAY_SIZE(supported_decoders); i++) + assert_str_contains(str, supported_decoders[i]); + + free(str); + + // Test LZMA_STR_GETOPT_LONG flag. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN, + LZMA_STR_GETOPT_LONG, NULL), LZMA_OK); + assert_str_contains(str, "--"); + + free(str); + + // Test LZMA_STR_ALL_FILTERS flag. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN, + LZMA_STR_ALL_FILTERS, NULL), LZMA_OK); +#if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1) + // With the flag, the string should contain the LZMA1 Filter. + assert_str_contains(str, "lzma1"); + + free(str); + + // If a non .xz filter is specified, it should still list the Filter. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_FILTER_LZMA1, + 0, NULL), LZMA_OK); + assert_str_eq(str, "lzma1"); +#endif + free(str); + + // Test with no flags. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_VLI_UNKNOWN, + 0, NULL), LZMA_OK); + + for (uint32_t i = 0; i < ARRAY_SIZE(supported_filters); i++) + assert_str_contains(str, supported_filters[i]); + + assert_str_doesnt_contain(str, "lzma1"); + + free(str); + + // Test providing a Filter ID. + assert_lzma_ret(lzma_str_list_filters(&str, LZMA_FILTER_LZMA2, + LZMA_STR_ALL_FILTERS, NULL), LZMA_OK); + assert_str_eq(str, "lzma2"); + + free(str); +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + + tuktest_run(test_lzma_str_to_filters); + tuktest_run(test_lzma_str_from_filters); + tuktest_run(test_lzma_str_list_filters); + + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_hardware.c b/cpp/third_party/xz-5.8.3/tests/test_hardware.c new file mode 100644 index 000000000..45763f686 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_hardware.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_hardware.c +/// \brief Tests src/liblzma/api/lzma/hardware.h API functions +/// +/// Since the output values of these functions are hardware dependent, these +/// tests are trivial. They are simply used to detect errors and machines +/// that these function are not supported on. +// +// Author: Jia Tan +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" +#include "mythread.h" + + +static void +test_lzma_physmem(void) +{ + // NOTE: Use _skip instead of _fail because 0 can also mean that we + // don't know how to get this information on this operating system. + if (lzma_physmem() == 0) + assert_skip("Could not determine amount of physical memory"); +} + + +static void +test_lzma_cputhreads(void) +{ +#ifndef MYTHREAD_ENABLED + assert_skip("Threading support disabled"); +#else + if (lzma_cputhreads() == 0) + assert_skip("Could not determine cpu core count"); +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + tuktest_run(test_lzma_physmem); + tuktest_run(test_lzma_cputhreads); + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_index.c b/cpp/third_party/xz-5.8.3/tests/test_index.c new file mode 100644 index 000000000..50e554ffd --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_index.c @@ -0,0 +1,1826 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_index.c +/// \brief Tests functions handling the lzma_index structure +/// +/// \todo Implement tests for lzma_file_info_decoder +// +// Authors: Jia Tan +// Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + +// liblzma internal header file needed for: +// UNPADDED_SIZE_MIN +// UNPADDED_SIZE_MAX +// vli_ceil4 +#include "common/index.h" + + +#define MEMLIMIT (UINT64_C(1) << 20) + +#ifdef HAVE_ENCODERS +static uint8_t *decode_buffer; +static size_t decode_buffer_size = 0; +#endif + +static lzma_index *decode_test_index; + + +static void +test_lzma_index_memusage(void) +{ + // The return value from lzma_index_memusage is an approximation + // of the amount of memory needed for lzma_index for a given + // amount of Streams and Blocks. It will be an upperbound, + // so this test will mostly sanity check and error check the + // function. + + // The maximum number of Streams should be UINT32_MAX in the + // current implementation even though the parameter is lzma_vli. + assert_uint_eq(lzma_index_memusage((lzma_vli)UINT32_MAX + 1, 1), + UINT64_MAX); + + // While the number of blocks is lzma_vli, the real maximum value is + // much smaller than LZMA_VLI_MAX. Just check that it fails with a + // huge but valid VLI and that it succeeds with a smaller one. + assert_uint_eq(lzma_index_memusage(1, LZMA_VLI_MAX / 5), UINT64_MAX); + assert_uint(lzma_index_memusage(1, LZMA_VLI_MAX / 11), <, UINT64_MAX); + + // Number of Streams must be non-zero + assert_uint_eq(lzma_index_memusage(0, 1), UINT64_MAX); + + // Number of Blocks CAN be zero + assert_uint(lzma_index_memusage(1, 0), !=, UINT64_MAX); + + // Arbitrary values for Stream and Block should work without error + // and should always increase + uint64_t previous = 1; + lzma_vli streams = 1; + lzma_vli blocks = 1; + + // Test 100 different increasing values for Streams and Block + for (int i = 0; i < 100; i++) { + uint64_t current = lzma_index_memusage(streams, blocks); + assert_uint(current, >, previous); + previous = current; + streams += 29; + blocks += 107; + } + + // Force integer overflow in calculation (should result in an error) + assert_uint_eq(lzma_index_memusage(UINT32_MAX, LZMA_VLI_MAX), + UINT64_MAX); +} + + +static void +test_lzma_index_memused(void) +{ + // Very similar to test_lzma_index_memusage above since + // lzma_index_memused is essentially a wrapper for + // lzma_index_memusage + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Test with empty Index + assert_uint(lzma_index_memused(idx), <, UINT64_MAX); + + // Append small Blocks and then test again (should pass). + for (lzma_vli i = 0; i < 10; i++) + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + + assert_uint(lzma_index_memused(idx), <, UINT64_MAX); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_append(void) +{ + // Basic input-output test done here. + // Less trivial tests for this function are done throughout + // other tests. + + // First test with NULL lzma_index + assert_lzma_ret(lzma_index_append(NULL, NULL, UNPADDED_SIZE_MIN, + 1), LZMA_PROG_ERROR); + + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Test with invalid Unpadded Size + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN - 1, 1), LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MAX + 1, 1), LZMA_PROG_ERROR); + + // Test with invalid Uncompressed Size + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MAX, LZMA_VLI_MAX + 1), + LZMA_PROG_ERROR); + + // Test expected successful Block appends + assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MIN, + 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN * 2, + 2), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN * 3, + 3), LZMA_OK); + + lzma_index_end(idx, NULL); + + // Test compressed .xz file size growing too large. This also tests + // a failing assert fixed in ae5c07b22a6b3766b84f409f1b6b5c100469068a. + // Should result in LZMA_DATA_ERROR. + idx = lzma_index_init(NULL); + + // The calculation for maximum unpadded size is to make room for the + // second stream when lzma_index_cat() is called. The + // 4 * LZMA_STREAM_HEADER_SIZE is for the header and footer of + // both streams. The extra 24 bytes are for the size of the indexes + // for both streams. This allows us to maximize the unpadded sum + // during the lzma_index_append() call after the indexes have been + // concatenated. + assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MAX + - ((4 * LZMA_STREAM_HEADER_SIZE) + 24), 1), LZMA_OK); + + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + assert_lzma_ret(lzma_index_cat(second, idx, NULL), LZMA_OK); + + assert_lzma_ret(lzma_index_append(second, NULL, UNPADDED_SIZE_MAX, 1), + LZMA_DATA_ERROR); + + lzma_index_end(second, NULL); + + // Test uncompressed size growing too large. + // Should result in LZMA_DATA_ERROR. + idx = lzma_index_init(NULL); + + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, LZMA_VLI_MAX), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_DATA_ERROR); + + lzma_index_end(idx, NULL); + + // Currently not testing for error case when the size of the Index + // grows too large to be stored. This was not practical to test for + // since too many Blocks needed to be created to cause this. +} + + +static void +test_lzma_index_stream_flags(void) +{ + // Only trivial tests done here testing for basic functionality. + // More in-depth testing for this function will be done in + // test_lzma_index_checks. + + // Testing for NULL inputs + assert_lzma_ret(lzma_index_stream_flags(NULL, NULL), + LZMA_PROG_ERROR); + + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + assert_lzma_ret(lzma_index_stream_flags(idx, NULL), + LZMA_PROG_ERROR); + + lzma_stream_flags stream_flags = { + .version = 0, + .backward_size = LZMA_BACKWARD_SIZE_MIN, + .check = LZMA_CHECK_CRC32 + }; + + assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags), + LZMA_OK); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_checks(void) +{ + // Tests should still pass, even if some of the check types + // are disabled. + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + lzma_stream_flags stream_flags = { + .version = 0, + .backward_size = LZMA_BACKWARD_SIZE_MIN, + .check = LZMA_CHECK_NONE + }; + + // First set the check type to None + assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags), + LZMA_OK); + assert_uint_eq(lzma_index_checks(idx), + LZMA_INDEX_CHECK_MASK_NONE); + + // Set the check type to CRC32 and repeat + stream_flags.check = LZMA_CHECK_CRC32; + assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags), + LZMA_OK); + assert_uint_eq(lzma_index_checks(idx), + LZMA_INDEX_CHECK_MASK_CRC32); + + // Set the check type to CRC64 and repeat + stream_flags.check = LZMA_CHECK_CRC64; + assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags), + LZMA_OK); + assert_uint_eq(lzma_index_checks(idx), + LZMA_INDEX_CHECK_MASK_CRC64); + + // Set the check type to SHA256 and repeat + stream_flags.check = LZMA_CHECK_SHA256; + assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags), + LZMA_OK); + assert_uint_eq(lzma_index_checks(idx), + LZMA_INDEX_CHECK_MASK_SHA256); + + // Create second lzma_index and cat to first + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + // Set the check type to CRC32 for the second lzma_index + stream_flags.check = LZMA_CHECK_CRC32; + assert_lzma_ret(lzma_index_stream_flags(second, &stream_flags), + LZMA_OK); + + assert_uint_eq(lzma_index_checks(second), + LZMA_INDEX_CHECK_MASK_CRC32); + + assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK); + + // Index should now have both CRC32 and SHA256 + assert_uint_eq(lzma_index_checks(idx), + LZMA_INDEX_CHECK_MASK_CRC32 | + LZMA_INDEX_CHECK_MASK_SHA256); + + // Change the check type of the second Stream to SHA256 + stream_flags.check = LZMA_CHECK_SHA256; + assert_lzma_ret(lzma_index_stream_flags(idx, &stream_flags), + LZMA_OK); + + // Index should now have only SHA256 + assert_uint_eq(lzma_index_checks(idx), + LZMA_INDEX_CHECK_MASK_SHA256); + + // Test with a third Stream + lzma_index *third = lzma_index_init(NULL); + assert_true(third != NULL); + + stream_flags.check = LZMA_CHECK_CRC64; + assert_lzma_ret(lzma_index_stream_flags(third, &stream_flags), + LZMA_OK); + + assert_uint_eq(lzma_index_checks(third), + LZMA_INDEX_CHECK_MASK_CRC64); + + assert_lzma_ret(lzma_index_cat(idx, third, NULL), LZMA_OK); + + // Index should now have CRC64 and SHA256 + assert_uint_eq(lzma_index_checks(idx), + LZMA_INDEX_CHECK_MASK_CRC64 | + LZMA_INDEX_CHECK_MASK_SHA256); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_stream_padding(void) +{ + // Test NULL lzma_index + assert_lzma_ret(lzma_index_stream_padding(NULL, 0), + LZMA_PROG_ERROR); + + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Test Stream Padding not a multiple of 4 + assert_lzma_ret(lzma_index_stream_padding(idx, 3), + LZMA_PROG_ERROR); + + // Test Stream Padding too large + assert_lzma_ret(lzma_index_stream_padding(idx, LZMA_VLI_MAX - 3), + LZMA_DATA_ERROR); + + // Test Stream Padding valid + assert_lzma_ret(lzma_index_stream_padding(idx, 0x1000), + LZMA_OK); + assert_lzma_ret(lzma_index_stream_padding(idx, 4), + LZMA_OK); + assert_lzma_ret(lzma_index_stream_padding(idx, 0), + LZMA_OK); + + // Test Stream Padding causing the file size to grow too large + assert_lzma_ret(lzma_index_append(idx, NULL, + LZMA_VLI_MAX - 0x1000, 1), LZMA_OK); + assert_lzma_ret(lzma_index_stream_padding(idx, 0x1000), + LZMA_DATA_ERROR); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_stream_count(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + assert_uint_eq(lzma_index_stream_count(idx), 1); + + // Appending Blocks should not change the Stream count value + assert_lzma_ret(lzma_index_append(idx, NULL, UNPADDED_SIZE_MIN, + 1), LZMA_OK); + + assert_uint_eq(lzma_index_stream_count(idx), 1); + + // Test with multiple Streams + for (uint32_t i = 0; i < 100; i++) { + lzma_index *idx_cat = lzma_index_init(NULL); + assert_true(idx != NULL); + assert_lzma_ret(lzma_index_cat(idx, idx_cat, NULL), LZMA_OK); + assert_uint_eq(lzma_index_stream_count(idx), i + 2); + } + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_block_count(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + assert_uint_eq(lzma_index_block_count(idx), 0); + + const uint32_t iterations = 0x1000; + for (uint32_t i = 0; i < iterations; i++) { + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + assert_uint_eq(lzma_index_block_count(idx), i + 1); + } + + // Create new lzma_index with a few Blocks + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + assert_lzma_ret(lzma_index_append(second, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(second, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(second, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + + assert_uint_eq(lzma_index_block_count(second), 3); + + // Concatenate the lzma_indexes together and the result should have + // the sum of the two individual counts. + assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK); + assert_uint_eq(lzma_index_block_count(idx), iterations + 3); + + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + + assert_uint_eq(lzma_index_block_count(idx), iterations + 4); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_size(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Base size should be: + // 1 byte Index Indicator + // 1 byte Number of Records + // 0 bytes Records + // 2 bytes Index Padding + // 4 bytes CRC32 + // Total: 8 bytes + assert_uint_eq(lzma_index_size(idx), 8); + + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + + // New size should be: + // 1 byte Index Indicator + // 1 byte Number of Records + // 2 bytes Records + // 0 bytes Index Padding + // 4 bytes CRC32 + // Total: 8 bytes + assert_uint_eq(lzma_index_size(idx), 8); + + assert_lzma_ret(lzma_index_append(idx, NULL, + LZMA_VLI_MAX / 4, LZMA_VLI_MAX / 4), LZMA_OK); + + // New size should be: + // 1 byte Index Indicator + // 1 byte Number of Records + // 20 bytes Records + // 2 bytes Index Padding + // 4 bytes CRC32 + // Total: 28 bytes + assert_uint_eq(lzma_index_size(idx), 28); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_stream_size(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Stream size calculated by: + // Size of Stream Header (12 bytes) + // Size of all Blocks + // Size of the Index + // Size of the Stream Footer (12 bytes) + + // First test with empty Index + // Stream size should be: + // Size of Stream Header - 12 bytes + // Size of all Blocks - 0 bytes + // Size of Index - 8 bytes + // Size of Stream Footer - 12 bytes + // Total: 32 bytes + assert_uint_eq(lzma_index_stream_size(idx), 32); + + // Next, append a few Blocks and retest + assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, 999, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, 997, 1), LZMA_OK); + + // Stream size should be: + // Size of Stream Header - 12 bytes + // Size of all Blocks - 3000 bytes [*] + // Size of Index - 16 bytes + // Size of Stream Footer - 12 bytes + // Total: 3040 bytes + // + // [*] Block size is a multiple of 4 bytes so 999 and 997 get + // rounded up to 1000 bytes. + assert_uint_eq(lzma_index_stream_size(idx), 3040); + + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + assert_uint_eq(lzma_index_stream_size(second), 32); + assert_lzma_ret(lzma_index_append(second, NULL, 1000, 1), LZMA_OK); + + // Stream size should be: + // Size of Stream Header - 12 bytes + // Size of all Blocks - 1000 bytes + // Size of Index - 12 bytes + // Size of Stream Footer - 12 bytes + // Total: 1036 bytes + assert_uint_eq(lzma_index_stream_size(second), 1036); + + assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK); + + // Stream size should be: + // Size of Stream Header - 12 bytes + // Size of all Blocks - 4000 bytes + // Size of Index - 20 bytes + // Size of Stream Footer - 12 bytes + // Total: 4044 bytes + assert_uint_eq(lzma_index_stream_size(idx), 4044); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_total_size(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // First test empty lzma_index. + // Result should be 0 since no Blocks have been added. + assert_uint_eq(lzma_index_total_size(idx), 0); + + // Add a few Blocks and retest after each append + assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK); + assert_uint_eq(lzma_index_total_size(idx), 1000); + + assert_lzma_ret(lzma_index_append(idx, NULL, 999, 1), LZMA_OK); + assert_uint_eq(lzma_index_total_size(idx), 2000); + + assert_lzma_ret(lzma_index_append(idx, NULL, 997, 1), LZMA_OK); + assert_uint_eq(lzma_index_total_size(idx), 3000); + + // Create second lzma_index and append Blocks to it. + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + assert_uint_eq(lzma_index_total_size(second), 0); + + assert_lzma_ret(lzma_index_append(second, NULL, 100, 1), LZMA_OK); + assert_uint_eq(lzma_index_total_size(second), 100); + + assert_lzma_ret(lzma_index_append(second, NULL, 100, 1), LZMA_OK); + assert_uint_eq(lzma_index_total_size(second), 200); + + // Concatenate the Streams together + assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK); + + // The resulting total size should be the size of all Blocks + // from both Streams + assert_uint_eq(lzma_index_total_size(idx), 3200); + + // Test sizes that aren't multiples of four bytes + assert_lzma_ret(lzma_index_append(idx, NULL, 11, 1), LZMA_OK); + assert_uint_eq(lzma_index_total_size(idx), 3212); + + assert_lzma_ret(lzma_index_append(idx, NULL, 11, 1), LZMA_OK); + assert_uint_eq(lzma_index_total_size(idx), 3224); + + assert_lzma_ret(lzma_index_append(idx, NULL, 9, 1), LZMA_OK); + assert_uint_eq(lzma_index_total_size(idx), 3236); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_file_size(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Should be the same as test_lzma_index_stream_size with + // only one Stream and no Stream Padding. + assert_uint_eq(lzma_index_file_size(idx), 32); + + assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, 999, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, 997, 1), LZMA_OK); + + assert_uint_eq(lzma_index_file_size(idx), 3040); + + // Next add Stream Padding + assert_lzma_ret(lzma_index_stream_padding(idx, 1000), + LZMA_OK); + + assert_uint_eq(lzma_index_file_size(idx), 4040); + + // Create second lzma_index. + // Very similar to test_lzma_index_stream_size, but + // the values should include the headers of the second Stream. + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + assert_lzma_ret(lzma_index_append(second, NULL, 1000, 1), LZMA_OK); + assert_uint_eq(lzma_index_stream_size(second), 1036); + + assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK); + + // .xz file size should be: + // Size of 2 Stream Headers - 12 * 2 bytes + // Size of all Blocks - 3000 + 1000 bytes + // Size of 2 Indexes - 16 + 12 bytes + // Size of Stream Padding - 1000 bytes + // Size of 2 Stream Footers - 12 * 2 bytes + // Total: 5076 bytes + assert_uint_eq(lzma_index_file_size(idx), 5076); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_uncompressed_size(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Empty lzma_index should have 0 uncompressed .xz file size. + assert_uint_eq(lzma_index_uncompressed_size(idx), 0); + + // Append a few small Blocks + assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 10), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 100), LZMA_OK); + + assert_uint_eq(lzma_index_uncompressed_size(idx), 111); + + // Create another lzma_index + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + // Append a few small Blocks + assert_lzma_ret(lzma_index_append(second, NULL, 1000, 2), LZMA_OK); + assert_lzma_ret(lzma_index_append(second, NULL, 1000, 20), LZMA_OK); + assert_lzma_ret(lzma_index_append(second, NULL, 1000, 200), LZMA_OK); + + assert_uint_eq(lzma_index_uncompressed_size(second), 222); + + // Concatenate second lzma_index to first + assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK); + + // New uncompressed .xz file size should be the sum of the two Streams + assert_uint_eq(lzma_index_uncompressed_size(idx), 333); + + // Append one more Block to the lzma_index and ensure that + // it is properly updated + assert_lzma_ret(lzma_index_append(idx, NULL, 1000, 111), LZMA_OK); + assert_uint_eq(lzma_index_uncompressed_size(idx), 444); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_iter_init(void) +{ + // Testing basic init functionality. + // The init function should call rewind on the iterator. + lzma_index *first = lzma_index_init(NULL); + assert_true(first != NULL); + + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + lzma_index *third = lzma_index_init(NULL); + assert_true(third != NULL); + + assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK); + assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK); + + lzma_index_iter iter; + lzma_index_iter_init(&iter, first); + + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)); + assert_uint_eq(iter.stream.number, 1); + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)); + assert_uint_eq(iter.stream.number, 2); + + lzma_index_iter_init(&iter, first); + + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)); + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)); + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)); + assert_uint_eq(iter.stream.number, 3); + + lzma_index_end(first, NULL); +} + + +static void +test_lzma_index_iter_rewind(void) +{ + lzma_index *first = lzma_index_init(NULL); + assert_true(first != NULL); + + lzma_index_iter iter; + lzma_index_iter_init(&iter, first); + + // Append 3 Blocks and iterate over each. This is to test + // the LZMA_INDEX_ITER_BLOCK mode. + for (uint32_t i = 0; i < 3; i++) { + assert_lzma_ret(lzma_index_append(first, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_BLOCK)); + assert_uint_eq(iter.block.number_in_file, i + 1); + assert_uint_eq(iter.block.number_in_stream, i + 1); + } + + // Rewind back to the beginning and iterate over the Blocks again + lzma_index_iter_rewind(&iter); + + // Should be able to re-iterate over the Blocks again. + for (uint32_t i = 0; i < 3; i++) { + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_BLOCK)); + assert_uint_eq(iter.block.number_in_file, i + 1); + assert_uint_eq(iter.block.number_in_stream, i + 1); + } + + // Next concatenate two more lzma_indexes, iterate over them, + // rewind, and iterate over them again. This is to test + // the LZMA_INDEX_ITER_STREAM mode. + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + lzma_index *third = lzma_index_init(NULL); + assert_true(third != NULL); + + assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK); + assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK); + + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_STREAM)); + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_STREAM)); + + assert_uint_eq(iter.stream.number, 3); + + lzma_index_iter_rewind(&iter); + + for (uint32_t i = 0; i < 3; i++) { + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_STREAM)); + assert_uint_eq(iter.stream.number, i + 1); + } + + lzma_index_end(first, NULL); +} + + +static void +test_lzma_index_iter_next(void) +{ + lzma_index *first = lzma_index_init(NULL); + assert_true(first != NULL); + + lzma_index_iter iter; + lzma_index_iter_init(&iter, first); + + // First test bad mode values + for (uint32_t i = LZMA_INDEX_ITER_NONEMPTY_BLOCK + 1; i < 100; i++) + assert_true(lzma_index_iter_next(&iter, i)); + + // Test iterating over Blocks + assert_lzma_ret(lzma_index_append(first, NULL, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(first, NULL, + UNPADDED_SIZE_MIN * 2, 10), LZMA_OK); + assert_lzma_ret(lzma_index_append(first, NULL, + UNPADDED_SIZE_MIN * 3, 100), LZMA_OK); + + // For Blocks, need to verify: + // - number_in_file (overall Block number) + // - compressed_file_offset + // - uncompressed_file_offset + // - number_in_stream (Block number relative to current Stream) + // - compressed_stream_offset + // - uncompressed_stream_offset + // - uncompressed_size + // - unpadded_size + // - total_size + + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)); + + // Verify Block data stored correctly + assert_uint_eq(iter.block.number_in_file, 1); + + // Should start right after the Stream Header + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE); + assert_uint_eq(iter.block.uncompressed_file_offset, 0); + assert_uint_eq(iter.block.number_in_stream, 1); + assert_uint_eq(iter.block.compressed_stream_offset, + LZMA_STREAM_HEADER_SIZE); + assert_uint_eq(iter.block.uncompressed_stream_offset, 0); + assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN); + assert_uint_eq(iter.block.total_size, vli_ceil4(UNPADDED_SIZE_MIN)); + + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)); + + // Verify Block data stored correctly + assert_uint_eq(iter.block.number_in_file, 2); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + + vli_ceil4(UNPADDED_SIZE_MIN)); + assert_uint_eq(iter.block.uncompressed_file_offset, 1); + assert_uint_eq(iter.block.number_in_stream, 2); + assert_uint_eq(iter.block.compressed_stream_offset, + LZMA_STREAM_HEADER_SIZE + + vli_ceil4(UNPADDED_SIZE_MIN)); + assert_uint_eq(iter.block.uncompressed_stream_offset, 1); + assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN * 2); + assert_uint_eq(iter.block.total_size, vli_ceil4(UNPADDED_SIZE_MIN * 2)); + + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)); + + // Verify Block data stored correctly + assert_uint_eq(iter.block.number_in_file, 3); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + + vli_ceil4(UNPADDED_SIZE_MIN) + + vli_ceil4(UNPADDED_SIZE_MIN * 2)); + assert_uint_eq(iter.block.uncompressed_file_offset, 11); + assert_uint_eq(iter.block.number_in_stream, 3); + assert_uint_eq(iter.block.compressed_stream_offset, + LZMA_STREAM_HEADER_SIZE + + vli_ceil4(UNPADDED_SIZE_MIN) + + vli_ceil4(UNPADDED_SIZE_MIN * 2)); + assert_uint_eq(iter.block.uncompressed_stream_offset, 11); + assert_uint_eq(iter.block.unpadded_size, UNPADDED_SIZE_MIN * 3); + assert_uint_eq(iter.block.total_size, + vli_ceil4(UNPADDED_SIZE_MIN * 3)); + + // Only three Blocks were added, so this should return true + assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)); + + const lzma_vli second_stream_compressed_start = + LZMA_STREAM_HEADER_SIZE * 2 + + vli_ceil4(UNPADDED_SIZE_MIN) + + vli_ceil4(UNPADDED_SIZE_MIN * 2) + + vli_ceil4(UNPADDED_SIZE_MIN * 3) + + lzma_index_size(first); + const lzma_vli second_stream_uncompressed_start = 1 + 10 + 100; + + // Test iterating over Streams. + // The second Stream will have 0 Blocks + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + // Set Stream Flags for Stream 2 + lzma_stream_flags flags = { + .version = 0, + .backward_size = LZMA_BACKWARD_SIZE_MIN, + .check = LZMA_CHECK_CRC32 + }; + + assert_lzma_ret(lzma_index_stream_flags(second, &flags), LZMA_OK); + + // The Second stream will have 8 bytes of Stream Padding + assert_lzma_ret(lzma_index_stream_padding(second, 8), LZMA_OK); + + const lzma_vli second_stream_index_size = lzma_index_size(second); + + // The third Stream will have 2 Blocks + lzma_index *third = lzma_index_init(NULL); + assert_true(third != NULL); + + assert_lzma_ret(lzma_index_append(third, NULL, 32, 20), LZMA_OK); + assert_lzma_ret(lzma_index_append(third, NULL, 64, 40), LZMA_OK); + + const lzma_vli third_stream_index_size = lzma_index_size(third); + + assert_lzma_ret(lzma_index_cat(first, second, NULL), LZMA_OK); + assert_lzma_ret(lzma_index_cat(first, third, NULL), LZMA_OK); + + // For Streams, need to verify: + // - flags (Stream Flags) + // - number (Stream count) + // - block_count + // - compressed_offset + // - uncompressed_offset + // - compressed_size + // - uncompressed_size + // - padding (Stream Padding) + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)); + + // Verify Stream + assert_uint_eq(iter.stream.flags->backward_size, + LZMA_BACKWARD_SIZE_MIN); + assert_uint_eq(iter.stream.flags->check, LZMA_CHECK_CRC32); + assert_uint_eq(iter.stream.number, 2); + assert_uint_eq(iter.stream.block_count, 0); + assert_uint_eq(iter.stream.compressed_offset, + second_stream_compressed_start); + assert_uint_eq(iter.stream.uncompressed_offset, + second_stream_uncompressed_start); + assert_uint_eq(iter.stream.compressed_size, + LZMA_STREAM_HEADER_SIZE * 2 + + second_stream_index_size); + assert_uint_eq(iter.stream.uncompressed_size, 0); + assert_uint_eq(iter.stream.padding, 8); + + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)); + + // Verify Stream + const lzma_vli third_stream_compressed_start = + second_stream_compressed_start + + LZMA_STREAM_HEADER_SIZE * 2 + + 8 + // Stream padding + second_stream_index_size; + const lzma_vli third_stream_uncompressed_start = + second_stream_uncompressed_start; + + assert_uint_eq(iter.stream.number, 3); + assert_uint_eq(iter.stream.block_count, 2); + assert_uint_eq(iter.stream.compressed_offset, + third_stream_compressed_start); + assert_uint_eq(iter.stream.uncompressed_offset, + third_stream_uncompressed_start); + assert_uint_eq(iter.stream.compressed_size, + LZMA_STREAM_HEADER_SIZE * 2 + + 96 + // Total compressed size + third_stream_index_size); + assert_uint_eq(iter.stream.uncompressed_size, 60); + assert_uint_eq(iter.stream.padding, 0); + + assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)); + + // Even after a failing call to next with ITER_STREAM mode, + // should still be able to iterate over the 2 Blocks in + // Stream 3. + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)); + + // Verify both Blocks + + // Next call to iterate Block should return true because the + // first Block can already be read from the earlier *successful* + // LZMA_INDEX_ITER_STREAM call; the previous failed call doesn't + // modify the iterator. + assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)); + + // Rewind to test LZMA_INDEX_ITER_ANY + lzma_index_iter_rewind(&iter); + + // Iterate past the first three Blocks + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)); + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)); + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)); + + // Iterate past the next Stream + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)); + + // Iterate past the next Stream + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)); + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)); + + // Last call should fail + assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)); + + // Rewind to test LZMA_INDEX_ITER_NONEMPTY_BLOCK + lzma_index_iter_rewind(&iter); + + // Iterate past the first three Blocks + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_NONEMPTY_BLOCK)); + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_NONEMPTY_BLOCK)); + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_NONEMPTY_BLOCK)); + + // Skip past the next Stream which has no Blocks. + // We will get to the first Block of the third Stream. + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_NONEMPTY_BLOCK)); + + // Iterate past the second (the last) Block in the third Stream + assert_false(lzma_index_iter_next(&iter, + LZMA_INDEX_ITER_NONEMPTY_BLOCK)); + + // Last call should fail since there is nothing left to iterate over. + assert_true(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)); + + lzma_index_end(first, NULL); +} + + +static void +test_lzma_index_iter_locate(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + lzma_index_iter iter; + lzma_index_iter_init(&iter, idx); + + // Cannot locate anything from an empty Index. + assert_true(lzma_index_iter_locate(&iter, 0)); + assert_true(lzma_index_iter_locate(&iter, 555)); + + // One empty Record: nothing is found since there's no uncompressed + // data. + assert_lzma_ret(lzma_index_append(idx, NULL, 16, 0), LZMA_OK); + assert_true(lzma_index_iter_locate(&iter, 0)); + + // Non-empty Record and we can find something. + assert_lzma_ret(lzma_index_append(idx, NULL, 32, 5), LZMA_OK); + assert_false(lzma_index_iter_locate(&iter, 0)); + assert_uint_eq(iter.block.total_size, 32); + assert_uint_eq(iter.block.uncompressed_size, 5); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + 16); + assert_uint_eq(iter.block.uncompressed_file_offset, 0); + + // Still cannot find anything past the end. + assert_true(lzma_index_iter_locate(&iter, 5)); + + // Add the third Record. + assert_lzma_ret(lzma_index_append(idx, NULL, 40, 11), LZMA_OK); + + assert_false(lzma_index_iter_locate(&iter, 0)); + assert_uint_eq(iter.block.total_size, 32); + assert_uint_eq(iter.block.uncompressed_size, 5); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + 16); + assert_uint_eq(iter.block.uncompressed_file_offset, 0); + + assert_false(lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)); + assert_uint_eq(iter.block.total_size, 40); + assert_uint_eq(iter.block.uncompressed_size, 11); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + 16 + 32); + assert_uint_eq(iter.block.uncompressed_file_offset, 5); + + assert_false(lzma_index_iter_locate(&iter, 2)); + assert_uint_eq(iter.block.total_size, 32); + assert_uint_eq(iter.block.uncompressed_size, 5); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + 16); + assert_uint_eq(iter.block.uncompressed_file_offset, 0); + + assert_false(lzma_index_iter_locate(&iter, 5)); + assert_uint_eq(iter.block.total_size, 40); + assert_uint_eq(iter.block.uncompressed_size, 11); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + 16 + 32); + assert_uint_eq(iter.block.uncompressed_file_offset, 5); + + assert_false(lzma_index_iter_locate(&iter, 5 + 11 - 1)); + assert_uint_eq(iter.block.total_size, 40); + assert_uint_eq(iter.block.uncompressed_size, 11); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + 16 + 32); + assert_uint_eq(iter.block.uncompressed_file_offset, 5); + + assert_true(lzma_index_iter_locate(&iter, 5 + 11)); + assert_true(lzma_index_iter_locate(&iter, 5 + 15)); + + // Large Index + lzma_index_end(idx, NULL); + idx = lzma_index_init(NULL); + assert_true(idx != NULL); + lzma_index_iter_init(&iter, idx); + + for (uint32_t n = 4; n <= 4 * 5555; n += 4) + assert_lzma_ret(lzma_index_append(idx, NULL, n + 7, n), + LZMA_OK); + + assert_uint_eq(lzma_index_block_count(idx), 5555); + + // First Record + assert_false(lzma_index_iter_locate(&iter, 0)); + assert_uint_eq(iter.block.unpadded_size, 4 + 7); + assert_uint_eq(iter.block.total_size, 4 + 8); + assert_uint_eq(iter.block.uncompressed_size, 4); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE); + assert_uint_eq(iter.block.uncompressed_file_offset, 0); + + assert_false(lzma_index_iter_locate(&iter, 3)); + assert_uint_eq(iter.block.unpadded_size, 4 + 7); + assert_uint_eq(iter.block.total_size, 4 + 8); + assert_uint_eq(iter.block.uncompressed_size, 4); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE); + assert_uint_eq(iter.block.uncompressed_file_offset, 0); + + // Second Record + assert_false(lzma_index_iter_locate(&iter, 4)); + assert_uint_eq(iter.block.unpadded_size, 2 * 4 + 7); + assert_uint_eq(iter.block.total_size, 2 * 4 + 8); + assert_uint_eq(iter.block.uncompressed_size, 2 * 4); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + 4 + 8); + assert_uint_eq(iter.block.uncompressed_file_offset, 4); + + // Last Record + assert_false(lzma_index_iter_locate( + &iter, lzma_index_uncompressed_size(idx) - 1)); + assert_uint_eq(iter.block.unpadded_size, 4 * 5555 + 7); + assert_uint_eq(iter.block.total_size, 4 * 5555 + 8); + assert_uint_eq(iter.block.uncompressed_size, 4 * 5555); + assert_uint_eq(iter.block.compressed_file_offset, + lzma_index_total_size(idx) + + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8); + assert_uint_eq(iter.block.uncompressed_file_offset, + lzma_index_uncompressed_size(idx) - 4 * 5555); + + // Allocation chunk boundaries. See INDEX_GROUP_SIZE in + // liblzma/common/index.c. + const uint32_t group_multiple = 256 * 4; + const uint32_t radius = 8; + const uint32_t start = group_multiple - radius; + lzma_vli ubase = 0; + lzma_vli tbase = 0; + uint32_t n; + for (n = 1; n < start; ++n) { + ubase += n * 4; + tbase += n * 4 + 8; + } + + while (n < start + 2 * radius) { + assert_false(lzma_index_iter_locate(&iter, ubase + n * 4)); + + assert_uint_eq(iter.block.compressed_file_offset, + tbase + n * 4 + 8 + + LZMA_STREAM_HEADER_SIZE); + assert_uint_eq(iter.block.uncompressed_file_offset, + ubase + n * 4); + + tbase += n * 4 + 8; + ubase += n * 4; + ++n; + + assert_uint_eq(iter.block.total_size, n * 4 + 8); + assert_uint_eq(iter.block.uncompressed_size, n * 4); + } + + // Do it also backwards. + while (n > start) { + assert_false(lzma_index_iter_locate( + &iter, ubase + (n - 1) * 4)); + + assert_uint_eq(iter.block.total_size, n * 4 + 8); + assert_uint_eq(iter.block.uncompressed_size, n * 4); + + --n; + tbase -= n * 4 + 8; + ubase -= n * 4; + + assert_uint_eq(iter.block.compressed_file_offset, + tbase + n * 4 + 8 + + LZMA_STREAM_HEADER_SIZE); + assert_uint_eq(iter.block.uncompressed_file_offset, + ubase + n * 4); + } + + // Test locating in concatenated Index. + lzma_index_end(idx, NULL); + idx = lzma_index_init(NULL); + assert_true(idx != NULL); + lzma_index_iter_init(&iter, idx); + for (n = 0; n < group_multiple; ++n) + assert_lzma_ret(lzma_index_append(idx, NULL, 8, 0), + LZMA_OK); + + assert_lzma_ret(lzma_index_append(idx, NULL, 16, 1), LZMA_OK); + assert_false(lzma_index_iter_locate(&iter, 0)); + assert_uint_eq(iter.block.total_size, 16); + assert_uint_eq(iter.block.uncompressed_size, 1); + assert_uint_eq(iter.block.compressed_file_offset, + LZMA_STREAM_HEADER_SIZE + group_multiple * 8); + assert_uint_eq(iter.block.uncompressed_file_offset, 0); + + lzma_index_end(idx, NULL); +} + + +static void +test_lzma_index_cat(void) +{ + // Most complex tests for this function are done in other tests. + // This will mostly test basic functionality. + + lzma_index *dest = lzma_index_init(NULL); + assert_true(dest != NULL); + + lzma_index *src = lzma_index_init(NULL); + assert_true(src != NULL); + + // First test NULL dest or src + assert_lzma_ret(lzma_index_cat(NULL, NULL, NULL), LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_cat(dest, NULL, NULL), LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_cat(NULL, src, NULL), LZMA_PROG_ERROR); + + // Check for compressed size overflow + assert_lzma_ret(lzma_index_append(dest, NULL, + (UNPADDED_SIZE_MAX / 2) + 1, 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(src, NULL, + (UNPADDED_SIZE_MAX / 2) + 1, 1), LZMA_OK); + assert_lzma_ret(lzma_index_cat(dest, src, NULL), LZMA_DATA_ERROR); + + lzma_index_end(src, NULL); + lzma_index_end(dest, NULL); + + // Check for uncompressed size overflow + dest = lzma_index_init(NULL); + assert_true(dest != NULL); + + src = lzma_index_init(NULL); + assert_true(src != NULL); + + assert_lzma_ret(lzma_index_append(dest, NULL, + UNPADDED_SIZE_MIN, (LZMA_VLI_MAX / 2) + 1), LZMA_OK); + assert_lzma_ret(lzma_index_append(src, NULL, + UNPADDED_SIZE_MIN, (LZMA_VLI_MAX / 2) + 1), LZMA_OK); + assert_lzma_ret(lzma_index_cat(dest, src, NULL), LZMA_DATA_ERROR); + + lzma_index_end(dest, NULL); + lzma_index_end(src, NULL); +} + + +// Helper function for test_lzma_index_dup(). +static bool +index_is_equal(const lzma_index *a, const lzma_index *b) +{ + // Compare only the Stream and Block sizes and offsets. + lzma_index_iter ra, rb; + lzma_index_iter_init(&ra, a); + lzma_index_iter_init(&rb, b); + + while (true) { + bool reta = lzma_index_iter_next(&ra, LZMA_INDEX_ITER_ANY); + bool retb = lzma_index_iter_next(&rb, LZMA_INDEX_ITER_ANY); + + // If both iterators finish at the same time, then the Indexes + // are identical. + if (reta) + return retb; + + if (ra.stream.number != rb.stream.number + || ra.stream.block_count + != rb.stream.block_count + || ra.stream.compressed_offset + != rb.stream.compressed_offset + || ra.stream.uncompressed_offset + != rb.stream.uncompressed_offset + || ra.stream.compressed_size + != rb.stream.compressed_size + || ra.stream.uncompressed_size + != rb.stream.uncompressed_size + || ra.stream.padding + != rb.stream.padding) + return false; + + if (ra.stream.block_count == 0) + continue; + + if (ra.block.number_in_file != rb.block.number_in_file + || ra.block.compressed_file_offset + != rb.block.compressed_file_offset + || ra.block.uncompressed_file_offset + != rb.block.uncompressed_file_offset + || ra.block.number_in_stream + != rb.block.number_in_stream + || ra.block.compressed_stream_offset + != rb.block.compressed_stream_offset + || ra.block.uncompressed_stream_offset + != rb.block.uncompressed_stream_offset + || ra.block.uncompressed_size + != rb.block.uncompressed_size + || ra.block.unpadded_size + != rb.block.unpadded_size + || ra.block.total_size + != rb.block.total_size) + return false; + } +} + + +// Allocator that succeeds for the first two allocation but fails the rest. +static void * +my_alloc(void *opaque, size_t a, size_t b) +{ + (void)opaque; + + assert_true(SIZE_MAX / a >= b); + + static unsigned count = 0; + if (count >= 2) + return NULL; + + ++count; + return malloc(a * b); +} + + +static const lzma_allocator test_index_dup_alloc = { &my_alloc, NULL, NULL }; + + +static void +test_lzma_index_dup(void) +{ + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Test for the bug fix 21515d79d778b8730a434f151b07202d52a04611: + // liblzma: Fix lzma_index_dup() for empty Streams. + assert_lzma_ret(lzma_index_stream_padding(idx, 4), LZMA_OK); + lzma_index *copy = lzma_index_dup(idx, NULL); + assert_true(copy != NULL); + assert_true(index_is_equal(idx, copy)); + lzma_index_end(copy, NULL); + + // Test for the bug fix 3bf857edfef51374f6f3fffae3d817f57d3264a0: + // liblzma: Fix a memory leak in error path of lzma_index_dup(). + // Use Valgrind to see that there are no leaks. + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, 10), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN * 2, 100), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK); + + assert_true(lzma_index_dup(idx, &test_index_dup_alloc) == NULL); + + // Test a few streams and blocks + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + assert_lzma_ret(lzma_index_stream_padding(second, 16), LZMA_OK); + + lzma_index *third = lzma_index_init(NULL); + assert_true(third != NULL); + + assert_lzma_ret(lzma_index_append(third, NULL, + UNPADDED_SIZE_MIN * 10, 40), LZMA_OK); + assert_lzma_ret(lzma_index_append(third, NULL, + UNPADDED_SIZE_MIN * 20, 400), LZMA_OK); + assert_lzma_ret(lzma_index_append(third, NULL, + UNPADDED_SIZE_MIN * 30, 4000), LZMA_OK); + + assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK); + assert_lzma_ret(lzma_index_cat(idx, third, NULL), LZMA_OK); + + copy = lzma_index_dup(idx, NULL); + assert_true(copy != NULL); + assert_true(index_is_equal(idx, copy)); + + lzma_index_end(copy, NULL); + lzma_index_end(idx, NULL); +} + + +#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS) +static void +verify_index_buffer(const lzma_index *idx, const uint8_t *buffer, + const size_t buffer_size) +{ + lzma_index_iter iter; + lzma_index_iter_init(&iter, idx); + + size_t buffer_pos = 0; + + // Verify Index Indicator + assert_uint_eq(buffer[buffer_pos++], 0); + + // Get Number of Records + lzma_vli number_of_records = 0; + lzma_vli block_count = 0; + assert_lzma_ret(lzma_vli_decode(&number_of_records, NULL, buffer, + &buffer_pos, buffer_size), LZMA_OK); + + while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)) { + // Verify each Record (Unpadded Size, then Uncompressed Size). + // Verify Unpadded Size. + lzma_vli unpadded_size, uncompressed_size; + assert_lzma_ret(lzma_vli_decode(&unpadded_size, + NULL, buffer, &buffer_pos, + buffer_size), LZMA_OK); + assert_uint_eq(unpadded_size, + iter.block.unpadded_size); + + // Verify Uncompressed Size + assert_lzma_ret(lzma_vli_decode(&uncompressed_size, + NULL, buffer, &buffer_pos, + buffer_size), LZMA_OK); + assert_uint_eq(uncompressed_size, + iter.block.uncompressed_size); + + block_count++; + } + + // Verify Number of Records + assert_uint_eq(number_of_records, block_count); + + // Verify Index Padding + for (; buffer_pos % 4 != 0; buffer_pos++) + assert_uint_eq(buffer[buffer_pos], 0); + + // Verify CRC32 + uint32_t crc32 = lzma_crc32(buffer, buffer_pos, 0); + assert_uint_eq(read32le(buffer + buffer_pos), crc32); +} + + +// In a few places the Index size is needed as a size_t but lzma_index_size() +// returns lzma_vli. +static size_t +get_index_size(const lzma_index *idx) +{ + const lzma_vli size = lzma_index_size(idx); + assert_uint(size, <, SIZE_MAX); + return (size_t)size; +} +#endif + + +static void +test_lzma_index_encoder(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + lzma_stream strm = LZMA_STREAM_INIT; + + // First do basic NULL checks + assert_lzma_ret(lzma_index_encoder(NULL, NULL), LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_encoder(&strm, NULL), LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_encoder(NULL, idx), LZMA_PROG_ERROR); + + // Append three small Blocks + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, 10), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN * 2, 100), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK); + + // Encode this lzma_index into a buffer + size_t buffer_size = get_index_size(idx); + uint8_t *buffer = tuktest_malloc(buffer_size); + + assert_lzma_ret(lzma_index_encoder(&strm, idx), LZMA_OK); + + strm.avail_out = buffer_size; + strm.next_out = buffer; + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + assert_uint_eq(strm.avail_out, 0); + + lzma_end(&strm); + + verify_index_buffer(idx, buffer, buffer_size); + + // Test with multiple Streams concatenated into 1 Index + lzma_index *second = lzma_index_init(NULL); + assert_true(second != NULL); + + // Include 1 Block + assert_lzma_ret(lzma_index_append(second, NULL, + UNPADDED_SIZE_MIN * 4, 20), LZMA_OK); + + // Include Stream Padding + assert_lzma_ret(lzma_index_stream_padding(second, 16), LZMA_OK); + + assert_lzma_ret(lzma_index_cat(idx, second, NULL), LZMA_OK); + buffer_size = get_index_size(idx); + buffer = tuktest_malloc(buffer_size); + assert_lzma_ret(lzma_index_encoder(&strm, idx), LZMA_OK); + + strm.avail_out = buffer_size; + strm.next_out = buffer; + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + assert_uint_eq(strm.avail_out, 0); + + verify_index_buffer(idx, buffer, buffer_size); + + lzma_index_end(idx, NULL); + lzma_end(&strm); +#endif +} + + +static void +generate_index_decode_buffer(void) +{ +#ifdef HAVE_ENCODERS + decode_test_index = lzma_index_init(NULL); + assert_true(decode_test_index != NULL); + + // Add 4 Blocks + for (uint32_t i = 1; i < 5; i++) + assert_lzma_ret(lzma_index_append(decode_test_index, NULL, + 0x1000 * i, 0x100 * i), LZMA_OK); + + const size_t size = (size_t)lzma_index_size(decode_test_index); + decode_buffer = tuktest_malloc(size); + + assert_lzma_ret(lzma_index_buffer_encode(decode_test_index, + decode_buffer, &decode_buffer_size, size), LZMA_OK); + assert_true(decode_buffer_size != 0); +#endif +} + + +#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS) +static void +decode_index(const uint8_t *buffer, const size_t size, lzma_stream *strm, + lzma_ret expected_error) +{ + strm->avail_in = size; + strm->next_in = buffer; + assert_lzma_ret(lzma_code(strm, LZMA_FINISH), expected_error); +} +#endif + + +static void +test_lzma_index_decoder(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + assert_true(decode_buffer_size != 0); + + lzma_stream strm = LZMA_STREAM_INIT; + + assert_lzma_ret(lzma_index_decoder(NULL, NULL, MEMLIMIT), + LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_decoder(&strm, NULL, MEMLIMIT), + LZMA_PROG_ERROR); + + // If the first argument (lzma_stream *strm) is NULL then + // *idx must still become NULL since the API docs say that + // it's done if an error occurs. This was fixed in + // 71eed2520e2eecae89bade9dceea16e56cfa2ea0. + lzma_index *idx_allocated = lzma_index_init(NULL); + lzma_index *idx = idx_allocated; + assert_lzma_ret(lzma_index_decoder(NULL, &idx, MEMLIMIT), + LZMA_PROG_ERROR); + assert_true(idx == NULL); + + lzma_index_end(idx_allocated, NULL); + idx_allocated = NULL; + + // Do actual decode + assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT), + LZMA_OK); + + decode_index(decode_buffer, decode_buffer_size, &strm, + LZMA_STREAM_END); + + // Compare results with expected + assert_true(index_is_equal(decode_test_index, idx)); + + lzma_index_end(idx, NULL); + + // Test again with too low memory limit + assert_lzma_ret(lzma_index_decoder(&strm, &idx, 0), LZMA_OK); + + decode_index(decode_buffer, decode_buffer_size, &strm, + LZMA_MEMLIMIT_ERROR); + + uint8_t *corrupt_buffer = tuktest_malloc(decode_buffer_size); + memcpy(corrupt_buffer, decode_buffer, decode_buffer_size); + + assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT), + LZMA_OK); + + // First corrupt the Index Indicator + corrupt_buffer[0] ^= 1; + decode_index(corrupt_buffer, decode_buffer_size, &strm, + LZMA_DATA_ERROR); + corrupt_buffer[0] ^= 1; + + // Corrupt something in the middle of Index + corrupt_buffer[decode_buffer_size / 2] ^= 1; + assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT), + LZMA_OK); + decode_index(corrupt_buffer, decode_buffer_size, &strm, + LZMA_DATA_ERROR); + corrupt_buffer[decode_buffer_size / 2] ^= 1; + + // Corrupt CRC32 + corrupt_buffer[decode_buffer_size - 1] ^= 1; + assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT), + LZMA_OK); + decode_index(corrupt_buffer, decode_buffer_size, &strm, + LZMA_DATA_ERROR); + corrupt_buffer[decode_buffer_size - 1] ^= 1; + + // Corrupt Index Padding by setting it to non-zero + corrupt_buffer[decode_buffer_size - 5] ^= 1; + assert_lzma_ret(lzma_index_decoder(&strm, &idx, MEMLIMIT), + LZMA_OK); + decode_index(corrupt_buffer, decode_buffer_size, &strm, + LZMA_DATA_ERROR); + corrupt_buffer[decode_buffer_size - 1] ^= 1; + + lzma_end(&strm); +#endif +} + + +static void +test_lzma_index_buffer_encode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + // These are simpler test than in test_lzma_index_encoder() + // because lzma_index_buffer_encode() is mostly a wrapper + // around lzma_index_encoder() anyway. + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN, 10), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN * 2, 100), LZMA_OK); + assert_lzma_ret(lzma_index_append(idx, NULL, + UNPADDED_SIZE_MIN * 3, 1000), LZMA_OK); + + size_t buffer_size = get_index_size(idx); + uint8_t *buffer = tuktest_malloc(buffer_size); + size_t out_pos = 1; + + // First test bad arguments + assert_lzma_ret(lzma_index_buffer_encode(NULL, NULL, NULL, 0), + LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_buffer_encode(idx, NULL, NULL, 0), + LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, NULL, 0), + LZMA_PROG_ERROR); + assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos, + 0), LZMA_PROG_ERROR); + out_pos = 0; + assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos, + 0), LZMA_BUF_ERROR); + assert_uint_eq(out_pos, 0); + assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos, + 1), LZMA_BUF_ERROR); + + // Do encoding + assert_lzma_ret(lzma_index_buffer_encode(idx, buffer, &out_pos, + buffer_size), LZMA_OK); + assert_uint_eq(out_pos, buffer_size); + + // Validate results + verify_index_buffer(idx, buffer, buffer_size); + + lzma_index_end(idx, NULL); +#endif +} + + +static void +test_lzma_index_buffer_decode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + assert_true(decode_buffer_size != 0); + + // Simple test since test_lzma_index_decoder() covers most of the + // lzma_index_buffer_decode() code anyway. + + // First test NULL checks + assert_lzma_ret(lzma_index_buffer_decode(NULL, NULL, NULL, NULL, + NULL, 0), LZMA_PROG_ERROR); + + uint64_t memlimit = MEMLIMIT; + size_t in_pos = 0; + lzma_index *idx_allocated = lzma_index_init(NULL); + lzma_index *idx = idx_allocated; + + assert_lzma_ret(lzma_index_buffer_decode(&idx, NULL, NULL, NULL, + NULL, 0), LZMA_PROG_ERROR); + assert_true(idx == NULL); + + idx = idx_allocated; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + NULL, NULL, 0), LZMA_PROG_ERROR); + assert_true(idx == NULL); + + idx = idx_allocated; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + decode_buffer, NULL, 0), LZMA_PROG_ERROR); + assert_true(idx == NULL); + + idx = idx_allocated; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + decode_buffer, NULL, 0), LZMA_PROG_ERROR); + assert_true(idx == NULL); + + idx = idx_allocated; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + decode_buffer, &in_pos, 0), LZMA_DATA_ERROR); + assert_true(idx == NULL); + + in_pos = 1; + idx = idx_allocated; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + decode_buffer, &in_pos, 0), LZMA_PROG_ERROR); + assert_true(idx == NULL); + + // Test too short input + in_pos = 0; + idx = idx_allocated; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + decode_buffer, &in_pos, decode_buffer_size - 1), + LZMA_DATA_ERROR); + assert_true(idx == NULL); + + lzma_index_end(idx_allocated, NULL); + idx_allocated = NULL; + + // Test expected successful decode + in_pos = 0; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + decode_buffer, &in_pos, decode_buffer_size), LZMA_OK); + + assert_uint_eq(in_pos, decode_buffer_size); + assert_true(index_is_equal(decode_test_index, idx)); + + lzma_index_end(idx, NULL); + + // Test too much input. This won't read past + // the end of the allocated array (decode_buffer_size bytes). + in_pos = 0; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + decode_buffer, &in_pos, decode_buffer_size + 16), + LZMA_OK); + + assert_uint_eq(in_pos, decode_buffer_size); + assert_true(index_is_equal(decode_test_index, idx)); + + lzma_index_end(idx, NULL); + + // Test too small memlimit + in_pos = 0; + memlimit = 1; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + decode_buffer, &in_pos, decode_buffer_size), + LZMA_MEMLIMIT_ERROR); + assert_uint(memlimit, >, 1); + assert_uint(memlimit, <, MEMLIMIT); +#endif +} + + +// With liblzma <= 5.8.2 (before the commit c8c22869e780), +// this triggers a buffer overflow in lzma_index_append(). +static void +test_decode_empty_and_append(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + uint8_t buf[256]; + lzma_index *idx = lzma_index_init(NULL); + assert_true(idx != NULL); + + // Encode an empty Index. + size_t buf_size = 0; + assert_lzma_ret(lzma_index_buffer_encode( + idx, buf, &buf_size, sizeof(buf)), LZMA_OK); + assert_true(buf_size > 0); + lzma_index_end(idx, NULL); + idx = NULL; + + // Decode the empty Index. + uint64_t memlimit = MEMLIMIT; + size_t buf_pos = 0; + assert_lzma_ret(lzma_index_buffer_decode(&idx, &memlimit, NULL, + buf, &buf_pos, buf_size), LZMA_OK); + assert_uint_eq(buf_pos, buf_size); + + // Append one Record to the decoded empty idx. + assert_lzma_ret(lzma_index_append(idx, NULL, 55, 1), LZMA_OK); + lzma_index_end(idx, NULL); +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + generate_index_decode_buffer(); + tuktest_run(test_lzma_index_memusage); + tuktest_run(test_lzma_index_memused); + tuktest_run(test_lzma_index_append); + tuktest_run(test_lzma_index_stream_flags); + tuktest_run(test_lzma_index_checks); + tuktest_run(test_lzma_index_stream_padding); + tuktest_run(test_lzma_index_stream_count); + tuktest_run(test_lzma_index_block_count); + tuktest_run(test_lzma_index_size); + tuktest_run(test_lzma_index_stream_size); + tuktest_run(test_lzma_index_total_size); + tuktest_run(test_lzma_index_file_size); + tuktest_run(test_lzma_index_uncompressed_size); + tuktest_run(test_lzma_index_iter_init); + tuktest_run(test_lzma_index_iter_rewind); + tuktest_run(test_lzma_index_iter_next); + tuktest_run(test_lzma_index_iter_locate); + tuktest_run(test_lzma_index_cat); + tuktest_run(test_lzma_index_dup); + tuktest_run(test_lzma_index_encoder); + tuktest_run(test_lzma_index_decoder); + tuktest_run(test_lzma_index_buffer_encode); + tuktest_run(test_lzma_index_buffer_decode); + tuktest_run(test_decode_empty_and_append); + lzma_index_end(decode_test_index, NULL); + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_index_hash.c b/cpp/third_party/xz-5.8.3/tests/test_index_hash.c new file mode 100644 index 000000000..842d5348b --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_index_hash.c @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_index_hash.c +/// \brief Tests src/liblzma/common/index_hash.c API functions +/// +/// \note No test included for lzma_index_hash_end since it +/// would be trivial unless tested for memory leaks +/// with something like valgrind +// +// Author: Jia Tan +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + +// Needed for UNPADDED_SIZE_MIN and UNPADDED_SIZE_MAX macro definitions +// and index_size and vli_ceil4 helper functions +#include "common/index.h" + + +static void +test_lzma_index_hash_init(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + // First test with NULL index_hash. + // This should create a fresh index_hash. + lzma_index_hash *index_hash = lzma_index_hash_init(NULL, NULL); + assert_true(index_hash != NULL); + + // Next test with non-NULL index_hash. + lzma_index_hash *second_hash = lzma_index_hash_init(index_hash, NULL); + + // It should not create a new index_hash pointer. + // Instead it must just re-init the first index_hash. + assert_true(index_hash == second_hash); + + lzma_index_hash_end(index_hash, NULL); +#endif +} + + +static void +test_lzma_index_hash_append(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + // Test all invalid parameters + assert_lzma_ret(lzma_index_hash_append(NULL, 0, 0), + LZMA_PROG_ERROR); + + // Test NULL index_hash + assert_lzma_ret(lzma_index_hash_append(NULL, UNPADDED_SIZE_MIN, + LZMA_VLI_MAX), LZMA_PROG_ERROR); + + // Test with invalid Unpadded Size + lzma_index_hash *index_hash = lzma_index_hash_init(NULL, NULL); + assert_true(index_hash != NULL); + assert_lzma_ret(lzma_index_hash_append(index_hash, + UNPADDED_SIZE_MIN - 1, LZMA_VLI_MAX), + LZMA_PROG_ERROR); + + // Test with invalid Uncompressed Size + assert_lzma_ret(lzma_index_hash_append(index_hash, + UNPADDED_SIZE_MIN, LZMA_VLI_MAX + 1), + LZMA_PROG_ERROR); + + // First append a Record describing a small Block. + // This should succeed. + assert_lzma_ret(lzma_index_hash_append(index_hash, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + + // Append another small Record. + assert_lzma_ret(lzma_index_hash_append(index_hash, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + + // Append a Record that would cause the compressed size to grow + // too big + assert_lzma_ret(lzma_index_hash_append(index_hash, + UNPADDED_SIZE_MAX, 1), LZMA_DATA_ERROR); + + lzma_index_hash_end(index_hash, NULL); +#endif +} + + +#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS) +// Fill an index_hash with unpadded and uncompressed VLIs +// by calling lzma_index_hash_append +static void +fill_index_hash(lzma_index_hash *index_hash, const lzma_vli *unpadded_sizes, + const lzma_vli *uncomp_sizes, uint32_t block_count) +{ + for (uint32_t i = 0; i < block_count; ++i) + assert_lzma_ret(lzma_index_hash_append(index_hash, + unpadded_sizes[i], uncomp_sizes[i]), LZMA_OK); +} + + +// Set the contents of buf to the expected Index based on the +// .xz specification. This needs the unpadded and uncompressed VLIs +// to correctly create the Index. +static void +generate_index(uint8_t *buf, const lzma_vli *unpadded_sizes, + const lzma_vli *uncomp_sizes, uint32_t block_count, + size_t index_max_size) +{ + size_t in_pos = 0; + size_t out_pos = 0; + + // First set Index Indicator + buf[out_pos++] = INDEX_INDICATOR; + + // Next write out Number of Records + assert_lzma_ret(lzma_vli_encode(block_count, &in_pos, buf, + &out_pos, index_max_size), LZMA_STREAM_END); + + // Next write out each Record. + // A Record consists of Unpadded Size and Uncompressed Size + // written next to each other as VLIs. + for (uint32_t i = 0; i < block_count; ++i) { + in_pos = 0; + assert_lzma_ret(lzma_vli_encode(unpadded_sizes[i], &in_pos, + buf, &out_pos, index_max_size), LZMA_STREAM_END); + in_pos = 0; + assert_lzma_ret(lzma_vli_encode(uncomp_sizes[i], &in_pos, + buf, &out_pos, index_max_size), LZMA_STREAM_END); + } + + // Add Index Padding + lzma_vli rounded_out_pos = vli_ceil4(out_pos); + memzero(buf + out_pos, rounded_out_pos - out_pos); + out_pos = rounded_out_pos; + + // Add the CRC32 + write32le(buf + out_pos, lzma_crc32(buf, out_pos, 0)); + out_pos += 4; + + assert_uint_eq(out_pos, index_max_size); +} +#endif + + +static void +test_lzma_index_hash_decode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + lzma_index_hash *index_hash = lzma_index_hash_init(NULL, NULL); + assert_true(index_hash != NULL); + + size_t in_pos = 0; + + // Six valid values for the Unpadded Size fields in an Index + const lzma_vli unpadded_sizes[6] = { + UNPADDED_SIZE_MIN, + 1000, + 4000, + 8000, + 16000, + 32000 + }; + + // Six valid values for the Uncompressed Size fields in an Index + const lzma_vli uncomp_sizes[6] = { + 1, + 500, + 8000, + 20, + 1, + 500 + }; + + // Add two Records to an index_hash + fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 2); + + const lzma_vli size_two_records = lzma_index_hash_size(index_hash); + assert_uint(size_two_records, >, 0); + uint8_t *index_two_records = tuktest_malloc(size_two_records); + + generate_index(index_two_records, unpadded_sizes, uncomp_sizes, 2, + size_two_records); + + // First test for basic buffer size error + in_pos = size_two_records + 1; + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_two_records, &in_pos, + size_two_records), LZMA_BUF_ERROR); + + // Next test for invalid Index Indicator + in_pos = 0; + index_two_records[0] ^= 1; + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_two_records, &in_pos, + size_two_records), LZMA_DATA_ERROR); + index_two_records[0] ^= 1; + + // Next verify the index_hash as expected + in_pos = 0; + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_two_records, &in_pos, + size_two_records), LZMA_STREAM_END); + + // Next test an index_hash with three Records + index_hash = lzma_index_hash_init(index_hash, NULL); + fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 3); + + const lzma_vli size_three_records = lzma_index_hash_size( + index_hash); + assert_uint(size_three_records, >, 0); + uint8_t *index_three_records = tuktest_malloc(size_three_records); + + generate_index(index_three_records, unpadded_sizes, uncomp_sizes, + 3, size_three_records); + + in_pos = 0; + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_three_records, &in_pos, + size_three_records), LZMA_STREAM_END); + + // Next test an index_hash with five Records + index_hash = lzma_index_hash_init(index_hash, NULL); + fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 5); + + const lzma_vli size_five_records = lzma_index_hash_size( + index_hash); + assert_uint(size_five_records, >, 0); + uint8_t *index_five_records = tuktest_malloc(size_five_records); + + generate_index(index_five_records, unpadded_sizes, uncomp_sizes, 5, + size_five_records); + + // Instead of testing all input at once, give input + // one byte at a time + in_pos = 0; + for (lzma_vli i = 0; i < size_five_records - 1; ++i) { + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_five_records, &in_pos, in_pos + 1), + LZMA_OK); + } + + // Last byte should return LZMA_STREAM_END + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_five_records, &in_pos, + in_pos + 1), LZMA_STREAM_END); + + // Next test if the index_hash is given an incorrect Unpadded + // Size. Should detect and report LZMA_DATA_ERROR + index_hash = lzma_index_hash_init(index_hash, NULL); + fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 5); + // The sixth Record will have an invalid Unpadded Size + assert_lzma_ret(lzma_index_hash_append(index_hash, + unpadded_sizes[5] + 1, + uncomp_sizes[5]), LZMA_OK); + + const lzma_vli size_six_records = lzma_index_hash_size( + index_hash); + + assert_uint(size_six_records, >, 0); + uint8_t *index_six_records = tuktest_malloc(size_six_records); + + generate_index(index_six_records, unpadded_sizes, uncomp_sizes, 6, + size_six_records); + in_pos = 0; + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_six_records, &in_pos, + size_six_records), LZMA_DATA_ERROR); + + // Next test if the Index is corrupt (invalid CRC32). + // Should detect and report LZMA_DATA_ERROR + index_hash = lzma_index_hash_init(index_hash, NULL); + fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 2); + + index_two_records[size_two_records - 1] ^= 1; + + in_pos = 0; + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_two_records, &in_pos, + size_two_records), LZMA_DATA_ERROR); + + // Next test with Index and index_hash struct not matching + // a Record + index_hash = lzma_index_hash_init(index_hash, NULL); + fill_index_hash(index_hash, unpadded_sizes, uncomp_sizes, 2); + // Recalculate Index with invalid Unpadded Size + const lzma_vli unpadded_sizes_invalid[2] = { + unpadded_sizes[0], + unpadded_sizes[1] + 1 + }; + + generate_index(index_two_records, unpadded_sizes_invalid, + uncomp_sizes, 2, size_two_records); + + in_pos = 0; + assert_lzma_ret(lzma_index_hash_decode(index_hash, + index_two_records, &in_pos, + size_two_records), LZMA_DATA_ERROR); + + lzma_index_hash_end(index_hash, NULL); +#endif +} + + +static void +test_lzma_index_hash_size(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + lzma_index_hash *index_hash = lzma_index_hash_init(NULL, NULL); + assert_true(index_hash != NULL); + + // First test empty index_hash + // Expected size should be: + // Index Indicator - 1 byte + // Number of Records - 1 byte + // List of Records - 0 bytes + // Index Padding - 2 bytes + // CRC32 - 4 bytes + // Total - 8 bytes + assert_uint_eq(lzma_index_hash_size(index_hash), 8); + + // Append a Record describing a small Block to the index_hash + assert_lzma_ret(lzma_index_hash_append(index_hash, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + + // Expected size should be: + // Index Indicator - 1 byte + // Number of Records - 1 byte + // List of Records - 2 bytes + // Index Padding - 0 bytes + // CRC32 - 4 bytes + // Total - 8 bytes + lzma_vli expected_size = 8; + assert_uint_eq(lzma_index_hash_size(index_hash), expected_size); + + // Append additional small Record + assert_lzma_ret(lzma_index_hash_append(index_hash, + UNPADDED_SIZE_MIN, 1), LZMA_OK); + + // Expected size should be: + // Index Indicator - 1 byte + // Number of Records - 1 byte + // List of Records - 4 bytes + // Index Padding - 2 bytes + // CRC32 - 4 bytes + // Total - 12 bytes + expected_size = 12; + assert_uint_eq(lzma_index_hash_size(index_hash), expected_size); + + // Append a larger Record to the index_hash (3 bytes for each VLI) + const lzma_vli three_byte_vli = 0x10000; + assert_lzma_ret(lzma_index_hash_append(index_hash, + three_byte_vli, three_byte_vli), LZMA_OK); + + // Expected size should be: + // Index Indicator - 1 byte + // Number of Records - 1 byte + // List of Records - 10 bytes + // Index Padding - 0 bytes + // CRC32 - 4 bytes + // Total - 16 bytes + expected_size = 16; + assert_uint_eq(lzma_index_hash_size(index_hash), expected_size); + + lzma_index_hash_end(index_hash, NULL); +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + tuktest_run(test_lzma_index_hash_init); + tuktest_run(test_lzma_index_hash_append); + tuktest_run(test_lzma_index_hash_decode); + tuktest_run(test_lzma_index_hash_size); + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_lzip_decoder.c b/cpp/third_party/xz-5.8.3/tests/test_lzip_decoder.c new file mode 100644 index 000000000..cee97b86d --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_lzip_decoder.c @@ -0,0 +1,475 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_lzip_decoder.c +/// \brief Tests decoding lzip data +// +// Author: Jia Tan +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + +#ifdef HAVE_LZIP_DECODER + +// Memlimit large enough to pass all of the test files +#define MEMLIMIT (1U << 20) +#define DECODE_CHUNK_SIZE 1024 + + +// The uncompressed data in the test files are short US-ASCII strings. +// The tests check if the decompressed output is what it is expected to be. +// Storing the strings here as text would break the tests on EBCDIC systems +// and storing the strings as an array of hex values is inconvenient, so +// store the CRC32 values of the expected data instead. +// +// CRC32 value of "Hello\nWorld\n" +static const uint32_t hello_world_crc = 0x15A2A343; + +// CRC32 value of "Trailing garbage\n" +static const uint32_t trailing_garbage_crc = 0x87081A60; + + +// Helper function to decode a good file with no flags and plenty high memlimit +static void +basic_lzip_decode(const char *src, const uint32_t expected_crc) +{ + size_t file_size; + uint8_t *data = tuktest_file_from_srcdir(src, &file_size); + uint32_t checksum = 0; + + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, 0), LZMA_OK); + + uint8_t output_buffer[DECODE_CHUNK_SIZE]; + + strm.next_in = data; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + // Feed 1 byte at a time to the decoder to look for any bugs + // when switching between decoding sequences + lzma_ret ret = LZMA_OK; + while (ret == LZMA_OK) { + strm.avail_in = 1; + ret = lzma_code(&strm, LZMA_RUN); + if (strm.avail_out == 0) { + checksum = lzma_crc32(output_buffer, + (size_t)(strm.next_out - output_buffer), + checksum); + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + } + } + + assert_lzma_ret(ret, LZMA_STREAM_END); + assert_uint_eq(strm.total_in, file_size); + + checksum = lzma_crc32(output_buffer, + (size_t)(strm.next_out - output_buffer), + checksum); + assert_uint_eq(checksum, expected_crc); + + lzma_end(&strm); +} + + +static void +test_options(void) +{ + // Test NULL stream + assert_lzma_ret(lzma_lzip_decoder(NULL, MEMLIMIT, 0), + LZMA_PROG_ERROR); + + // Test invalid flags + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, UINT32_MAX), + LZMA_OPTIONS_ERROR); + // Memlimit tests are done elsewhere +} + + +static void +test_v0_decode(void) +{ + // This tests if liblzma can decode lzip version 0 files. + // lzip 1.17 and older can decompress this, but lzip 1.18 + // and newer can no longer decode these files. + basic_lzip_decode("files/good-1-v0.lz", hello_world_crc); +} + + +static void +test_v1_decode(void) +{ + // This tests decoding a basic lzip v1 file + basic_lzip_decode("files/good-1-v1.lz", hello_world_crc); +} + + +// Helper function to decode a good file with trailing bytes after +// the lzip stream +static void +trailing_helper(const char *src, const uint32_t expected_data_checksum, + const uint32_t expected_trailing_checksum) +{ + size_t file_size; + uint32_t checksum = 0; + uint8_t *data = tuktest_file_from_srcdir(src, &file_size); + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, + LZMA_CONCATENATED), LZMA_OK); + + uint8_t output_buffer[DECODE_CHUNK_SIZE]; + + strm.next_in = data; + strm.avail_in = file_size; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + lzma_ret ret = LZMA_OK; + while (ret == LZMA_OK) { + ret = lzma_code(&strm, LZMA_RUN); + if (strm.avail_out == 0) { + checksum = lzma_crc32(output_buffer, + (size_t)(strm.next_out - output_buffer), + checksum); + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + } + } + + assert_lzma_ret(ret, LZMA_STREAM_END); + assert_uint(strm.total_in, <, file_size); + + checksum = lzma_crc32(output_buffer, + (size_t)(strm.next_out - output_buffer), + checksum); + + assert_uint_eq(checksum, expected_data_checksum); + + // Trailing data should be readable from strm.next_in + checksum = lzma_crc32(strm.next_in, strm.avail_in, 0); + assert_uint_eq(checksum, expected_trailing_checksum); + + lzma_end(&strm); +} + + +// Helper function to decode a bad file and compare to returned error to +// what the caller expects +static void +decode_expect_error(const char *src, lzma_ret expected_error) +{ + lzma_stream strm = LZMA_STREAM_INIT; + size_t file_size; + uint8_t *data = tuktest_file_from_srcdir(src, &file_size); + + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, + LZMA_CONCATENATED), LZMA_OK); + + uint8_t output_buffer[DECODE_CHUNK_SIZE]; + + strm.avail_in = file_size; + strm.next_in = data; + + lzma_ret ret = LZMA_OK; + + do { + // Discard output since we are only looking for errors + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + if (strm.avail_in == 0) + ret = lzma_code(&strm, LZMA_FINISH); + else + ret = lzma_code(&strm, LZMA_RUN); + } while (ret == LZMA_OK); + + assert_lzma_ret(ret, expected_error); + lzma_end(&strm); +} + + +static void +test_v0_trailing(void) +{ + trailing_helper("files/good-1-v0-trailing-1.lz", hello_world_crc, + trailing_garbage_crc); +} + + +static void +test_v1_trailing(void) +{ + trailing_helper("files/good-1-v1-trailing-1.lz", hello_world_crc, + trailing_garbage_crc); + + // The second files/good-1-v1-trailing-2.lz will have the same + // expected output and trailing output as + // files/good-1-v1-trailing-1.lz, but this tests if the prefix + // to the trailing data contains lzip magic bytes. + // When this happens, the expected behavior is to silently ignore + // the magic byte prefix and consume it from the input file. + trailing_helper("files/good-1-v1-trailing-2.lz", hello_world_crc, + trailing_garbage_crc); + + // Expect LZMA_BUF error if a file ends with the lzip magic bytes + // but does not contain any data after + decode_expect_error("files/bad-1-v1-trailing-magic.lz", + LZMA_BUF_ERROR); +} + + +static void +test_concatenated(void) +{ + // First test a file with one v0 member and one v1 member + // The first member should contain "Hello\n" and + // the second member should contain "World!\n" + lzma_stream strm = LZMA_STREAM_INIT; + size_t file_size; + uint8_t *v0_v1 = tuktest_file_from_srcdir("files/good-2-v0-v1.lz", + &file_size); + + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, + LZMA_CONCATENATED), LZMA_OK); + + uint8_t output_buffer[DECODE_CHUNK_SIZE]; + + strm.next_in = v0_v1; + strm.avail_in = file_size; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + + assert_uint_eq(strm.total_in, file_size); + + uint32_t checksum = lzma_crc32(output_buffer, strm.total_out, 0); + assert_uint_eq(checksum, hello_world_crc); + + // The second file contains one v1 member and one v2 member + uint8_t *v1_v0 = tuktest_file_from_srcdir("files/good-2-v1-v0.lz", + &file_size); + + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, + LZMA_CONCATENATED), LZMA_OK); + + strm.next_in = v1_v0; + strm.avail_in = file_size; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + + assert_uint_eq(strm.total_in, file_size); + checksum = lzma_crc32(output_buffer, strm.total_out, 0); + assert_uint_eq(checksum, hello_world_crc); + + // The third file contains 2 v1 members + uint8_t *v1_v1 = tuktest_file_from_srcdir("files/good-2-v1-v1.lz", + &file_size); + + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, + LZMA_CONCATENATED), LZMA_OK); + + strm.next_in = v1_v1; + strm.avail_in = file_size; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + + assert_uint_eq(strm.total_in, file_size); + checksum = lzma_crc32(output_buffer, strm.total_out, 0); + assert_uint_eq(checksum, hello_world_crc); + + lzma_end(&strm); +} + + +static void +test_crc(void) +{ + // Test invalid checksum + lzma_stream strm = LZMA_STREAM_INIT; + size_t file_size; + uint8_t *data = tuktest_file_from_srcdir("files/bad-1-v1-crc32.lz", + &file_size); + + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, + LZMA_CONCATENATED), LZMA_OK); + + uint8_t output_buffer[DECODE_CHUNK_SIZE]; + + strm.next_in = data; + strm.avail_in = file_size; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_DATA_ERROR); + + // Test ignoring the checksum value - should decode successfully + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, + LZMA_CONCATENATED | LZMA_IGNORE_CHECK), LZMA_OK); + + strm.next_in = data; + strm.avail_in = file_size; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + assert_uint_eq(strm.total_in, file_size); + + // Test tell check + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, + LZMA_CONCATENATED | LZMA_TELL_ANY_CHECK), LZMA_OK); + + strm.next_in = data; + strm.avail_in = file_size; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_GET_CHECK); + assert_uint_eq(lzma_get_check(&strm), LZMA_CHECK_CRC32); + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_DATA_ERROR); + lzma_end(&strm); +} + + +static void +test_invalid_magic_bytes(void) +{ + uint8_t lzip_id_string[] = { 0x4C, 0x5A, 0x49, 0x50 }; + lzma_stream strm = LZMA_STREAM_INIT; + + for (uint32_t i = 0; i < ARRAY_SIZE(lzip_id_string); i++) { + // Corrupt magic bytes + lzip_id_string[i] ^= 1; + uint8_t output_buffer[DECODE_CHUNK_SIZE]; + + assert_lzma_ret(lzma_lzip_decoder(&strm, MEMLIMIT, 0), + LZMA_OK); + + strm.next_in = lzip_id_string; + strm.avail_in = sizeof(lzip_id_string); + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), + LZMA_FORMAT_ERROR); + + // Reset magic bytes + lzip_id_string[i] ^= 1; + } + + lzma_end(&strm); +} + + +static void +test_invalid_version(void) +{ + // The file contains a version number that is not 0 or 1, + // so it should cause an error + decode_expect_error("files/unsupported-1-v234.lz", + LZMA_OPTIONS_ERROR); +} + + +static void +test_invalid_dictionary_size(void) +{ + // The first file has a too small dictionary size field. + decode_expect_error("files/bad-1-v1-dict-1.lz", LZMA_DATA_ERROR); + + // The second file has a too large dictionary size field. + decode_expect_error("files/bad-1-v1-dict-2.lz", LZMA_DATA_ERROR); +} + + +static void +test_invalid_uncomp_size(void) +{ + // Test invalid v0 lzip file uncomp size + decode_expect_error("files/bad-1-v0-uncomp-size.lz", + LZMA_DATA_ERROR); + + // Test invalid v1 lzip file uncomp size + decode_expect_error("files/bad-1-v1-uncomp-size.lz", + LZMA_DATA_ERROR); +} + + +static void +test_invalid_member_size(void) +{ + decode_expect_error("files/bad-1-v1-member-size.lz", + LZMA_DATA_ERROR); +} + + +static void +test_invalid_memlimit(void) +{ + // A very low memlimit should prevent decoding. + // It should be possible to update the memlimit after the error. + size_t file_size; + uint8_t *data = tuktest_file_from_srcdir("files/good-1-v1.lz", + &file_size); + + uint8_t output_buffer[DECODE_CHUNK_SIZE]; + + lzma_stream strm = LZMA_STREAM_INIT; + + assert_lzma_ret(lzma_lzip_decoder(&strm, 1, 0), LZMA_OK); + + strm.next_in = data; + strm.avail_in = file_size; + strm.next_out = output_buffer; + strm.avail_out = sizeof(output_buffer); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); + + // Up the memlimit so that decoding can continue. + // First only increase by a small amount and expect an error. + assert_lzma_ret(lzma_memlimit_set(&strm, 100), LZMA_MEMLIMIT_ERROR); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT), LZMA_OK); + + // Finish decoding + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + + assert_uint_eq(strm.total_in, file_size); + uint32_t checksum = lzma_crc32(output_buffer, strm.total_out, 0); + assert_uint_eq(checksum, hello_world_crc); + + lzma_end(&strm); +} +#endif + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + +#ifndef HAVE_LZIP_DECODER + tuktest_early_skip("lzip decoder disabled"); +#else + tuktest_run(test_options); + tuktest_run(test_v0_decode); + tuktest_run(test_v1_decode); + tuktest_run(test_v0_trailing); + tuktest_run(test_v1_trailing); + tuktest_run(test_concatenated); + tuktest_run(test_crc); + tuktest_run(test_invalid_magic_bytes); + tuktest_run(test_invalid_version); + tuktest_run(test_invalid_dictionary_size); + tuktest_run(test_invalid_uncomp_size); + tuktest_run(test_invalid_member_size); + tuktest_run(test_invalid_memlimit); + return tuktest_end(); +#endif +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_memlimit.c b/cpp/third_party/xz-5.8.3/tests/test_memlimit.c new file mode 100644 index 000000000..7e8f86208 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_memlimit.c @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_memlimit.c +/// \brief Tests memory usage limit in decoders +// +// Author: Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" +#include "mythread.h" + + +#define MEMLIMIT_TOO_LOW 1234U +#define MEMLIMIT_HIGH_ENOUGH (2U << 20) + + +static uint8_t *in; +static size_t in_size; + +#ifdef HAVE_DECODERS +static uint8_t out[8192]; +#endif + + +static void +test_memlimit_stream_decoder(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_stream_decoder(&strm, MEMLIMIT_TOO_LOW, 0), + LZMA_OK); + + strm.next_in = in; + strm.avail_in = in_size; + strm.next_out = out; + strm.avail_out = sizeof(out); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); + + assert_uint_eq(lzma_memlimit_get(&strm), MEMLIMIT_TOO_LOW); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_TOO_LOW + 1), + LZMA_MEMLIMIT_ERROR); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_HIGH_ENOUGH), + LZMA_OK); + + // This fails before commit 660739f99ab211edec4071de98889fb32ed04e98 + // (liblzma <= 5.2.6, liblzma <= 5.3.3alpha). It was fixed in 5.2.7. + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + + lzma_end(&strm); +#endif +} + + +static void +test_memlimit_stream_decoder_mt(void) +{ +#ifndef MYTHREAD_ENABLED + assert_skip("Threading support disabled"); +#elif !defined(HAVE_DECODERS) + assert_skip("Decoder support disabled"); +#else + lzma_stream strm = LZMA_STREAM_INIT; + lzma_mt mt = { + .flags = 0, + .threads = 1, + .timeout = 0, + .memlimit_threading = 0, + .memlimit_stop = MEMLIMIT_TOO_LOW, + }; + + assert_lzma_ret(lzma_stream_decoder_mt(&strm, &mt), LZMA_OK); + + strm.next_in = in; + strm.avail_in = in_size; + strm.next_out = out; + strm.avail_out = sizeof(out); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); + + assert_uint_eq(lzma_memlimit_get(&strm), MEMLIMIT_TOO_LOW); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_TOO_LOW + 1), + LZMA_MEMLIMIT_ERROR); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_HIGH_ENOUGH), + LZMA_OK); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + lzma_end(&strm); +#endif +} + + +static void +test_memlimit_alone_decoder(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + size_t alone_size; + uint8_t *alone_buf = tuktest_file_from_srcdir( + "files/good-unknown_size-with_eopm.lzma", &alone_size); + + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_alone_decoder(&strm, MEMLIMIT_TOO_LOW), LZMA_OK); + + strm.next_in = alone_buf; + strm.avail_in = alone_size; + strm.next_out = out; + strm.avail_out = sizeof(out); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); + + assert_uint_eq(lzma_memlimit_get(&strm), MEMLIMIT_TOO_LOW); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_TOO_LOW + 1), + LZMA_MEMLIMIT_ERROR); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_HIGH_ENOUGH), + LZMA_OK); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + lzma_end(&strm); +#endif +} + + +static void +test_memlimit_auto_decoder(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_auto_decoder(&strm, MEMLIMIT_TOO_LOW, 0), + LZMA_OK); + + strm.next_in = in; + strm.avail_in = in_size; + strm.next_out = out; + strm.avail_out = sizeof(out); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); + + assert_uint_eq(lzma_memlimit_get(&strm), MEMLIMIT_TOO_LOW); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_TOO_LOW + 1), + LZMA_MEMLIMIT_ERROR); + assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_HIGH_ENOUGH), + LZMA_OK); + + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + lzma_end(&strm); +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + + in = tuktest_file_from_srcdir("files/good-1-check-crc32.xz", &in_size); + + tuktest_run(test_memlimit_stream_decoder); + tuktest_run(test_memlimit_stream_decoder_mt); + tuktest_run(test_memlimit_alone_decoder); + tuktest_run(test_memlimit_auto_decoder); + + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_microlzma.c b/cpp/third_party/xz-5.8.3/tests/test_microlzma.c new file mode 100644 index 000000000..c1d99d77f --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_microlzma.c @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_microlzma.c +/// \brief Tests MicroLZMA encoding and decoding +// +// Author: Jia Tan +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + +#define BUFFER_SIZE 1024 + + +#ifdef HAVE_ENCODER_LZMA1 + +// MicroLZMA encoded "Hello\nWorld\n" output size in bytes. +#define ENCODED_OUTPUT_SIZE 17 + +// Byte array of "Hello\nWorld\n". This is used for various encoder tests. +static const uint8_t hello_world[] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, + 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x0A }; + +// This is the CRC32 value of the MicroLZMA encoding of "Hello\nWorld\n". +// The settings used were based on LZMA_PRESET_DEFAULT as of liblzma 5.6.0. +// This assumes MicroLZMA is correct in liblzma 5.6.0, which is safe +// considering the encoded "Hello\nWorld\n" can successfully be decoded at +// this time. This is to test for regressions that cause MicroLZMA output +// to change. +static const uint32_t hello_world_encoded_crc = 0x3CDE40A8; + + +// Function implementation borrowed from lzma_decoder.c. It is needed to +// ensure the first byte of a MicroLZMA stream is set correctly with the +// negation of the LZMA properties. +static bool +lzma_lzma_lclppb_decode(lzma_options_lzma *options, uint8_t byte) +{ + if (byte > (4 * 5 + 4) * 9 + 8) + return true; + + // See the file format specification to understand this. + options->pb = byte / (9 * 5); + byte -= options->pb * 9 * 5; + options->lp = byte / 9; + options->lc = byte - options->lp * 9; + + return options->lc + options->lp > LZMA_LCLP_MAX; +} + + +/////////////////// +// Encoder tests // +/////////////////// + +// This tests a few of the basic options. These options are not unique to +// MicroLZMA in any way, its mostly ensuring that the options are actually +// being checked before initializing the decoder internals. +static void +test_encode_options(void) +{ + lzma_stream strm = LZMA_STREAM_INIT; + lzma_options_lzma opt_lzma; + + // Initialize with default options. + assert_false(lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT)); + + // NULL stream + assert_lzma_ret(lzma_microlzma_encoder(NULL, &opt_lzma), + LZMA_PROG_ERROR); + + // lc/lp/pb = 5/0/2 (lc invalid) + opt_lzma.lc = 5; + opt_lzma.lp = 0; + opt_lzma.pb = 2; + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), + LZMA_OPTIONS_ERROR); + + // lc/lp/pb = 0/5/2 (lp invalid) + opt_lzma.lc = 0; + opt_lzma.lp = 5; + opt_lzma.pb = 2; + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), + LZMA_OPTIONS_ERROR); + + // lc/lp/pb = 3/2/2 (lc + lp invalid) + opt_lzma.lc = 3; + opt_lzma.lp = 2; + opt_lzma.pb = 2; + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), + LZMA_OPTIONS_ERROR); + + // lc/lp/pb = 3/0/5 (pb invalid) + opt_lzma.lc = 3; + opt_lzma.lp = 0; + opt_lzma.pb = 5; + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), + LZMA_OPTIONS_ERROR); + + // Zero out lp, pb, lc options to not interfere with later tests. + opt_lzma.lp = 0; + opt_lzma.pb = 0; + opt_lzma.lc = 0; + + // Set invalid dictionary size. + opt_lzma.dict_size = LZMA_DICT_SIZE_MIN - 1; + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), + LZMA_OPTIONS_ERROR); + + // Maximum dictionary size for the encoder, as described in lzma12.h + // is 1.5 GiB. + opt_lzma.dict_size = (UINT32_C(1) << 30) + (UINT32_C(1) << 29) + 1; + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), + LZMA_OPTIONS_ERROR); + + lzma_end(&strm); +} + + +static void +test_encode_basic(void) +{ + lzma_stream strm = LZMA_STREAM_INIT; + lzma_options_lzma opt_lzma; + + // The lzma_lzma_preset return value is inverse of what it perhaps + // should be, that is, it returns false on success. + assert_false(lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT)); + + // Initialize the encoder using the default options. + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), LZMA_OK); + + uint8_t output[BUFFER_SIZE]; + + strm.next_in = hello_world; + strm.avail_in = sizeof(hello_world); + strm.next_out = output; + strm.avail_out = sizeof(output); + + // Everything must be encoded in one lzma_code() call. + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + + // Check that the entire input was consumed. + assert_uint_eq(strm.total_in, sizeof(hello_world)); + + // Check that the first byte in the output stream is not 0x00. + // In a regular raw LZMA stream the first byte is always 0x00. + // In MicroLZMA the first byte replaced by the bitwise-negation + // of the LZMA properties. + assert_uint(output[0], !=, 0x00); + + const uint8_t props = ~output[0]; + + lzma_options_lzma test_options; + assert_false(lzma_lzma_lclppb_decode(&test_options, props)); + + assert_uint_eq(opt_lzma.lc, test_options.lc); + assert_uint_eq(opt_lzma.lp, test_options.lp); + assert_uint_eq(opt_lzma.pb, test_options.pb); + + // Compute the check over the output data. This is compared to + // the expected check value. + const uint32_t check_val = lzma_crc32(output, strm.total_out, 0); + + assert_uint_eq(check_val, hello_world_encoded_crc); + + lzma_end(&strm); +} + + +// This tests the behavior when strm.avail_out is so small it cannot hold +// the header plus 1 encoded byte (< 6). +static void +test_encode_small_out(void) +{ + lzma_stream strm = LZMA_STREAM_INIT; + lzma_options_lzma opt_lzma; + + assert_false(lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT)); + + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), LZMA_OK); + + uint8_t output[BUFFER_SIZE]; + + strm.next_in = hello_world; + strm.avail_in = sizeof(hello_world); + strm.next_out = output; + strm.avail_out = 5; + + // LZMA_PROG_ERROR is expected when strm.avail_out < 6 + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_PROG_ERROR); + + // The encoder must be reset because coders cannot be used again + // after returning LZMA_PROG_ERROR. + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), LZMA_OK); + + // Reset strm.avail_out to be > 6, but not enough to hold all of the + // compressed data. + strm.avail_out = ENCODED_OUTPUT_SIZE - 1; + + // Encoding should not return an error now. + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + assert_uint(strm.total_in, <, sizeof(hello_world)); + + lzma_end(&strm); +} + + +// LZMA_FINISH is the only supported action. All others must +// return LZMA_PROG_ERROR. +static void +test_encode_actions(void) +{ + lzma_stream strm = LZMA_STREAM_INIT; + lzma_options_lzma opt_lzma; + + assert_false(lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT)); + + const lzma_action actions[] = { + LZMA_RUN, + LZMA_SYNC_FLUSH, + LZMA_FULL_FLUSH, + LZMA_FULL_BARRIER, + }; + + for (size_t i = 0; i < ARRAY_SIZE(actions); ++i) { + assert_lzma_ret(lzma_microlzma_encoder(&strm, &opt_lzma), + LZMA_OK); + + uint8_t output[BUFFER_SIZE]; + + strm.next_in = hello_world; + strm.avail_in = sizeof(hello_world); + strm.next_out = output; + strm.avail_out = sizeof(output); + + assert_lzma_ret(lzma_code(&strm, actions[i]), + LZMA_PROG_ERROR); + } + + lzma_end(&strm); +} +#endif // HAVE_ENCODER_LZMA1 + + +/////////////////// +// Decoder tests // +/////////////////// + +#if defined(HAVE_DECODER_LZMA1) && defined(HAVE_ENCODER_LZMA1) + +// Byte array of "Goodbye World!". This is used for various decoder tests. +static const uint8_t goodbye_world[] = { 0x47, 0x6F, 0x6F, 0x64, 0x62, + 0x79, 0x65, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21 }; + +static uint8_t *goodbye_world_encoded = NULL; +static size_t goodbye_world_encoded_size = 0; + + +// Helper function to encode data and return the compressed size. +static size_t +basic_microlzma_encode(const uint8_t *input, size_t in_size, + uint8_t **compressed) +{ + lzma_stream strm = LZMA_STREAM_INIT; + lzma_options_lzma opt_lzma; + + // Lazy way to set the output size since the input should never + // inflate by much in these simple test cases. This is tested to + // be large enough after encoding to fit the entire input, so if + // this assumption does not hold then this will fail. + const size_t out_size = in_size << 1; + + *compressed = tuktest_malloc(out_size); + + // Always encode with the default options for simplicity. + if (lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT)) + goto decoder_setup_error; + + if (lzma_microlzma_encoder(&strm, &opt_lzma) != LZMA_OK) + goto decoder_setup_error; + + strm.next_in = input; + strm.avail_in = in_size; + strm.next_out = *compressed; + strm.avail_out = out_size; + + if (lzma_code(&strm, LZMA_FINISH) != LZMA_STREAM_END) + goto decoder_setup_error; + + // Check that the entire input was consumed and that it fit into + // the output buffer. + if (strm.total_in != in_size) + goto decoder_setup_error; + + lzma_end(&strm); + + // lzma_end() doesn't touch other members of lzma_stream than + // lzma_stream.internal so using strm.total_out here is fine. + return strm.total_out; + +decoder_setup_error: + tuktest_error("Failed to initialize decoder tests"); + return 0; +} + + +static void +test_decode_options(void) +{ + // NULL stream + assert_lzma_ret(lzma_microlzma_decoder(NULL, BUFFER_SIZE, + sizeof(hello_world), true, + LZMA_DICT_SIZE_DEFAULT), LZMA_PROG_ERROR); + + // Uncompressed size larger than max + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_microlzma_decoder(&strm, BUFFER_SIZE, + LZMA_VLI_MAX + 1, true, LZMA_DICT_SIZE_DEFAULT), + LZMA_OPTIONS_ERROR); +} + + +// Test that decoding succeeds when uncomp_size is correct regardless of +// the value of uncomp_size_is_exact. +static void +test_decode_uncomp_size_is_exact(void) +{ + lzma_stream strm = LZMA_STREAM_INIT; + + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size, + sizeof(goodbye_world), true, + LZMA_DICT_SIZE_DEFAULT), LZMA_OK); + + uint8_t output[BUFFER_SIZE]; + + strm.next_in = goodbye_world_encoded; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); + assert_uint_eq(strm.total_in, goodbye_world_encoded_size); + + assert_uint_eq(strm.total_out, sizeof(goodbye_world)); + assert_array_eq(goodbye_world, output, sizeof(goodbye_world)); + + // Reset decoder with uncomp_size_is_exact set to false and + // uncomp_size set to correct value. Also test using the + // uncompressed size as the dictionary size. + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size, + sizeof(goodbye_world), false, + sizeof(goodbye_world)), LZMA_OK); + + strm.next_in = goodbye_world_encoded; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_STREAM_END); + assert_uint_eq(strm.total_in, goodbye_world_encoded_size); + + assert_uint_eq(strm.total_out, sizeof(goodbye_world)); + assert_array_eq(goodbye_world, output, sizeof(goodbye_world)); + + lzma_end(&strm); +} + + +// This tests decoding when MicroLZMA decoder is called with +// an incorrect uncompressed size. +static void +test_decode_uncomp_size_wrong(void) +{ + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size, + sizeof(goodbye_world) + 1, false, + LZMA_DICT_SIZE_DEFAULT), LZMA_OK); + + uint8_t output[BUFFER_SIZE]; + + strm.next_in = goodbye_world_encoded; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + // LZMA_OK should be returned because the input size given was + // larger than the actual encoded size. The decoder is expecting + // more input to possibly fill the uncompressed size that was set. + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_OK); + + assert_uint_eq(strm.total_out, sizeof(goodbye_world)); + + assert_array_eq(goodbye_world, output, sizeof(goodbye_world)); + + // Next, test with uncomp_size_is_exact set. + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size, + sizeof(goodbye_world) + 1, true, + LZMA_DICT_SIZE_DEFAULT), LZMA_OK); + + strm.next_in = goodbye_world_encoded; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + // No error detected, even though all input was consumed and there + // is more room in the output buffer. + // + // FIXME? LZMA_FINISH tells that no more input is coming and + // the MicroLZMA decoder knows the exact compressed size from + // the initialization as well. So should it return LZMA_DATA_ERROR + // on the first call instead of relying on the generic lzma_code() + // logic to eventually get LZMA_BUF_ERROR? + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_OK); + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_OK); + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_BUF_ERROR); + + assert_uint_eq(strm.total_out, sizeof(goodbye_world)); + assert_array_eq(goodbye_world, output, sizeof(goodbye_world)); + + // Reset stream with uncomp_size smaller than the real + // uncompressed size. + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size, + ARRAY_SIZE(hello_world) - 1, true, + LZMA_DICT_SIZE_DEFAULT), LZMA_OK); + + strm.next_in = goodbye_world_encoded; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + // This case actually results in an error since it decodes the full + // uncompressed size but the range coder is not in the proper state + // for the stream to end. + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_DATA_ERROR); + + lzma_end(&strm); +} + + +static void +test_decode_comp_size_wrong(void) +{ + lzma_stream strm = LZMA_STREAM_INIT; + + // goodbye_world_encoded_size + 1 is safe because extra space was + // allocated for goodbye_world_encoded. The extra space isn't + // initialized but it shouldn't be read either, thus Valgrind + // has to remain happy with this code. + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size + 1, + sizeof(goodbye_world), true, + LZMA_DICT_SIZE_DEFAULT), LZMA_OK); + + uint8_t output[BUFFER_SIZE]; + + strm.next_in = goodbye_world_encoded; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + // When uncomp_size_is_exact is set, the compressed size must be + // correct or else LZMA_DATA_ERROR is returned. + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_DATA_ERROR); + + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size + 1, + sizeof(goodbye_world), false, + LZMA_DICT_SIZE_DEFAULT), LZMA_OK); + + strm.next_in = goodbye_world_encoded; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + // When uncomp_size_is_exact is not set, the decoder does not + // detect when the compressed size is wrong as long as all of the + // expected output has been decoded. This is because the decoder + // assumes that the real uncompressed size might be bigger than + // the specified value and in that case more input might be needed + // as well. + assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); + + lzma_end(&strm); +} + + +static void +test_decode_bad_lzma_properties(void) +{ + // Alter first byte to encode invalid LZMA properties. + uint8_t *compressed = tuktest_malloc(goodbye_world_encoded_size); + memcpy(compressed, goodbye_world_encoded, goodbye_world_encoded_size); + + // lc=3, lp=2, pb=2 + compressed[0] = (uint8_t)~0x6FU; + + lzma_stream strm = LZMA_STREAM_INIT; + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size, + sizeof(goodbye_world), false, + LZMA_DICT_SIZE_DEFAULT), LZMA_OK); + + uint8_t output[BUFFER_SIZE]; + + strm.next_in = compressed; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_OPTIONS_ERROR); + + // Use valid, but incorrect LZMA properties. + // lc=3, lp=1, pb=2 + compressed[0] = (uint8_t)~0x66; + + assert_lzma_ret(lzma_microlzma_decoder(&strm, + goodbye_world_encoded_size, + ARRAY_SIZE(goodbye_world), true, + LZMA_DICT_SIZE_DEFAULT), LZMA_OK); + + strm.next_in = compressed; + strm.avail_in = goodbye_world_encoded_size; + strm.next_out = output; + strm.avail_out = sizeof(output); + + assert_lzma_ret(lzma_code(&strm, LZMA_RUN), LZMA_DATA_ERROR); + + lzma_end(&strm); +} +#endif + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + +#ifndef HAVE_ENCODER_LZMA1 + tuktest_early_skip("LZMA1 encoder disabled"); +#else + tuktest_run(test_encode_options); + tuktest_run(test_encode_basic); + tuktest_run(test_encode_small_out); + tuktest_run(test_encode_actions); + + // MicroLZMA decoder tests require the basic encoder functionality. +# ifdef HAVE_DECODER_LZMA1 + goodbye_world_encoded_size = basic_microlzma_encode(goodbye_world, + sizeof(goodbye_world), &goodbye_world_encoded); + + tuktest_run(test_decode_options); + tuktest_run(test_decode_uncomp_size_is_exact); + tuktest_run(test_decode_uncomp_size_wrong); + tuktest_run(test_decode_comp_size_wrong); + tuktest_run(test_decode_bad_lzma_properties); +# endif + + return tuktest_end(); +#endif +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_scripts.sh b/cpp/third_party/xz-5.8.3/tests/test_scripts.sh new file mode 100755 index 000000000..ca9600ec1 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_scripts.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# SPDX-License-Identifier: 0BSD + +############################################################################### +# +# Author: Jonathan Nieder +# +############################################################################### + +# If scripts weren't built, this test is skipped. +# When this is run from CMake, $1 is a relative path +# to the directory with the executables and the scripts. +XZ=${1:-../src/xz}/xz +XZDIFF=${1:-../src/scripts}/xzdiff +XZGREP=${1:-../src/scripts}/xzgrep + +for i in XZ XZDIFF XZGREP; do + eval test -x "\$$i" && continue + exit 77 +done + +# If decompression support is missing, this test is skipped. +# Installing the scripts in this case is a bit silly but they +# could still be used with other decompression tools so configure +# doesn't automatically disable scripts if decoders are disabled. +if test ! -f ../config.h \ + || grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then + : +else + echo "Decompression support is disabled, skipping this test." + exit 77 +fi + +PATH=`pwd`/${1:-../src/xz}:$PATH +export PATH + +test -z "$srcdir" && srcdir=. +preimage=$srcdir/files/good-1-check-crc32.xz +samepostimage=$srcdir/files/good-1-check-crc64.xz +otherpostimage=$srcdir/files/good-1-lzma2-1.xz + +"$XZDIFF" "$preimage" "$samepostimage" >/dev/null +status=$? +if test "$status" != 0 ; then + echo "xzdiff with no changes exited with status $status != 0" + exit 1 +fi + +"$XZDIFF" "$preimage" "$otherpostimage" >/dev/null +status=$? +if test "$status" != 1 ; then + echo "xzdiff with changes exited with status $status != 1" + exit 1 +fi + +"$XZDIFF" "$preimage" "$srcdir/files/missing.xz" >/dev/null 2>&1 +status=$? +if test "$status" != 2 ; then + echo "xzdiff with missing operand exited with status $status != 2" + exit 1 +fi + +# The exit status must be 0 when a match was found at least from one file, +# and 1 when no match was found in any file. +cp "$srcdir/files/good-1-lzma2-1.xz" xzgrep_test_1.xz +cp "$srcdir/files/good-2-lzma2.xz" xzgrep_test_2.xz +for pattern in el Hello NOMATCH; do + for opts in "" "-l" "-h" "-H"; do + echo "=> xzgrep $opts $pattern <=" + "$XZGREP" $opts $pattern xzgrep_test_1.xz xzgrep_test_2.xz + echo retval $? + done +done > xzgrep_test_output 2>&1 + +if cmp -s "$srcdir/xzgrep_expected_output" xzgrep_test_output ; then + : +else + echo "unexpected output from xzgrep" + exit 1 +fi + +exit 0 diff --git a/cpp/third_party/xz-5.8.3/tests/test_stream_flags.c b/cpp/third_party/xz-5.8.3/tests/test_stream_flags.c new file mode 100644 index 000000000..3bc48be07 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_stream_flags.c @@ -0,0 +1,478 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_stream_flags.c +/// \brief Tests Stream Header and Stream Footer coders +// +// Authors: Jia Tan +// Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + + +// Size of the Stream Flags field +// (taken from src/liblzma/common/stream_flags_common.h) +#define XZ_STREAM_FLAGS_SIZE 2 + +#ifdef HAVE_ENCODERS +// Header and footer magic bytes for .xz file format +// (taken from src/liblzma/common/stream_flags_common.c) +static const uint8_t xz_header_magic[6] + = { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00 }; +static const uint8_t xz_footer_magic[2] = { 0x59, 0x5A }; +#endif + + +#ifdef HAVE_ENCODERS +static void +stream_header_encode_helper(lzma_check check) +{ + lzma_stream_flags flags = { + .version = 0, + .check = check, + }; + + uint8_t header[LZMA_STREAM_HEADER_SIZE]; + + // Encode Stream Header + assert_lzma_ret(lzma_stream_header_encode(&flags, header), LZMA_OK); + + // Stream Header must start with Header Magic Bytes + const uint32_t magic_size = sizeof(xz_header_magic); + assert_array_eq(header, xz_header_magic, magic_size); + + // Next must come Stream Flags + const uint8_t *encoded_stream_flags = header + magic_size; + + // First byte is always null-byte. + // Second byte must have the Check ID in the lowest four bits + // and the highest four bits zero. + const uint8_t expected_stream_flags[] = { 0, check }; + assert_array_eq(encoded_stream_flags, expected_stream_flags, + XZ_STREAM_FLAGS_SIZE); + + // Last part is the CRC32 of the Stream Flags + const uint8_t *crc_ptr = encoded_stream_flags + XZ_STREAM_FLAGS_SIZE; + const uint32_t expected_crc = lzma_crc32(expected_stream_flags, + XZ_STREAM_FLAGS_SIZE, 0); + assert_uint_eq(read32le(crc_ptr), expected_crc); +} +#endif + + +static void +test_lzma_stream_header_encode(void) +{ +#ifndef HAVE_ENCODERS + assert_skip("Encoder support disabled"); +#else + for (lzma_check i = 0; i < LZMA_CHECK_ID_MAX; i++) + stream_header_encode_helper(i); + + lzma_stream_flags flags = { + .version = 0, + .check = LZMA_CHECK_CRC32 + }; + + uint8_t header[LZMA_STREAM_HEADER_SIZE]; + + // Should fail if version > 0 + flags.version = 1; + assert_lzma_ret(lzma_stream_header_encode(&flags, header), + LZMA_OPTIONS_ERROR); + flags.version = 0; + + // Should fail if Check ID is invalid + flags.check = INVALID_LZMA_CHECK_ID; + assert_lzma_ret(lzma_stream_header_encode(&flags, header), + LZMA_PROG_ERROR); + flags.check = LZMA_CHECK_CRC32; + + // Should pass even if Backward Size is invalid + // because Stream Header doesn't have that field. + flags.backward_size = LZMA_VLI_MAX + 1; + assert_lzma_ret(lzma_stream_header_encode(&flags, header), LZMA_OK); +#endif +} + + +#if defined(HAVE_ENCODERS) +static void +stream_footer_encode_helper(lzma_check check) +{ + lzma_stream_flags flags = { + .version = 0, + .check = check, + .backward_size = LZMA_BACKWARD_SIZE_MIN, + }; + + uint8_t footer[LZMA_STREAM_HEADER_SIZE]; + + // Encode Stream Footer + assert_lzma_ret(lzma_stream_footer_encode(&flags, footer), LZMA_OK); + + // Stream Footer must start with CRC32 + const uint32_t crc = read32le(footer); + const uint32_t expected_crc = lzma_crc32(footer + sizeof(uint32_t), + LZMA_STREAM_HEADER_SIZE - (sizeof(uint32_t) + + sizeof(xz_footer_magic)), 0); + assert_uint_eq(crc, expected_crc); + + // Next the Backward Size + const uint32_t backwards_size = read32le(footer + sizeof(uint32_t)); + const uint32_t expected_backwards_size = flags.backward_size / 4 - 1; + assert_uint_eq(backwards_size, expected_backwards_size); + + // Next the Stream Flags + const uint8_t *stream_flags = footer + sizeof(uint32_t) * 2; + + // First byte must be null + assert_uint_eq(stream_flags[0], 0); + + // Second byte must have the Check ID in the lowest four bits + // and the highest four bits zero. + assert_uint_eq(stream_flags[1], check); + + // And ends with Footer Magic Bytes + const uint8_t *expected_footer_magic = stream_flags + + XZ_STREAM_FLAGS_SIZE; + assert_array_eq(expected_footer_magic, xz_footer_magic, + sizeof(xz_footer_magic)); +} +#endif + + +static void +test_lzma_stream_footer_encode(void) +{ +#ifndef HAVE_ENCODERS + assert_skip("Encoder support disabled"); +#else + for (lzma_check i = 0; i < LZMA_CHECK_ID_MAX; i++) + stream_footer_encode_helper(i); + + lzma_stream_flags flags = { + .version = 0, + .backward_size = LZMA_BACKWARD_SIZE_MIN, + .check = LZMA_CHECK_CRC32 + }; + + uint8_t footer[LZMA_STREAM_HEADER_SIZE]; + + // Should fail if version > 0 + flags.version = 1; + assert_lzma_ret(lzma_stream_footer_encode(&flags, footer), + LZMA_OPTIONS_ERROR); + flags.version = 0; + + // Should fail if Check ID is invalid + flags.check = INVALID_LZMA_CHECK_ID; + assert_lzma_ret(lzma_stream_footer_encode(&flags, footer), + LZMA_PROG_ERROR); + + // Should fail if Backward Size is invalid + flags.backward_size -= 1; + assert_lzma_ret(lzma_stream_footer_encode(&flags, footer), + LZMA_PROG_ERROR); + flags.backward_size += 2; + assert_lzma_ret(lzma_stream_footer_encode(&flags, footer), + LZMA_PROG_ERROR); + flags.backward_size = LZMA_BACKWARD_SIZE_MAX + 4; + assert_lzma_ret(lzma_stream_footer_encode(&flags, footer), + LZMA_PROG_ERROR); +#endif +} + + +#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS) +static void +stream_header_decode_helper(lzma_check check) +{ + lzma_stream_flags flags = { + .version = 0, + .check = check + }; + + uint8_t header[LZMA_STREAM_HEADER_SIZE]; + + assert_lzma_ret(lzma_stream_header_encode(&flags, header), LZMA_OK); + + lzma_stream_flags dest_flags; + assert_lzma_ret(lzma_stream_header_decode(&dest_flags, header), + LZMA_OK); + + // Version should be 0 + assert_uint_eq(dest_flags.version, 0); + + // Backward Size should be LZMA_VLI_UNKNOWN + assert_uint_eq(dest_flags.backward_size, LZMA_VLI_UNKNOWN); + + // Check ID must equal the argument given to this function. + assert_uint_eq(dest_flags.check, check); +} +#endif + + +static void +test_lzma_stream_header_decode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + for (lzma_check i = 0; i < LZMA_CHECK_ID_MAX; i++) + stream_header_decode_helper(i); + + lzma_stream_flags flags = { + .version = 0, + .check = LZMA_CHECK_CRC32 + }; + + uint8_t header[LZMA_STREAM_HEADER_SIZE]; + lzma_stream_flags dest; + + // First encode known flags to header buffer + assert_lzma_ret(lzma_stream_header_encode(&flags, header), LZMA_OK); + + // Should fail if magic bytes do not match + header[0] ^= 1; + assert_lzma_ret(lzma_stream_header_decode(&dest, header), + LZMA_FORMAT_ERROR); + header[0] ^= 1; + + // Should fail if a reserved bit is set + uint8_t *stream_flags = header + sizeof(xz_header_magic); + stream_flags[0] = 1; + + // Need to adjust CRC32 after making a change since the CRC32 + // is verified before decoding the Stream Flags field. + uint8_t *crc32_ptr = header + sizeof(xz_header_magic) + + XZ_STREAM_FLAGS_SIZE; + const uint32_t crc_orig = read32le(crc32_ptr); + uint32_t new_crc32 = lzma_crc32( + stream_flags, XZ_STREAM_FLAGS_SIZE, 0); + write32le(crc32_ptr, new_crc32); + assert_lzma_ret(lzma_stream_header_decode(&dest, header), + LZMA_OPTIONS_ERROR); + stream_flags[0] = 0; + write32le(crc32_ptr, crc_orig); + + // Should fail if upper bits of check ID are set + stream_flags[1] |= 0xF0; + new_crc32 = lzma_crc32(stream_flags, XZ_STREAM_FLAGS_SIZE, 0); + write32le(crc32_ptr, new_crc32); + assert_lzma_ret(lzma_stream_header_decode(&dest, header), + LZMA_OPTIONS_ERROR); + stream_flags[1] = flags.check; + write32le(crc32_ptr, crc_orig); + + // Should fail if CRC32 does not match. + // First, alter a byte in the Stream Flags. + stream_flags[0] = 1; + assert_lzma_ret(lzma_stream_header_decode(&dest, header), + LZMA_DATA_ERROR); + stream_flags[0] = 0; + + // Next, change the CRC32. + *crc32_ptr ^= 1; + assert_lzma_ret(lzma_stream_header_decode(&dest, header), + LZMA_DATA_ERROR); +#endif +} + + +#if defined(HAVE_ENCODERS) && defined(HAVE_DECODERS) +static void +stream_footer_decode_helper(lzma_check check) +{ + lzma_stream_flags flags = { + .version = 0, + .backward_size = LZMA_BACKWARD_SIZE_MIN, + .check = check, + }; + + uint8_t footer[LZMA_STREAM_HEADER_SIZE]; + assert_lzma_ret(lzma_stream_footer_encode(&flags, footer), LZMA_OK); + + lzma_stream_flags dest_flags; + assert_lzma_ret(lzma_stream_footer_decode(&dest_flags, footer), + LZMA_OK); + + // Version should be 0. + assert_uint_eq(dest_flags.version, 0); + + // Backward Size should equal the value from the flags. + assert_uint_eq(dest_flags.backward_size, flags.backward_size); + + // Check ID must equal argument given to this function. + assert_uint_eq(dest_flags.check, check); +} +#endif + + +static void +test_lzma_stream_footer_decode(void) +{ +#if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS) + assert_skip("Encoder or decoder support disabled"); +#else + for (lzma_check i = 0; i < LZMA_CHECK_ID_MAX; i++) + stream_footer_decode_helper(i); + + lzma_stream_flags flags = { + .version = 0, + .check = LZMA_CHECK_CRC32, + .backward_size = LZMA_BACKWARD_SIZE_MIN + }; + + uint8_t footer[LZMA_STREAM_HEADER_SIZE]; + lzma_stream_flags dest; + + // First encode known flags to the footer buffer + assert_lzma_ret(lzma_stream_footer_encode(&flags, footer), LZMA_OK); + + // Should fail if magic bytes do not match + footer[LZMA_STREAM_HEADER_SIZE - 1] ^= 1; + assert_lzma_ret(lzma_stream_footer_decode(&dest, footer), + LZMA_FORMAT_ERROR); + footer[LZMA_STREAM_HEADER_SIZE - 1] ^= 1; + + // Should fail if a reserved bit is set. + // In the Stream Footer, the Stream Flags follow the CRC32 (4 bytes) + // and the Backward Size (4 bytes) + uint8_t *stream_flags = footer + sizeof(uint32_t) * 2; + stream_flags[0] = 1; + + // Need to adjust the CRC32 so it will not fail that check instead + uint8_t *crc32_ptr = footer; + const uint32_t crc_orig = read32le(crc32_ptr); + uint8_t *backward_size = footer + sizeof(uint32_t); + uint32_t new_crc32 = lzma_crc32(backward_size, sizeof(uint32_t) + + XZ_STREAM_FLAGS_SIZE, 0); + write32le(crc32_ptr, new_crc32); + assert_lzma_ret(lzma_stream_footer_decode(&dest, footer), + LZMA_OPTIONS_ERROR); + stream_flags[0] = 0; + write32le(crc32_ptr, crc_orig); + + // Should fail if upper bits of check ID are set + stream_flags[1] |= 0xF0; + new_crc32 = lzma_crc32(backward_size, sizeof(uint32_t) + + XZ_STREAM_FLAGS_SIZE, 0); + write32le(crc32_ptr, new_crc32); + assert_lzma_ret(lzma_stream_footer_decode(&dest, footer), + LZMA_OPTIONS_ERROR); + stream_flags[1] = flags.check; + write32le(crc32_ptr, crc_orig); + + // Should fail if CRC32 does not match. + // First, alter a byte in the Stream Flags. + stream_flags[0] = 1; + assert_lzma_ret(lzma_stream_footer_decode(&dest, footer), + LZMA_DATA_ERROR); + stream_flags[0] = 0; + + // Next, change the CRC32 + *crc32_ptr ^= 1; + assert_lzma_ret(lzma_stream_footer_decode(&dest, footer), + LZMA_DATA_ERROR); +#endif +} + + +static void +test_lzma_stream_flags_compare(void) +{ + lzma_stream_flags first = { + .version = 0, + .backward_size = LZMA_BACKWARD_SIZE_MIN, + .check = LZMA_CHECK_CRC32, + }; + + lzma_stream_flags second = first; + + // First test should pass + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), LZMA_OK); + + // Altering either version should cause an error + first.version = 1; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_OPTIONS_ERROR); + second.version = 1; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_OPTIONS_ERROR); + first.version = 0; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_OPTIONS_ERROR); + second.version = 0; + + // Check types must be under the maximum + first.check = INVALID_LZMA_CHECK_ID; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_PROG_ERROR); + second.check = INVALID_LZMA_CHECK_ID; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_PROG_ERROR); + first.check = LZMA_CHECK_CRC32; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_PROG_ERROR); + second.check = LZMA_CHECK_CRC32; + + // Check types must be equal + for (lzma_check i = 0; i < LZMA_CHECK_ID_MAX; i++) { + first.check = i; + if (i == second.check) + assert_lzma_ret(lzma_stream_flags_compare(&first, + &second), LZMA_OK); + else + assert_lzma_ret(lzma_stream_flags_compare(&first, + &second), LZMA_DATA_ERROR); + } + first.check = LZMA_CHECK_CRC32; + + // Backward Size comparison is skipped if either are LZMA_VLI_UNKNOWN + first.backward_size = LZMA_VLI_UNKNOWN; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), LZMA_OK); + second.backward_size = LZMA_VLI_MAX + 1; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), LZMA_OK); + second.backward_size = LZMA_BACKWARD_SIZE_MIN; + + // Backward Sizes need to be valid + first.backward_size = LZMA_VLI_MAX + 4; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_PROG_ERROR); + second.backward_size = LZMA_VLI_MAX + 4; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_PROG_ERROR); + first.backward_size = LZMA_BACKWARD_SIZE_MIN; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_PROG_ERROR); + second.backward_size = LZMA_BACKWARD_SIZE_MIN; + + // Backward Sizes must be equal + second.backward_size = first.backward_size + 4; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_DATA_ERROR); + + // Should fail if Backward Sizes are > LZMA_BACKWARD_SIZE_MAX + // even though they are equal + first.backward_size = LZMA_BACKWARD_SIZE_MAX + 1; + second.backward_size = LZMA_BACKWARD_SIZE_MAX + 1; + assert_lzma_ret(lzma_stream_flags_compare(&first, &second), + LZMA_PROG_ERROR); +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + tuktest_run(test_lzma_stream_header_encode); + tuktest_run(test_lzma_stream_footer_encode); + tuktest_run(test_lzma_stream_header_decode); + tuktest_run(test_lzma_stream_footer_decode); + tuktest_run(test_lzma_stream_flags_compare); + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/test_suffix.sh b/cpp/third_party/xz-5.8.3/tests/test_suffix.sh new file mode 100755 index 000000000..1859fe4c8 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_suffix.sh @@ -0,0 +1,192 @@ +#!/bin/sh +# SPDX-License-Identifier: 0BSD + +############################################################################### +# +# Author: Jia Tan +# +############################################################################### + +# Optional argument: +# $1 = directory of the xz executable + +# If xz was not built, skip this test. Autotools and CMake put +# the xz executable in a different location. +XZ=${1:-../src/xz}/xz +if test ! -x "$XZ"; then + echo "xz was not built, skipping this test." + exit 77 +fi + +# If compression or decompression support is missing, this test is skipped. +# This isn't perfect because it does not specifically check for LZMA1/2 +# filters. Many of the other tests also assume LZMA1/2 support if encoders +# or decoders are enabled. +if test ! -f ../config.h ; then + : +elif grep 'define HAVE_ENCODERS' ../config.h > /dev/null \ + && grep 'define HAVE_DECODERS' ../config.h > /dev/null ; then + : +else + echo "Compression or decompression support is disabled, skipping this test." + exit 77 +fi + +# Create temporary input file. The file contents are not important. +SUFFIX_INPUT="suffix_temp" +SUFFIX_INPUT_FILES="$SUFFIX_INPUT"_files +SUFFIX_INPUT_FILES0="$SUFFIX_INPUT"_files0 + +# Remove possible leftover temporary files +rm -f \ + "$SUFFIX_INPUT" \ + "$SUFFIX_INPUT.foo" \ + "$SUFFIX_INPUT_FILES" \ + "$SUFFIX_INPUT_FILES" + +echo "foobar" > "$SUFFIX_INPUT" + +# Test basic suffix when compressing with raw format. +if "$XZ" -zfk --suffix=".foo" -Fraw --lzma1=preset=0 "$SUFFIX_INPUT" ; then + : +else + echo "Failed to compress a file with a suffix set in raw format" + exit 1 +fi + +# Test the output file is named properly. +if test -f "$SUFFIX_INPUT.foo" ; then + : +else + echo "Raw format compressed output file not named properly" + exit 1 +fi + +# Expect an error when compressing with raw format without a suffix +if "$XZ" -zfk -Fraw --lzma1=preset=0 "$SUFFIX_INPUT" 2> /dev/null; then + echo "Error not reported when compressing in raw format without a suffix" + exit 1 +fi + +# Expect an error when decompressing with raw format without a suffix +if "$XZ" -df -Fraw --lzma1=preset=0 "$SUFFIX_INPUT.foo" 2> /dev/null; then + echo "Error not reported when decompressing in raw format without a suffix" + exit 1 +fi + +# Test basic decompression with raw format and a suffix. This will also +# delete $SUFFIX_INPUT.foo +if "$XZ" -df --suffix=".foo" -Fraw --lzma1=preset=0 "$SUFFIX_INPUT.foo"; then + : +else + echo "Failed to decompress a file with a suffix set in raw format" + exit 1 +fi + +# Test basic compression with .xz format and a suffix +if "$XZ" -zfk --suffix=".foo" --lzma2=preset=0 "$SUFFIX_INPUT" ; then + : +else + echo "Failed to compress a file with a suffix set in .xz format" + exit 1 +fi + +# Test the output file is named properly. +if test -f "$SUFFIX_INPUT.foo" ; then + : +else + echo ".xz format compressed output file named properly" + exit 1 +fi + +# This will delete $SUFFIX_INPUT.foo +if "$XZ" -df --suffix=".foo" "$SUFFIX_INPUT.foo"; then + : +else + echo "Failed to decompress a file with a suffix set in .xz format" + exit 1 +fi + +# Test reading from stdin in raw mode. This was broken in +# cc5aa9ab138beeecaee5a1e81197591893ee9ca0 and fixed in +# 837ea40b1c9d4998cac4500b55171bf33e0c31a6 +if echo foo | "$XZ" -Fraw --lzma1=preset=0 > /dev/null ; then + : +else + echo "Implicit write to stdout not detected" + exit 1 +fi + +# Create two temporary files to be used with --files and --files0. +printf '%s\n' "$SUFFIX_INPUT" > "$SUFFIX_INPUT_FILES" +printf '%s\0' "$SUFFIX_INPUT" > "$SUFFIX_INPUT_FILES0" + +# Test proper handling of --files/--files0 when no suffix is set. This +# must result in an error because xz does not know how to rename the output +# file from the input files. This caused a segmentation fault due to a +# mistake in f481523baac946fa3bc13d79186ffaf0c0b818a7, which was fixed by +# 0a601ddc89fd7e1370807c6b58964f361dfcd34a. +if "$XZ" -Fraw --lzma1=preset=0 --files="$SUFFIX_INPUT_FILES" 2> /dev/null ; then + echo "Failed to report error when compressing a file specified by --files in raw mode without a suffix" + exit 1 +fi + +if "$XZ" -Fraw --lzma1=preset=0 --files0="$SUFFIX_INPUT_FILES0" 2> /dev/null ; then + echo "Failed to report error when compressing a file specified by --files0 in raw mode without a suffix" + exit 1 +fi + +# Test proper suffix usage in raw mode with --files and --files0. +if "$XZ" -zfk -Fraw --lzma1=preset=0 --suffix=.foo --files="$SUFFIX_INPUT_FILES" ; then + : +else + echo "Error compressing a file specified by --files in raw mode with a suffix set" + exit 1 +fi + +if test -f "$SUFFIX_INPUT.foo" ; then + : +else + echo "Entry processed by --files not named properly" + exit 1 +fi + +# Remove the artifact so we can be sure the next test executes properly. +rm "$SUFFIX_INPUT.foo" + +if "$XZ" -zfk -Fraw --lzma1=preset=0 --suffix=.foo --files0="$SUFFIX_INPUT_FILES0" ; then + : +else + echo "Error compressing a file specified by --files0 in raw mode with a suffix set" + exit 1 +fi + +if test -f "$SUFFIX_INPUT.foo" ; then + : +else + echo "Entry processed by --files0 not named properly" + exit 1 +fi + +# When the file type cannot be determined by xz, it will copy the contents +# of the file only if -c,--stdout is used. This was broken by +# 837ea40b1c9d4998cac4500b55171bf33e0c31a6 and fixed by +# f481523baac946fa3bc13d79186ffaf0c0b818a7. +if echo foo | "$XZ" -df > /dev/null 2>&1; then + echo "Failed to report error when decompressing unknown file type without -c,--stdout" + exit 1 +fi + +if echo foo | "$XZ" -dfc > /dev/null; then + : +else + echo "Failed to copy input to standard out when decompressing unknown file type with -c,--stdout" + exit 1 +fi + +# Remove remaining test artifacts +rm -f \ + "$SUFFIX_INPUT" \ + "$SUFFIX_INPUT.foo" \ + "$SUFFIX_INPUT_FILES" \ + "$SUFFIX_INPUT_FILES0" diff --git a/cpp/third_party/xz-5.8.3/tests/test_vli.c b/cpp/third_party/xz-5.8.3/tests/test_vli.c new file mode 100644 index 000000000..51487dcf1 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/test_vli.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file test_vli.c +/// \brief Tests liblzma vli functions +// +// Author: Jia Tan +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tests.h" + + +// Pre-encoded VLI values for testing +// VLI can have between 1 and 9 bytes when encoded +// They are encoded little endian where all but the last +// byte must have the leading 1 bit set +#if defined(HAVE_ENCODERS) || defined(HAVE_DECODERS) +static const uint8_t one_byte[1] = {0x25}; +static const lzma_vli one_byte_value = 37; + +static const uint8_t two_bytes[2] = {0x80, 0x56}; +static const lzma_vli two_byte_value = 11008; + +static const uint8_t three_bytes[3] = {0x99, 0x92, 0x20}; +static const lzma_vli three_byte_value = 526617; + +static const uint8_t four_bytes[4] = {0x97, 0x83, 0x94, 0x47}; +static const lzma_vli four_byte_value = 149225879; + +static const uint8_t five_bytes[5] = {0xA6, 0x92, 0x88, 0x89, 0x32}; +static const lzma_vli five_byte_value = 13440780582; + +static const uint8_t six_bytes[6] = {0xA9, 0x84, 0x99, 0x82, 0x94, 0x12}; +static const lzma_vli six_byte_value = 623848604201; + +static const uint8_t seven_bytes[7] = {0x90, 0x80, 0x90, 0x80, 0x90, 0x80, + 0x79}; +static const lzma_vli seven_byte_value = 532167923073040; + +static const uint8_t eight_bytes[8] = {0x91, 0x87, 0xF2, 0xB2, 0xC2, 0xD2, + 0x93, 0x63}; +static const lzma_vli eight_byte_value = 55818443594433425; + +static const uint8_t nine_bytes[9] = {0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, + 0xE1, 0xF1, 0x1}; +static const lzma_vli nine_byte_value = 136100349976529025; +#endif + + +static void +test_lzma_vli_size(void) +{ + // First test invalid VLI values (should return 0) + // VLI UNKNOWN is an invalid VLI + assert_uint_eq(lzma_vli_size(LZMA_VLI_UNKNOWN), 0); + // Loop over a few VLI values just over the maximum + for (uint64_t i = LZMA_VLI_MAX + 1; i < LZMA_VLI_MAX + 10; i++) + assert_uint_eq(lzma_vli_size(i), 0); + + // Number should increment every seven set bits + lzma_vli vli = 1; + for (uint32_t i = 1; i < LZMA_VLI_BYTES_MAX; i++, vli <<= 7) { + // Test the base value and a few others around it + assert_uint_eq(lzma_vli_size(vli), i); + assert_uint_eq(lzma_vli_size(vli * 2), i); + assert_uint_eq(lzma_vli_size(vli + 10), i); + assert_uint_eq(lzma_vli_size(vli * 3 + 39), i); + } +} + + +#ifdef HAVE_ENCODERS +// Helper function for test_lzma_vli_encode +// Encodes an input VLI and compares against a pre-computed value +static void +encode_single_call_mode(lzma_vli input, const uint8_t *expected, + uint32_t expected_len) +{ + uint8_t out[LZMA_VLI_BYTES_MAX]; + size_t out_pos = 0; + assert_lzma_ret(lzma_vli_encode(input, NULL, out, &out_pos, + expected_len), LZMA_OK); + assert_uint_eq(out_pos, expected_len); + assert_array_eq(out, expected, expected_len); +} + + +// Helper function for test_lzma_vli_encode +// Encodes an input VLI one byte at a time with the multi call +// method. Then compares against a pre-computed value +static void +encode_multi_call_mode(lzma_vli input, const uint8_t *expected, + uint32_t expected_len) +{ + uint8_t out[LZMA_VLI_BYTES_MAX]; + size_t out_pos = 0; + size_t vli_pos = 0; + + for (uint32_t i = 1; i < expected_len; i++) { + assert_lzma_ret(lzma_vli_encode(input, &vli_pos, out, + &out_pos, i), LZMA_OK); + assert_uint_eq(out_pos, i); + assert_uint_eq(vli_pos, i); + } + assert_lzma_ret(lzma_vli_encode(input, &vli_pos, out, &out_pos, + expected_len), LZMA_STREAM_END); + assert_uint_eq(out_pos, expected_len); + assert_uint_eq(vli_pos, expected_len); + assert_array_eq(out, expected, expected_len); +} +#endif + + +static void +test_lzma_vli_encode(void) +{ +#ifndef HAVE_ENCODERS + assert_skip("Encoder support disabled"); +#else + size_t vli_pos = 0; + uint8_t out[LZMA_VLI_BYTES_MAX]; + uint8_t zeros[LZMA_VLI_BYTES_MAX]; + memzero(out, LZMA_VLI_BYTES_MAX); + memzero(zeros, LZMA_VLI_BYTES_MAX); + size_t out_pos = 0; + + // First test invalid input parameters + // VLI invalid + assert_lzma_ret(lzma_vli_encode(LZMA_VLI_UNKNOWN, &vli_pos, out, + &out_pos, sizeof(out)), LZMA_PROG_ERROR); + // Failure should not change params + assert_uint_eq(vli_pos, 0); + assert_uint_eq(out_pos, 0); + assert_array_eq(out, zeros, LZMA_VLI_BYTES_MAX); + + assert_lzma_ret(lzma_vli_encode(LZMA_VLI_MAX + 1, &vli_pos, out, + &out_pos, sizeof(out)), LZMA_PROG_ERROR); + assert_uint_eq(vli_pos, 0); + assert_uint_eq(out_pos, 0); + assert_array_eq(out, zeros, LZMA_VLI_BYTES_MAX); + + // 0 output size + assert_lzma_ret(lzma_vli_encode(one_byte_value, &vli_pos, out, + &out_pos, 0), LZMA_BUF_ERROR); + assert_uint_eq(vli_pos, 0); + assert_uint_eq(out_pos, 0); + assert_array_eq(out, zeros, LZMA_VLI_BYTES_MAX); + + // Size of VLI does not fit in buffer + size_t phony_out_pos = 3; + assert_lzma_ret(lzma_vli_encode(one_byte_value, NULL, out, + &phony_out_pos, 2), LZMA_PROG_ERROR); + + assert_lzma_ret(lzma_vli_encode(LZMA_VLI_MAX / 2, NULL, out, + &out_pos, 2), LZMA_PROG_ERROR); + + // Test single-call mode (using vli_pos as NULL) + encode_single_call_mode(one_byte_value, one_byte, + sizeof(one_byte)); + encode_single_call_mode(two_byte_value, two_bytes, + sizeof(two_bytes)); + encode_single_call_mode(three_byte_value, three_bytes, + sizeof(three_bytes)); + encode_single_call_mode(four_byte_value, four_bytes, + sizeof(four_bytes)); + encode_single_call_mode(five_byte_value, five_bytes, + sizeof(five_bytes)); + encode_single_call_mode(six_byte_value, six_bytes, + sizeof(six_bytes)); + encode_single_call_mode(seven_byte_value, seven_bytes, + sizeof(seven_bytes)); + encode_single_call_mode(eight_byte_value, eight_bytes, + sizeof(eight_bytes)); + encode_single_call_mode(nine_byte_value, nine_bytes, + sizeof(nine_bytes)); + + // Test multi-call mode + encode_multi_call_mode(one_byte_value, one_byte, + sizeof(one_byte)); + encode_multi_call_mode(two_byte_value, two_bytes, + sizeof(two_bytes)); + encode_multi_call_mode(three_byte_value, three_bytes, + sizeof(three_bytes)); + encode_multi_call_mode(four_byte_value, four_bytes, + sizeof(four_bytes)); + encode_multi_call_mode(five_byte_value, five_bytes, + sizeof(five_bytes)); + encode_multi_call_mode(six_byte_value, six_bytes, + sizeof(six_bytes)); + encode_multi_call_mode(seven_byte_value, seven_bytes, + sizeof(seven_bytes)); + encode_multi_call_mode(eight_byte_value, eight_bytes, + sizeof(eight_bytes)); + encode_multi_call_mode(nine_byte_value, nine_bytes, + sizeof(nine_bytes)); +#endif +} + + +#ifdef HAVE_DECODERS +static void +decode_single_call_mode(const uint8_t *input, uint32_t input_len, + lzma_vli expected) +{ + lzma_vli out = 0; + size_t in_pos = 0; + + assert_lzma_ret(lzma_vli_decode(&out, NULL, input, &in_pos, + input_len), LZMA_OK); + assert_uint_eq(in_pos, input_len); + assert_uint_eq(out, expected); +} + + +static void +decode_multi_call_mode(const uint8_t *input, uint32_t input_len, + lzma_vli expected) +{ + lzma_vli out = 0; + size_t in_pos = 0; + size_t vli_pos = 0; + + for (uint32_t i = 1; i < input_len; i++) { + assert_lzma_ret(lzma_vli_decode(&out, &vli_pos, input, + &in_pos, i), LZMA_OK); + assert_uint_eq(in_pos, i); + assert_uint_eq(vli_pos, i); + } + + assert_lzma_ret(lzma_vli_decode(&out, &vli_pos, input, &in_pos, + input_len), LZMA_STREAM_END); + assert_uint_eq(in_pos, input_len); + assert_uint_eq(vli_pos, input_len); + assert_uint_eq(out, expected); +} +#endif + + +static void +test_lzma_vli_decode(void) +{ +#ifndef HAVE_DECODERS + assert_skip("Decoder support disabled"); +#else + lzma_vli out = 0; + size_t in_pos = 0; + + // First test invalid input params + // 0 in_size + assert_lzma_ret(lzma_vli_decode(&out, NULL, one_byte, &in_pos, 0), + LZMA_DATA_ERROR); + assert_uint_eq(out, 0); + assert_uint_eq(in_pos, 0); + + // VLI encoded is invalid (last digit has leading 1 set) + uint8_t invalid_vli[3] = {0x80, 0x80, 0x80}; + assert_lzma_ret(lzma_vli_decode(&out, NULL, invalid_vli, &in_pos, + sizeof(invalid_vli)), LZMA_DATA_ERROR); + + // Bad vli_pos + size_t vli_pos = LZMA_VLI_BYTES_MAX; + assert_lzma_ret(lzma_vli_decode(&out, &vli_pos, invalid_vli, &in_pos, + sizeof(invalid_vli)), LZMA_PROG_ERROR); + + // Bad in_pos + in_pos = sizeof(invalid_vli); + assert_lzma_ret(lzma_vli_decode(&out, &in_pos, invalid_vli, &in_pos, + sizeof(invalid_vli)), LZMA_BUF_ERROR); + + // Test single call mode + decode_single_call_mode(one_byte, sizeof(one_byte), + one_byte_value); + decode_single_call_mode(two_bytes, sizeof(two_bytes), + two_byte_value); + decode_single_call_mode(three_bytes, sizeof(three_bytes), + three_byte_value); + decode_single_call_mode(four_bytes, sizeof(four_bytes), + four_byte_value); + decode_single_call_mode(five_bytes, sizeof(five_bytes), + five_byte_value); + decode_single_call_mode(six_bytes, sizeof(six_bytes), + six_byte_value); + decode_single_call_mode(seven_bytes, sizeof(seven_bytes), + seven_byte_value); + decode_single_call_mode(eight_bytes, sizeof(eight_bytes), + eight_byte_value); + decode_single_call_mode(nine_bytes, sizeof(nine_bytes), + nine_byte_value); + + // Test multi call mode + decode_multi_call_mode(one_byte, sizeof(one_byte), + one_byte_value); + decode_multi_call_mode(two_bytes, sizeof(two_bytes), + two_byte_value); + decode_multi_call_mode(three_bytes, sizeof(three_bytes), + three_byte_value); + decode_multi_call_mode(four_bytes, sizeof(four_bytes), + four_byte_value); + decode_multi_call_mode(five_bytes, sizeof(five_bytes), + five_byte_value); + decode_multi_call_mode(six_bytes, sizeof(six_bytes), + six_byte_value); + decode_multi_call_mode(seven_bytes, sizeof(seven_bytes), + seven_byte_value); + decode_multi_call_mode(eight_bytes, sizeof(eight_bytes), + eight_byte_value); + decode_multi_call_mode(nine_bytes, sizeof(nine_bytes), + nine_byte_value); +#endif +} + + +extern int +main(int argc, char **argv) +{ + tuktest_start(argc, argv); + tuktest_run(test_lzma_vli_size); + tuktest_run(test_lzma_vli_encode); + tuktest_run(test_lzma_vli_decode); + return tuktest_end(); +} diff --git a/cpp/third_party/xz-5.8.3/tests/tests.cmake b/cpp/third_party/xz-5.8.3/tests/tests.cmake new file mode 100644 index 000000000..9302a5e42 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/tests.cmake @@ -0,0 +1,228 @@ +# SPDX-License-Identifier: 0BSD + +############################################################################# +# +# Optional file to be included by the top-level CMakeLists.txt to run tests +# +# The CMake rules for the tests are in this separate optional file so +# that it's trivial to just delete the whole "tests" directory and still +# get an otherwise normal CMake-based build. This way it's easy to ensure +# that nothing in the "tests" directory can affect the build process. +# +# Author: Lasse Collin +# +############################################################################# + +include(CTest) + +if(BUILD_TESTING) + ################################ + # Windows Application Manifest # + ################################ + + # On Windows (but not on Cygwin or MSYS2) we want to add the + # application manifest to the test programs so that they are + # run in the same configuration as the programs that are installed. + # The same object file can be used for all test programs. + add_library(tests_w32res OBJECT) + + # CMake requires that even an object library must have at least once + # source file. Give it a header file that results in no output files. + target_sources(tests_w32res PRIVATE tests/tests.h) + + # The Ninja Generator requires setting the linker language since it + # cannot guess the programming language of a header file. + set_target_properties(tests_w32res PROPERTIES LINKER_LANGUAGE C) + + target_include_directories(tests_w32res PRIVATE src/common + src/common + src/liblzma/api + ) + + if(WIN32) + target_sources(tests_w32res PRIVATE tests/tests_w32res.rc) + set_source_files_properties(tests/tests_w32res.rc PROPERTIES + OBJECT_DEPENDS "${W32RES_DEPENDENCIES}" + ) + endif() + + ################# + # liblzma tests # + ################# + + set(LIBLZMA_TESTS + test_bcj_exact_size + test_block_header + test_check + test_filter_flags + test_filter_str + test_hardware + test_index + test_index_hash + test_lzip_decoder + test_memlimit + test_stream_flags + test_vli + ) + + # MicroLZMA encoder is needed for both encoder and decoder tests. + # If MicroLZMA decoder is not configured but LZMA1 decoder is, then + # test_microlzma will fail to compile because this configuration is + # not possible in the Autotools build, so the test was not made to + # support it since it would have required additional changes. + if (XZ_MICROLZMA_ENCODER AND (XZ_MICROLZMA_DECODER + OR NOT "lzma1" IN_LIST DECODERS)) + list(APPEND LIBLZMA_TESTS test_microlzma) + endif() + + foreach(TEST IN LISTS LIBLZMA_TESTS) + add_executable("${TEST}" "tests/${TEST}.c") + + target_include_directories("${TEST}" PRIVATE + src/common + src/liblzma/api + src/liblzma + ) + + target_link_libraries("${TEST}" PRIVATE liblzma tests_w32res) + + # Put the test programs into their own subdirectory so they don't + # pollute the top-level dir which might contain xz and xzdec. + set_target_properties("${TEST}" PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tests_bin" + ) + + add_test(NAME "${TEST}" + COMMAND "${CMAKE_CURRENT_BINARY_DIR}/tests_bin/${TEST}" + ) + + # Set srcdir environment variable so that the tests find their + # input files from the source tree. + # + # Set the return code for skipped tests to match Automake convention. + set_tests_properties("${TEST}" PROPERTIES + ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}/tests" + SKIP_RETURN_CODE 77 + ) + endforeach() + + + ########################### + # Command line tool tests # + ########################### + + # Since the CMake-based build doesn't use config.h, the test scripts + # cannot grep the contents of config.h to know which features have + # been disabled. When config.h is missing, they assume that all + # features are enabled. Thus, check if certain groups of features have + # been disabled and then possibly skip some of the tests entirely instead + # of letting them fail. + set(SUPPORTED_FILTERS_SORTED "${SUPPORTED_FILTERS}") + list(SORT SUPPORTED_FILTERS_SORTED) + + set(ENCODERS_SORTED "${XZ_ENCODERS}") + list(SORT ENCODERS_SORTED) + + if("${ENCODERS_SORTED}" STREQUAL "${SUPPORTED_FILTERS_SORTED}") + set(HAVE_ALL_ENCODERS ON) + else() + set(HAVE_ALL_ENCODERS OFF) + endif() + + set(DECODERS_SORTED "${XZ_DECODERS}") + list(SORT DECODERS_SORTED) + + if("${DECODERS_SORTED}" STREQUAL "${SUPPORTED_FILTERS_SORTED}") + set(HAVE_ALL_DECODERS ON) + else() + set(HAVE_ALL_DECODERS OFF) + endif() + + set(SUPPORTED_CHECKS_SORTED "${SUPPORTED_CHECKS}") + list(SORT SUPPORTED_CHECKS_SORTED) + + set(XZ_CHECKS_SORTED "${XZ_CHECKS}") + list(SORT XZ_CHECKS_SORTED) + + if("${SUPPORTED_CHECKS_SORTED}" STREQUAL "${XZ_CHECKS_SORTED}") + set(HAVE_ALL_CHECKS ON) + else() + set(HAVE_ALL_CHECKS OFF) + endif() + + # test_scripts.sh only needs LZMA2 decoder and CRC32. + if(ENABLE_SCRIPTS) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_scripts") + + add_test(NAME test_scripts.sh + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_scripts.sh" ".." + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_scripts" + ) + + set_tests_properties(test_scripts.sh PROPERTIES + ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}/tests" + SKIP_RETURN_CODE 77 + ) + endif() + + # test_suffix.sh only needs LZMA2 encoder and decoder. + if(UNIX AND HAVE_ENCODERS AND HAVE_DECODERS) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_suffix") + + add_test(NAME test_suffix.sh + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_suffix.sh" ".." + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_suffix" + ) + + set_tests_properties(test_suffix.sh PROPERTIES + SKIP_RETURN_CODE 77 + ) + endif() + + # The test_compress.sh based tests compress and decompress using different + # filters so run it only if all encoders and decoders have been enabled. + if(UNIX AND HAVE_ALL_ENCODERS AND HAVE_ALL_DECODERS) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_compress") + + add_executable(create_compress_files tests/create_compress_files.c) + target_link_libraries(create_compress_files PRIVATE tests_w32res) + target_include_directories(create_compress_files PRIVATE src/common) + set_target_properties(create_compress_files PROPERTIES + RUNTIME_OUTPUT_DIRECTORY test_compress) + + foreach(T compress_generated_abc + compress_generated_text + compress_generated_random) + add_test(NAME "test_${T}" + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_compress.sh" + "${T}" ".." + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_compress" + ) + + set_tests_properties("test_${T}" PROPERTIES + ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}/tests" + SKIP_RETURN_CODE 77 + ) + endforeach() + endif() + + # test_files.sh decompresses files that use different filters and + # check types so run it only if support for all of them has been enabled. + if(UNIX AND HAVE_ALL_DECODERS AND HAVE_ALL_CHECKS AND XZ_LZIP_DECODER) + # test_files.sh doesn't make any temporary files but it + # must not be run at the top-level build directory because + # it checks if ../config.h exists. We don't want to read + # files outside the build directory! + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_files") + + add_test(NAME test_files.sh + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_files.sh" ".." + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_files" + ) + + set_tests_properties(test_files.sh PROPERTIES + ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}/tests" + SKIP_RETURN_CODE 77 + ) + endif() +endif() diff --git a/cpp/third_party/xz-5.8.3/tests/tests.h b/cpp/third_party/xz-5.8.3/tests/tests.h new file mode 100644 index 000000000..f706cab88 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/tests.h @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file tests.h +/// \brief Common definitions for test applications +// +// Author: Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef LZMA_TESTS_H +#define LZMA_TESTS_H + +#include "sysdefs.h" +#include "tuklib_integer.h" +#include "lzma.h" +#include "tuktest.h" + + +// Invalid value for the lzma_check enumeration. This must be positive +// but small enough to fit into signed char since the underlying type might +// one some platform be a signed char. +// +// Don't put LZMA_ at the beginning of the name so that it is obvious that +// this constant doesn't come from the API headers. +#define INVALID_LZMA_CHECK_ID ((lzma_check)(LZMA_CHECK_ID_MAX + 1)) + + +// This table and macro allow getting more readable error messages when +// comparing the lzma_ret enumeration values. +static const char enum_strings_lzma_ret[][24] = { + "LZMA_OK", + "LZMA_STREAM_END", + "LZMA_NO_CHECK", + "LZMA_UNSUPPORTED_CHECK", + "LZMA_GET_CHECK", + "LZMA_MEM_ERROR", + "LZMA_MEMLIMIT_ERROR", + "LZMA_FORMAT_ERROR", + "LZMA_OPTIONS_ERROR", + "LZMA_DATA_ERROR", + "LZMA_BUF_ERROR", + "LZMA_PROG_ERROR", + "LZMA_SEEK_NEEDED", +}; + +#define assert_lzma_ret(test_expr, ref_val) \ + assert_enum_eq(test_expr, ref_val, enum_strings_lzma_ret) + + +static const char enum_strings_lzma_check[][24] = { + "LZMA_CHECK_NONE", + "LZMA_CHECK_CRC32", + "LZMA_CHECK_UNKNOWN_2", + "LZMA_CHECK_UNKNOWN_3", + "LZMA_CHECK_CRC64", + "LZMA_CHECK_UNKNOWN_5", + "LZMA_CHECK_UNKNOWN_6", + "LZMA_CHECK_UNKNOWN_7", + "LZMA_CHECK_UNKNOWN_8", + "LZMA_CHECK_UNKNOWN_9", + "LZMA_CHECK_SHA256", + "LZMA_CHECK_UNKNOWN_11", + "LZMA_CHECK_UNKNOWN_12", + "LZMA_CHECK_UNKNOWN_13", + "LZMA_CHECK_UNKNOWN_14", + "LZMA_CHECK_UNKNOWN_15", +}; + +#define assert_lzma_check(test_expr, ref_val) \ + assert_enum_eq(test_expr, ref_val, enum_strings_lzma_check) + +#endif diff --git a/cpp/third_party/xz-5.8.3/tests/tests_w32res.rc b/cpp/third_party/xz-5.8.3/tests/tests_w32res.rc new file mode 100644 index 000000000..0b6c5250c --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/tests_w32res.rc @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: 0BSD */ + +/* + * Author: Lasse Collin + */ + +/* + * It's silly to add version info to test programs but GNU windres fails + * if there are no resources to build, which happens with Autotools on + * Cygwin and MSYS2 because otherwise one more Automake conditional would + * be needed. + */ + +#define MY_TYPE VFT_APP +#define MY_NAME "test" +#define MY_SUFFIX ".exe" +#define MY_DESC "Test program" +#include "common_w32res.rc" diff --git a/cpp/third_party/xz-5.8.3/tests/tuktest.h b/cpp/third_party/xz-5.8.3/tests/tuktest.h new file mode 100644 index 000000000..12abd5324 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/tuktest.h @@ -0,0 +1,1053 @@ +// SPDX-License-Identifier: 0BSD + +/////////////////////////////////////////////////////////////////////////////// +// +/// \file tuktest.h +/// \brief Helper macros for writing simple test programs +/// \version 2024-02-14 +/// +/// Some inspiration was taken from Seatest by Keith Nicholas and +/// from STest which is a fork of Seatest by Jia Tan. +/// +/// This is standard C99/C11 only and thus should be fairly portable +/// outside POSIX systems too. +/// +/// This supports putting multiple tests in a single test program +/// although it is perfectly fine to have only one test per program. +/// Each test can produce one of these results: +/// - Pass +/// - Fail +/// - Skip +/// - Hard error (the remaining tests, if any, are not run) +/// +/// By default this produces an exit status that is compatible with +/// Automake and Meson, and mostly compatible with CMake.[1] +/// If a test program contains multiple tests, only one exit code can +/// be returned. Of the following, the first match is used: +/// - 99 if any test returned a hard error +/// - stdlib.h's EXIT_FAILURE if at least one test failed +/// - 77 if at least one test was skipped or no tests were run at all +/// - stdlib.h's EXIT_SUCCESS (0 on POSIX); that is, if none of the above +/// are true then there was at least one test to run and none of them +/// failed, was skipped, or returned a hard error. +/// +/// A summary of tests being run and their results are printed to stdout. +/// If you want ANSI coloring for the output, #define TUKTEST_COLOR. +/// If you only want output when something goes wrong, #define TUKTEST_QUIET. +/// +/// The downside of the above mapping is that it cannot indicate if +/// some tests were skipped and some passed. If that is likely to +/// happen it may be better to split into multiple test programs (one +/// test per program) or use the TAP mode described below. +/// +/// By using #define TUKTEST_TAP before #including this file the +/// output will be Test Anything Protocol (TAP) version 12 compatible +/// and the exit status will always be EXIT_SUCCESS. This can be easily +/// used with Automake via its tap-driver.sh. Meson supports TAP natively. +/// TAP's todo-directive isn't supported for now, mostly because it's not +/// trivially convertible to the exit-status reporting method. +/// +/// If TUKTEST_TAP is used, TUKTEST_QUIET and TUKTEST_COLOR are ignored. +/// +/// The main() function may look like this (remember to include config.h +/// or such files too if needed!): +/// +/// #include "tuktest.h" +/// +/// int main(int argc, char **argv) +/// { +/// tuktest_start(argc, argv); +/// +/// if (!is_package_foo_available()) +/// tuktest_early_skip("Optional package foo is not available"); +/// +/// if (!do_common_initializations()) +/// tuktest_error("Error during common initializations"); +/// +/// tuktest_run(testfunc1); +/// tuktest_run(testfunc2); +/// +/// return tuktest_end(); +/// } +/// +/// Using exit(tuktest_end()) as a pair to tuktest_start() is OK too. +/// +/// Each test function called via tuktest_run() should be of type +/// "void testfunc1(void)". The test functions should use the +/// various assert_CONDITION() macros. The current test stops if +/// an assertion fails (this is implemented with setjmp/longjmp). +/// Execution continues from the next test unless the failure was +/// due to assert_error() (indicating a hard error) which makes +/// the program exit() without running any remaining tests. +/// +/// Search for "define assert" in this file to find the explanations +/// of the available assertion macros. +/// +/// IMPORTANT: +/// +/// - The assert_CONDITION() macros may only be used by code that is +/// called via tuktest_run()! This includes the function named in +/// the tuktest_run() call and functions called further from there. +/// (The assert_CONDITION() macros depend on setup code in tuktest_run() +/// and other use results in undefined behavior.) +/// +/// - tuktest_start(), tuktest_early_skip, tuktest_run(), and tuktest_end() +/// must not be used in the tests called via tuktest_run()! (tuktest_end() +/// is called more freely internally by this file but such use isn't part +/// of the API.) +/// +/// - tuktest_error(), tuktest_malloc(), tuktest_free(), +/// tuktest_file_from_srcdir(), and tuktest_file_from_builddir() +/// can be used everywhere after tuktest_start() has been called. +/// (In tests running under tuktest_run(), assert_error() can be used +/// instead of tuktest_error() when a hard error occurs.) +/// +/// - Everything else is for internal use only. +/// +/// Footnotes: +/// +/// [1] As of 2022-06-02: +/// See the Automake manual "info (automake)Scripts-based Testsuites" or: +/// https://www.gnu.org/software/automake/manual/automake.html#Scripts_002dbased-Testsuites +/// +/// Meson: https://mesonbuild.com/Unit-tests.html +/// +/// CMake handles passing and failing tests by default but treats hard +/// errors as regular fails. To make CMake support skipped tests +/// correctly, one has to set the SKIP_RETURN_CODE property for each test: +/// +/// set_tests_properties(foo_test_name PROPERTIES SKIP_RETURN_CODE 77) +/// +/// See: +/// https://cmake.org/cmake/help/latest/command/set_tests_properties.html +/// https://cmake.org/cmake/help/latest/prop_test/SKIP_RETURN_CODE.html +// +// Author: Lasse Collin +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TUKTEST_H +#define TUKTEST_H + +#include + +// On some (too) old systems inttypes.h doesn't exist or isn't good enough. +// Include it conditionally so that any portability tricks can be done before +// tuktest.h is included. On any modern system inttypes.h is fine as is. +#ifndef PRIu64 +# include +#endif + +#include +#include +#include +#include + + +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define TUKTEST_GNUC_REQ(major, minor) \ + ((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \ + || __GNUC__ > (major)) +#else +# define TUKTEST_GNUC_REQ(major, minor) 0 +#endif + + +// This is silencing warnings about unused functions. Not all test programs +// need all functions from this header. +#if TUKTEST_GNUC_REQ(3, 0) || defined(__clang__) +# define tuktest_maybe_unused __attribute__((__unused__)) +#else +# define tuktest_maybe_unused +#endif + +// We need printf("") so silence the warning about empty format string. +#if TUKTEST_GNUC_REQ(4, 2) || defined(__clang__) +# pragma GCC diagnostic ignored "-Wformat-zero-length" +#endif + + +// Types and printf format macros to use in integer assertions and also for +// printing size_t values (C99's %zu isn't available on very old systems). +typedef int64_t tuktest_int; +typedef uint64_t tuktest_uint; +#define TUKTEST_PRId PRId64 +#define TUKTEST_PRIu PRIu64 +#define TUKTEST_PRIX PRIX64 + + +// When TAP mode isn't used, Automake-compatible exit statuses are used. +#define TUKTEST_EXIT_PASS EXIT_SUCCESS +#define TUKTEST_EXIT_FAIL EXIT_FAILURE +#define TUKTEST_EXIT_SKIP 77 +#define TUKTEST_EXIT_ERROR 99 + + +enum tuktest_result { + TUKTEST_PASS, + TUKTEST_FAIL, + TUKTEST_SKIP, + TUKTEST_ERROR, +}; + + +#ifdef TUKTEST_TAP +# undef TUKTEST_QUIET +# undef TUKTEST_COLOR +# undef TUKTEST_TAP +# define TUKTEST_TAP 1 +# define TUKTEST_STR_PASS "ok -" +# define TUKTEST_STR_FAIL "not ok -" +# define TUKTEST_STR_SKIP "ok - # SKIP" +# define TUKTEST_STR_ERROR "Bail out!" +#else +# define TUKTEST_TAP 0 +# ifdef TUKTEST_COLOR +# define TUKTEST_COLOR_PASS "\x1B[0;32m" +# define TUKTEST_COLOR_FAIL "\x1B[0;31m" +# define TUKTEST_COLOR_SKIP "\x1B[1;34m" +# define TUKTEST_COLOR_ERROR "\x1B[0;35m" +# define TUKTEST_COLOR_TOTAL "\x1B[1m" +# define TUKTEST_COLOR_OFF "\x1B[m" +# define TUKTEST_COLOR_IF(cond, color) ((cond) ? (color) : "" ) +# else +# define TUKTEST_COLOR_PASS "" +# define TUKTEST_COLOR_FAIL "" +# define TUKTEST_COLOR_SKIP "" +# define TUKTEST_COLOR_ERROR "" +# define TUKTEST_COLOR_TOTAL "" +# define TUKTEST_COLOR_OFF "" +# define TUKTEST_COLOR_IF(cond, color) "" +# endif +# define TUKTEST_COLOR_ADD(str, color) color str TUKTEST_COLOR_OFF +# define TUKTEST_STR_PASS \ + TUKTEST_COLOR_ADD("PASS:", TUKTEST_COLOR_PASS) +# define TUKTEST_STR_FAIL \ + TUKTEST_COLOR_ADD("FAIL:", TUKTEST_COLOR_FAIL) +# define TUKTEST_STR_SKIP \ + TUKTEST_COLOR_ADD("SKIP:", TUKTEST_COLOR_SKIP) +# define TUKTEST_STR_ERROR \ + TUKTEST_COLOR_ADD("ERROR:", TUKTEST_COLOR_ERROR) +#endif + +// NOTE: If TUKTEST_TAP is defined then TUKTEST_QUIET will get undefined above. +#ifndef TUKTEST_QUIET +# define TUKTEST_QUIET 0 +#else +# undef TUKTEST_QUIET +# define TUKTEST_QUIET 1 +#endif + + +// Counts of the passed, failed, skipped, and hard-errored tests. +// This is indexed with the enumeration constants from enum tuktest_result. +static unsigned tuktest_stats[4] = { 0, 0, 0, 0 }; + +// Copy of argc and argv from main(). These are set by tuktest_start(). +static int tuktest_argc = 0; +static char **tuktest_argv = NULL; + +// Name of the currently-running test. This exists because it's nice +// to print the main test function name even if the failing test-assertion +// fails in a function called by the main test function. +static const char *tuktest_name = NULL; + +// longjmp() target for when a test-assertion fails. +static jmp_buf tuktest_jmpenv; + + +// This declaration is needed for tuktest_malloc(). +static int tuktest_end(void); + + +// Internal helper for handling hard errors both inside and +// outside tuktest_run(). +#define tuktest_error_impl(filename, line, ...) \ +do { \ + tuktest_print_result_prefix(TUKTEST_ERROR, filename, line); \ + printf(__VA_ARGS__); \ + printf("\n"); \ + ++tuktest_stats[TUKTEST_ERROR]; \ + exit(tuktest_end()); \ +} while (0) + + +// printf() is without checking its return value in many places. This function +// is called before exiting to check the status of stdout and catch errors. +static void +tuktest_catch_stdout_errors(void) +{ + if (ferror(stdout) || fclose(stdout)) { + fputs("Error while writing to stdout\n", stderr); + exit(TUKTEST_EXIT_ERROR); + } +} + + +// A simplified basename()-like function that is good enough for +// cleaning up __FILE__. This supports / and \ as path separator. +// If the path separator is wrong then the full path will be printed; +// it's a cosmetic problem only. +static const char * +tuktest_basename(const char *filename) +{ + for (const char *p = filename + strlen(filename); p > filename; --p) + if (*p == '/' || *p == '\\') + return p + 1; + + return filename; +} + + +// Internal helper that prints the prefix of the fail/skip/error message line. +static void +tuktest_print_result_prefix(enum tuktest_result result, + const char *filename, unsigned line) +{ + // This is never called with TUKTEST_PASS but I kept it here anyway. + const char *result_str + = result == TUKTEST_PASS ? TUKTEST_STR_PASS + : result == TUKTEST_FAIL ? TUKTEST_STR_FAIL + : result == TUKTEST_SKIP ? TUKTEST_STR_SKIP + : TUKTEST_STR_ERROR; + + const char *short_filename = tuktest_basename(filename); + + if (tuktest_name != NULL) + printf("%s %s [%s:%u] ", result_str, tuktest_name, + short_filename, line); + else + printf("%s [%s:%u] ", result_str, short_filename, line); +} + + +// An entry for linked list of memory allocations. +struct tuktest_malloc_record { + struct tuktest_malloc_record *next; + void *p; +}; + +// Linked list of per-test allocations. This is used when under tuktest_run(). +// These allocations are freed in tuktest_run() and, in case of a hard error, +// also in tuktest_end(). +static struct tuktest_malloc_record *tuktest_malloc_test = NULL; + +// Linked list of global allocations. This is used allocations are made +// outside tuktest_run(). These are freed in tuktest_end(). +static struct tuktest_malloc_record *tuktest_malloc_global = NULL; + + +/// A wrapper for malloc() that never return NULL and the allocated memory is +/// automatically freed at the end of tuktest_run() (if allocation was done +/// within a test) or early in tuktest_end() (if allocation was done outside +/// tuktest_run()). +/// +/// If allocation fails, a hard error is reported and this function won't +/// return. Possible other tests won't be run (this will call exit()). +#define tuktest_malloc(size) tuktest_malloc_impl(size, __FILE__, __LINE__) + +static void * +tuktest_malloc_impl(size_t size, const char *filename, unsigned line) +{ + void *p = malloc(size == 0 ? 1 : size); + struct tuktest_malloc_record *r = malloc(sizeof(*r)); + + if (p == NULL || r == NULL) { + free(r); + free(p); + + // Avoid %zu for portability to very old systems that still + // can compile C99 code. + tuktest_error_impl(filename, line, + "tuktest_malloc(%" TUKTEST_PRIu ") failed", + (tuktest_uint)size); + } + + r->p = p; + + if (tuktest_name == NULL) { + // We were called outside tuktest_run(). + r->next = tuktest_malloc_global; + tuktest_malloc_global = r; + } else { + // We were called under tuktest_run(). + r->next = tuktest_malloc_test; + tuktest_malloc_test = r; + } + + return p; +} + + +/// Frees memory allocated using tuktest_malloc(). Usually this isn't needed +/// as the memory is freed automatically. +/// +/// NULL is silently ignored. +/// +/// NOTE: Under tuktest_run() only memory allocated there can be freed. +/// That is, allocations done outside tuktest_run() can only be freed +/// outside tuktest_run(). +#define tuktest_free(ptr) tuktest_free_impl(ptr, __FILE__, __LINE__) + +static void +tuktest_free_impl(void *p, const char *filename, unsigned line) +{ + if (p == NULL) + return; + + struct tuktest_malloc_record **r = tuktest_name != NULL + ? &tuktest_malloc_test : &tuktest_malloc_global; + + while (*r != NULL) { + struct tuktest_malloc_record *tmp = *r; + + if (tmp->p == p) { + *r = tmp->next; + free(p); + free(tmp); + return; + } + + r = &tmp->next; + } + + tuktest_error_impl(filename, line, "tuktest_free: " + "Allocation matching the pointer was not found"); +} + + +// Frees all allocates in the given record list. The argument must be +// either &tuktest_malloc_test or &tuktest_malloc_global. +static void +tuktest_free_all(struct tuktest_malloc_record **r) +{ + while (*r != NULL) { + struct tuktest_malloc_record *tmp = *r; + *r = tmp->next; + free(tmp->p); + free(tmp); + } +} + + +/// Initialize the test framework. No other functions or macros +/// from this file may be called before calling this. +/// +/// If the arguments from main() aren't available, use 0 and NULL. +/// If these are set, then only a subset of tests can be run by +/// specifying their names on the command line. +#define tuktest_start(argc, argv) \ +do { \ + tuktest_argc = argc; \ + tuktest_argv = argv; \ + if (!TUKTEST_TAP && !TUKTEST_QUIET) \ + printf("=== %s ===\n", tuktest_basename(__FILE__)); \ +} while (0) + + +/// If it can be detected early that no tests can be run, this macro can +/// be called after tuktest_start() but before any tuktest_run() to print +/// a reason why the tests were skipped. Note that this macro calls exit(). +/// +/// Using "return tuktest_end();" in main() when no tests were run has +/// the same result as tuktest_early_skip() except that then no reason +/// for the skipping can be printed. +#define tuktest_early_skip(...) \ +do { \ + printf("%s [%s:%u] ", \ + TUKTEST_TAP ? "1..0 # SKIP" : TUKTEST_STR_SKIP, \ + tuktest_basename(__FILE__), __LINE__); \ + printf(__VA_ARGS__); \ + printf("\n"); \ + if (!TUKTEST_TAP && !TUKTEST_QUIET) \ + printf("=== END ===\n"); \ + tuktest_catch_stdout_errors(); \ + exit(TUKTEST_TAP ? EXIT_SUCCESS : TUKTEST_EXIT_SKIP); \ +} while (0) + + +/// Some test programs need to do initializations before or between +/// calls to tuktest_run(). If such initializations unexpectedly fail, +/// tuktest_error() can be used to report it as a hard error outside +/// test functions, for example, in main(). Then the remaining tests +/// won't be run (this macro calls exit()). +/// +/// Typically tuktest_error() would be used before any tuktest_run() +/// calls but it is also possible to use tuktest_error() after one or +/// more tests have been run with tuktest_run(). This is in contrast to +/// tuktest_early_skip() which must never be called after tuktest_run(). +/// +/// NOTE: tuktest_start() must have been called before tuktest_error(). +/// +/// NOTE: This macro can be called from test functions running under +/// tuktest_run() but assert_error() is somewhat preferred in that context. +#define tuktest_error(...) tuktest_error_impl(__FILE__, __LINE__, __VA_ARGS__) + + +/// At the end of main() one should have "return tuktest_end();" which +/// prints the stats or the TAP plan, and handles the exit status. +/// Using exit(tuktest_end()) is OK too. +/// +/// If the test program can detect early that all tests must be skipped, +/// then tuktest_early_skip() may be useful so that the reason why the +/// tests were skipped can be printed. +static int +tuktest_end(void) +{ + tuktest_free_all(&tuktest_malloc_test); + tuktest_free_all(&tuktest_malloc_global); + + unsigned total_tests = 0; + for (unsigned i = 0; i <= TUKTEST_ERROR; ++i) + total_tests += tuktest_stats[i]; + + if (tuktest_stats[TUKTEST_ERROR] == 0 && tuktest_argc > 1 + && (unsigned)(tuktest_argc - 1) > total_tests) { + printf(TUKTEST_STR_ERROR " Fewer tests were run than " + "specified on the command line. " + "Was a test name mistyped?\n"); + ++tuktest_stats[TUKTEST_ERROR]; + } + +#if TUKTEST_TAP + // Print the plan only if no "Bail out!" has occurred. + // Print the skip directive if no tests were run. + // We cannot know the reason for the skip here though + // (see tuktest_early_skip()). + if (tuktest_stats[TUKTEST_ERROR] == 0) + printf("1..%u%s\n", total_tests, + total_tests == 0 ? " # SKIP" : ""); + + tuktest_catch_stdout_errors(); + return EXIT_SUCCESS; +#else + if (!TUKTEST_QUIET) + printf("---\n" + "%s# TOTAL: %u" TUKTEST_COLOR_OFF "\n" + "%s# PASS: %u" TUKTEST_COLOR_OFF "\n" + "%s# SKIP: %u" TUKTEST_COLOR_OFF "\n" + "%s# FAIL: %u" TUKTEST_COLOR_OFF "\n" + "%s# ERROR: %u" TUKTEST_COLOR_OFF "\n" + "=== END ===\n", + TUKTEST_COLOR_TOTAL, + total_tests, + TUKTEST_COLOR_IF( + tuktest_stats[TUKTEST_PASS] > 0, + TUKTEST_COLOR_PASS), + tuktest_stats[TUKTEST_PASS], + TUKTEST_COLOR_IF( + tuktest_stats[TUKTEST_SKIP] > 0, + TUKTEST_COLOR_SKIP), + tuktest_stats[TUKTEST_SKIP], + TUKTEST_COLOR_IF( + tuktest_stats[TUKTEST_FAIL] > 0, + TUKTEST_COLOR_FAIL), + tuktest_stats[TUKTEST_FAIL], + TUKTEST_COLOR_IF( + tuktest_stats[TUKTEST_ERROR] > 0, + TUKTEST_COLOR_ERROR), + tuktest_stats[TUKTEST_ERROR]); + + tuktest_catch_stdout_errors(); + + if (tuktest_stats[TUKTEST_ERROR] > 0) + return TUKTEST_EXIT_ERROR; + + if (tuktest_stats[TUKTEST_FAIL] > 0) + return TUKTEST_EXIT_FAIL; + + if (tuktest_stats[TUKTEST_SKIP] > 0 || total_tests == 0) + return TUKTEST_EXIT_SKIP; + + return TUKTEST_EXIT_PASS; +#endif +} + + +/// Runs the specified test function. Requires that tuktest_start() +/// has already been called and that tuktest_end() has NOT been called yet. +#define tuktest_run(testfunc) \ + tuktest_run_test(&(testfunc), #testfunc) + +tuktest_maybe_unused +static void +tuktest_run_test(void (*testfunc)(void), const char *testfunc_str) +{ + // If any command line arguments were given, only the test functions + // named on the command line will be run. + if (tuktest_argc > 1) { + int i = 1; + while (strcmp(tuktest_argv[i], testfunc_str) != 0) + if (++i == tuktest_argc) + return; + } + + // This is set so that failed assertions can print the correct + // test name even when the assertion is in a helper function + // called by the test function. + tuktest_name = testfunc_str; + + // The way setjmp() may be called is very restrictive. + // A switch statement is one of the few conforming ways + // to get the value passed to longjmp(); doing something + // like "int x = setjmp(env)" is NOT allowed (undefined behavior). + switch (setjmp(tuktest_jmpenv)) { + case 0: + testfunc(); + ++tuktest_stats[TUKTEST_PASS]; + if (!TUKTEST_QUIET) + printf(TUKTEST_STR_PASS " %s\n", tuktest_name); + break; + + case TUKTEST_FAIL: + ++tuktest_stats[TUKTEST_FAIL]; + break; + + case TUKTEST_SKIP: + ++tuktest_stats[TUKTEST_SKIP]; + break; + + default: + ++tuktest_stats[TUKTEST_ERROR]; + exit(tuktest_end()); + } + + tuktest_free_all(&tuktest_malloc_test); + tuktest_name = NULL; +} + + +// Maximum allowed file size in tuktest_file_from_* macros and functions. +#ifndef TUKTEST_FILE_SIZE_MAX +# define TUKTEST_FILE_SIZE_MAX (64L << 20) +#endif + +/// Allocates memory and reads the specified file into a buffer. +/// If the environment variable srcdir is set, it will be prefixed +/// to the filename. Otherwise the filename is used as is (and so +/// the behavior is identical to tuktest_file_from_builddir() below). +/// +/// On success the a pointer to malloc'ed memory is returned. +/// The size of the allocation and the file is stored in *size. +/// +/// If anything goes wrong, a hard error is reported and this function +/// won't return. Possible other tests won't be run (this will call exit()). +/// +/// Empty files and files over TUKTEST_FILE_SIZE_MAX are rejected. +/// The assumption is that something is wrong in these cases. +/// +/// This function can be called either from outside the tests (like in main()) +/// or from tests run via tuktest_run(). Remember to free() the memory to +/// keep Valgrind happy. +#define tuktest_file_from_srcdir(filename, sizeptr) \ + tuktest_file_from_x(getenv("srcdir"), filename, sizeptr, \ + __FILE__, __LINE__) + +/// Like tuktest_file_from_srcdir except this reads from the current directory. +#define tuktest_file_from_builddir(filename, sizeptr) \ + tuktest_file_from_x(NULL, filename, sizeptr, __FILE__, __LINE__) + +// Internal helper for the macros above. +tuktest_maybe_unused +static void * +tuktest_file_from_x(const char *prefix, const char *filename, size_t *size, + const char *prog_filename, unsigned prog_line) +{ + // If needed: buffer for holding prefix + '/' + filename + '\0'. + char *alloc_name = NULL; + + // Buffer for the data read from the file. + void *buf = NULL; + + // File being read + FILE *f = NULL; + + // Error message to use under the "error:" label. + const char *error_msg = NULL; + + if (filename == NULL) { + error_msg = "Filename is NULL"; + filename = "(NULL)"; + goto error; + } + + if (filename[0] == '\0') { + error_msg = "Filename is an empty string"; + filename = "(empty string)"; + goto error; + } + + if (size == NULL) { + error_msg = "The size argument is NULL"; + goto error; + } + + // If a prefix was given, construct the full filename. + if (prefix != NULL && prefix[0] != '\0') { + const size_t prefix_len = strlen(prefix); + const size_t filename_len = strlen(filename); + + const size_t alloc_name_size + = prefix_len + 1 + filename_len + 1; + alloc_name = tuktest_malloc_impl(alloc_name_size, + prog_filename, prog_line); + + memcpy(alloc_name, prefix, prefix_len); + alloc_name[prefix_len] = '/'; + memcpy(alloc_name + prefix_len + 1, filename, filename_len); + alloc_name[prefix_len + 1 + filename_len] = '\0'; + + // Set filename to point to the new string. alloc_name + // can be freed unconditionally as it is NULL if a prefix + // wasn't specified. + filename = alloc_name; + } + + f = fopen(filename, "rb"); + if (f == NULL) { + error_msg = "Failed to open the file"; + goto error; + } + + // Get the size of the file and store it in *size. + // + // We assume that the file isn't big and even reject very big files. + // There is no need to use fseeko/ftello from POSIX to support + // large files. Using standard C functions is portable outside POSIX. + if (fseek(f, 0, SEEK_END) != 0) { + error_msg = "Seeking failed (fseek end)"; + goto error; + } + + const long end = ftell(f); + if (end < 0) { + error_msg = "Seeking failed (ftell)"; + goto error; + } + + if (end == 0) { + error_msg = "File is empty"; + goto error; + } + + if (end > TUKTEST_FILE_SIZE_MAX) { + error_msg = "File size exceeds TUKTEST_FILE_SIZE_MAX"; + goto error; + } + + *size = (size_t)end; + rewind(f); + + buf = tuktest_malloc_impl(*size, prog_filename, prog_line); + + const size_t amount = fread(buf, 1, *size, f); + if (ferror(f)) { + error_msg = "Read error"; + goto error; + } + + if (amount != *size) { + error_msg = "File is smaller than indicated by ftell()"; + goto error; + } + + const int fclose_ret = fclose(f); + f = NULL; + if (fclose_ret != 0) { + error_msg = "Error closing the file"; + goto error; + } + + tuktest_free(alloc_name); + return buf; + +error: + if (f != NULL) + (void)fclose(f); + + tuktest_error_impl(prog_filename, prog_line, + "tuktest_file_from_x: %s: %s\n", filename, error_msg); +} + + +// Internal helper for assert_fail, assert_skip, and assert_error. +#define tuktest_print_and_jump(result, ...) \ +do { \ + tuktest_print_result_prefix(result, __FILE__, __LINE__); \ + printf(__VA_ARGS__); \ + printf("\n"); \ + longjmp(tuktest_jmpenv, result); \ +} while (0) + + +/// Unconditionally fails the test (non-zero exit status if not using TAP). +/// Execution will continue from the next test. +/// +/// A printf format string is supported. +/// If no extra message is wanted, use "" as the argument. +#define assert_fail(...) tuktest_print_and_jump(TUKTEST_FAIL, __VA_ARGS__) + + +/// Skips the test (exit status 77 if not using TAP). +/// Execution will continue from the next test. +/// +/// If you can detect early that no tests can be run, tuktest_early_skip() +/// might be a better way to skip the test(s). Especially in TAP mode this +/// makes a difference as with assert_skip() it will list a skipped specific +/// test name but with tuktest_early_skip() it will indicate that the whole +/// test program was skipped (with tuktest_early_skip() the TAP plan will +/// indicate zero tests). +/// +/// A printf format string is supported. +/// If no extra message is wanted, use "" as the argument. +#define assert_skip(...) tuktest_print_and_jump(TUKTEST_SKIP, __VA_ARGS__) + + +/// Hard error (exit status 99 if not using TAP). +/// The remaining tests in this program will not be run or reported. +/// +/// A printf format string is supported. +/// If no extra message is wanted, use "" as the argument. +#define assert_error(...) tuktest_print_and_jump(TUKTEST_ERROR, __VA_ARGS__) + + +/// Fails the test if the test expression doesn't evaluate to false. +#define assert_false(test_expr) \ +do { \ + if (test_expr) \ + assert_fail("assert_fail: '%s' is true but should be false", \ + #test_expr); \ +} while (0) + + +/// Fails the test if the test expression doesn't evaluate to true. +#define assert_true(test_expr) \ +do { \ + if (!(test_expr)) \ + assert_fail("assert_true: '%s' is false but should be true", \ + #test_expr); \ +} while (0) + + +/// Fails the test if comparing the signed integer expressions using the +/// specified comparison operator evaluates to false. For example, +/// assert_int(foobar(), >=, 0) fails the test if 'foobar() >= 0' isn't true. +/// For good error messages, the first argument should be the test expression +/// and the third argument the reference value (usually a constant). +/// +/// For equality (==) comparison there is a assert_int_eq() which +/// might be more convenient to use. +#define assert_int(test_expr, cmp_op, ref_value) \ +do { \ + const tuktest_int v_test_ = (test_expr); \ + const tuktest_int v_ref_ = (ref_value); \ + if (!(v_test_ cmp_op v_ref_)) \ + assert_fail("assert_int: '%s == %" TUKTEST_PRId \ + "' but expected '... %s %" TUKTEST_PRId "'", \ + #test_expr, v_test_, #cmp_op, v_ref_); \ +} while (0) + + +/// Like assert_int() but for unsigned integers. +/// +/// For equality (==) comparison there is a assert_uint_eq() which +/// might be more convenient to use. +#define assert_uint(test_expr, cmp_op, ref_value) \ +do { \ + const tuktest_uint v_test_ = (test_expr); \ + const tuktest_uint v_ref_ = (ref_value); \ + if (!(v_test_ cmp_op v_ref_)) \ + assert_fail("assert_uint: '%s == %" TUKTEST_PRIu \ + "' but expected '... %s %" TUKTEST_PRIu "'", \ + #test_expr, v_test_, #cmp_op, v_ref_); \ +} while (0) + + +/// Fails the test if test expression doesn't equal the expected +/// signed integer value. +#define assert_int_eq(test_expr, ref_value) \ + assert_int(test_expr, ==, ref_value) + + +/// Fails the test if test expression doesn't equal the expected +/// unsigned integer value. +#define assert_uint_eq(test_expr, ref_value) \ + assert_uint(test_expr, ==, ref_value) + + +/// Fails the test if the test expression doesn't equal the expected +/// enumeration value. This is like assert_int_eq() but the error message +/// shows the enumeration constant names instead of their numeric values +/// as long as the values are non-negative and not big. +/// +/// The third argument must be a table of string pointers. A pointer to +/// a pointer doesn't work because this determines the number of elements +/// in the array using sizeof. For example: +/// +/// const char *my_enum_names[] = { "MY_FOO", "MY_BAR", "MY_BAZ" }; +/// assert_enum_eq(some_func_returning_my_enum(), MY_BAR, my_enum_names); +/// +/// (If the reference value is out of bounds, both values are printed as +/// an integer. If only test expression is out of bounds, it is printed +/// as an integer and the reference as a string. Otherwise both are printed +/// as a string.) +#define assert_enum_eq(test_expr, ref_value, enum_strings) \ +do { \ + const tuktest_int v_test_ = (test_expr); \ + const tuktest_int v_ref_ = (ref_value); \ + if (v_test_ != v_ref_) { \ + const int array_len_ = (int)(sizeof(enum_strings) \ + / sizeof((enum_strings)[0])); \ + if (v_ref_ < 0 || v_ref_ >= array_len_) \ + assert_fail("assert_enum_eq: '%s == %" TUKTEST_PRId \ + "' but expected " \ + "'... == %" TUKTEST_PRId "'", \ + #test_expr, v_test_, v_ref_); \ + else if (v_test_ < 0 || v_test_ >= array_len_) \ + assert_fail("assert_enum_eq: '%s == %" TUKTEST_PRId \ + "' but expected '... == %s'", \ + #test_expr, v_test_, \ + (enum_strings)[v_ref_]); \ + else \ + assert_fail("assert_enum_eq: '%s == %s' " \ + "but expected '... = %s'", \ + #test_expr, (enum_strings)[v_test_], \ + (enum_strings)[v_ref_]); \ + } \ +} while (0) + + +/// Fails the test if the specified bit isn't set in the test expression. +#define assert_bit_set(test_expr, bit) \ +do { \ + const tuktest_uint v_test_ = (test_expr); \ + const unsigned v_bit_ = (bit); \ + const tuktest_uint v_mask_ = (tuktest_uint)1 << v_bit_; \ + if (!(v_test_ & v_mask_)) \ + assert_fail("assert_bit_set: '%s == 0x%" TUKTEST_PRIX \ + "' but bit %u (0x%" TUKTEST_PRIX ") " \ + "is not set", \ + #test_expr, v_test_, v_bit_, v_mask_); \ +} while (0) + + +/// Fails the test if the specified bit is set in the test expression. +#define assert_bit_not_set(test_expr, bit) \ +do { \ + const tuktest_uint v_test_ = (test_expr); \ + const unsigned v_bit_ = (bit); \ + const tuktest_uint v_mask_ = (tuktest_uint)1 << v_bit_; \ + if (v_test_ & v_mask_) \ + assert_fail("assert_bit_not_set: '%s == 0x%" TUKTEST_PRIX \ + "' but bit %u (0x%" TUKTEST_PRIX ") is set", \ + #test_expr, v_test_, v_bit_, v_mask_); \ +} while (0) + + +/// Fails the test if unless all bits that are set in the bitmask are also +/// set in the test expression. +#define assert_bitmask_set(test_expr, mask) \ +do { \ + const tuktest_uint v_mask_ = (mask); \ + const tuktest_uint v_test_ = (test_expr) & v_mask_; \ + if (v_test_ != v_mask_) \ + assert_fail("assert_bitmask_set: " \ + "'((%s) & 0x%" TUKTEST_PRIX ") == " \ + "0x%" TUKTEST_PRIX "' but expected " \ + "'... == 0x%" TUKTEST_PRIX "'", \ + #test_expr, v_mask_, v_test_, v_mask_); \ +} while (0) + + +/// Fails the test if any of the bits that are set in the bitmask are also +/// set in the test expression. +#define assert_bitmask_not_set(test_expr, mask) \ +do { \ + const tuktest_uint v_mask_ = (mask); \ + const tuktest_uint v_test_ = (test_expr) & v_mask_; \ + if (v_test_ != 0) \ + assert_fail("assert_bitmask_not_set: "\ + "'((%s) & 0x%" TUKTEST_PRIX ") == " \ + "0x%" TUKTEST_PRIX "' but expected " \ + "'... == 0'", \ + #test_expr, v_mask_, v_test_); \ +} while (0) + + +// Internal helper to add common code for string assertions. +#define tuktest_str_helper1(macro_name, test_expr, ref_value) \ + const char *v_test_ = (test_expr); \ + const char *v_ref_ = (ref_value); \ + if (v_test_ == NULL) \ + assert_fail(macro_name ": Test expression '%s' is NULL", \ + #test_expr); \ + if (v_ref_ == NULL) \ + assert_fail(macro_name ": Reference value '%s' is NULL", \ + #ref_value) + + +// Internal helper to add common code for string assertions and to check +// that the reference value isn't an empty string. +#define tuktest_str_helper2(macro_name, test_expr, ref_value) \ + tuktest_str_helper1(macro_name, test_expr, ref_value); \ + if (v_ref_[0] == '\0') \ + assert_fail(macro_name ": Reference value is an empty string") + + +/// Fails the test if the test expression evaluates to string that doesn't +/// equal to the expected string. +#define assert_str_eq(test_expr, ref_value) \ +do { \ + tuktest_str_helper1("assert_str_eq", test_expr, ref_value); \ + if (strcmp(v_ref_, v_test_) != 0) \ + assert_fail("assert_str_eq: '%s' evaluated to '%s' " \ + "but expected '%s'", \ + #test_expr, v_test_, v_ref_); \ +} while (0) + + +/// Fails the test if the test expression evaluates to a string that doesn't +/// contain the reference value as a substring. Also fails the test if +/// the reference value is an empty string. +#define assert_str_contains(test_expr, ref_value) \ +do { \ + tuktest_str_helper2("assert_str_contains", test_expr, ref_value); \ + if (strstr(v_test_, v_ref_) == NULL) \ + assert_fail("assert_str_contains: '%s' evaluated to '%s' " \ + "which doesn't contain '%s'", \ + #test_expr, v_test_, v_ref_); \ +} while (0) + + +/// Fails the test if the test expression evaluates to a string that +/// contains the reference value as a substring. Also fails the test if +/// the reference value is an empty string. +#define assert_str_doesnt_contain(test_expr, ref_value) \ +do { \ + tuktest_str_helper2("assert_str_doesnt_contain", \ + test_expr, ref_value); \ + if (strstr(v_test_, v_ref_) != NULL) \ + assert_fail("assert_str_doesnt_contain: " \ + "'%s' evaluated to '%s' which contains '%s'", \ + #test_expr, v_test_, v_ref_); \ +} while (0) + + +/// Fails the test if the first array_size elements of the test array +/// don't equal to correct_array. +/// +/// NOTE: This avoids %zu for portability to very old systems that still +/// can compile C99 code. +#define assert_array_eq(test_array, correct_array, array_size) \ +do { \ + for (size_t i_ = 0; i_ < (array_size); ++i_) \ + if ((test_array)[i_] != (correct_array)[i_]) \ + assert_fail("assert_array_eq: " \ + "%s[%" TUKTEST_PRIu "] != "\ + "%s[%" TUKTEST_PRIu "] " \ + "but should be equal", \ + #test_array, (tuktest_uint)i_, \ + #correct_array, (tuktest_uint)i_); \ +} while (0) + +#endif diff --git a/cpp/third_party/xz-5.8.3/tests/xzgrep_expected_output b/cpp/third_party/xz-5.8.3/tests/xzgrep_expected_output new file mode 100644 index 000000000..e531d9316 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/tests/xzgrep_expected_output @@ -0,0 +1,39 @@ +=> xzgrep el <= +xzgrep_test_1.xz:elit, sed do eiusmod tempor incididunt ut +xzgrep_test_1.xz:in voluptate velit esse cillum dolore eu +xzgrep_test_2.xz:Hello +retval 0 +=> xzgrep -l el <= +xzgrep_test_1.xz +xzgrep_test_2.xz +retval 0 +=> xzgrep -h el <= +elit, sed do eiusmod tempor incididunt ut +in voluptate velit esse cillum dolore eu +Hello +retval 0 +=> xzgrep -H el <= +xzgrep_test_1.xz:elit, sed do eiusmod tempor incididunt ut +xzgrep_test_1.xz:in voluptate velit esse cillum dolore eu +xzgrep_test_2.xz:Hello +retval 0 +=> xzgrep Hello <= +xzgrep_test_2.xz:Hello +retval 0 +=> xzgrep -l Hello <= +xzgrep_test_2.xz +retval 0 +=> xzgrep -h Hello <= +Hello +retval 0 +=> xzgrep -H Hello <= +xzgrep_test_2.xz:Hello +retval 0 +=> xzgrep NOMATCH <= +retval 1 +=> xzgrep -l NOMATCH <= +retval 1 +=> xzgrep -h NOMATCH <= +retval 1 +=> xzgrep -H NOMATCH <= +retval 1 diff --git a/cpp/third_party/xz-5.8.3/windows/INSTALL-MSVC.txt b/cpp/third_party/xz-5.8.3/windows/INSTALL-MSVC.txt new file mode 100644 index 000000000..e92175b6b --- /dev/null +++ b/cpp/third_party/xz-5.8.3/windows/INSTALL-MSVC.txt @@ -0,0 +1,44 @@ + +Building XZ Utils with Microsoft Visual Studio +============================================== + +Introduction +------------ + + liblzma got MSVC support in XZ Utils 5.2.0, and the xz, xzdec, + lzmadec, and lzmainfo command line tools in XZ Utils 5.6.0. + + Visual Studio 2015 and later are supported. + + NOTE: The *.exe files are linked against GNU getopt_long from + the "lib" directory. That code is under the GNU LGPLv2.1 + and thus the matching source code must be provided when + distributing the *.exe files. The simplest way to comply with + the license requirements is to distribute the matching XZ Utils + source package alongside the *.exe files. + + +Building +-------- + + Use CMake to generate build files for MSVC. Visual Studio project + files are no longer provided (XZ Utils 5.4.x were the last versions + to include the project files). + + NOTE: GCC and Clang compatible inline assembly isn't supported by + the MSVC compiler. Using clang-cl under MSVC should make inline + assembly work (untested). + + +Notes +----- + + liblzma API headers declare the functions with __declspec(dllimport) + by default. To avoid this when using static liblzma from your code, + #define LZMA_API_STATIC before #including . + + MSVC gives a bunch of compiler warnings. Some warnings are specific + to 32-bit or 64-bit build and some appear for both builds. These + are known and shouldn't be a problem. Some of them will probably + be fixed in the future. + diff --git a/cpp/third_party/xz-5.8.3/windows/INSTALL-MinGW-w64_with_Autotools.txt b/cpp/third_party/xz-5.8.3/windows/INSTALL-MinGW-w64_with_Autotools.txt new file mode 100644 index 000000000..89c744092 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/windows/INSTALL-MinGW-w64_with_Autotools.txt @@ -0,0 +1,49 @@ + +Creating XZ Utils Windows package with build.bash +================================================= + +Introduction +------------ + + The script build.bash can be used for building XZ Utils with + GCC + MinGW-w64 under MSYS2, under the ancient MSYS, or + cross-compiling from GNU/Linux. The script will create a package + with binaries and documentation in a hopefully-convenient bundle. + + NOTE: build.bash requires files that are only included + in release tarballs. If building from xz.git, a distribution + tarball should be created first. + + For native builds on Windows, the CMake-based build described + in the file INSTALL-MinGW-w64_with_CMake.txt is simpler to do as + it has no need for MSYS2 and it works from xz.git without extra + steps. For cross-compilation and package creation the script can + be convenient though. + + These instructions are for making a package with build.bash and thus + don't apply to normal Autotool-based builds under Cygwin or MSYS2. + + +Usage +----- + + First copy the file COPYING.MinGW-w64-runtime.txt from MinGW-w64 + to this directory. It contains copyright and license notices that + apply to the MinGW-w64 runtime that gets statically linked into + the XZ Utils binaries being built. build.bash will include the file + in the final package. + + Put i686 and/or x86_64 GCC-based toolchain in PATH depending on + which builds are wanted. + + Optional: Put the 7z tool from 7-Zip or p7zip in PATH. Without + this, .zip and .7z files won't be created from the finished "pkg" + directory contents. + + Run build.bash: + + bash windows/build.bash + + Note that it does an in-tree build so the build files will be mixed + with the source files in the same directory tree. + diff --git a/cpp/third_party/xz-5.8.3/windows/INSTALL-MinGW-w64_with_CMake.txt b/cpp/third_party/xz-5.8.3/windows/INSTALL-MinGW-w64_with_CMake.txt new file mode 100644 index 000000000..191beae39 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/windows/INSTALL-MinGW-w64_with_CMake.txt @@ -0,0 +1,211 @@ + +Building XZ Utils on Windows using MinGW-w64 and CMake +====================================================== + + 1. Introduction + 1.1. Licensing considerations + 2. MSVCRT or UCRT + 3. CMake + 4. MinGW-w64 toolchains + 4.1. MinGW-w64 with GCC + 4.2. MinGW-w64 with Clang/LLVM + 5. Building XZ Utils + 5.1. Advanced build options + 6. Creating an import library for MSVC / Visual Studio + + +1. Introduction +--------------- + + This document explains how to build XZ Utils using MinGW-w64, + GCC or Clang/LLVM, CMake, and GNU make (mingw32-make) natively + on Windows. The resulting XZ Utils library and executable files + will only depend on DLLs that are included in Windows. + + The build tools can be extracted into separate directories and used + directly from there and deleted when no longer needed. There are no + installers to run for these and no configuration needed. + + These instructions don't apply to Cygwin. XZ Utils can be built + under Cygwin in the same way as many other packages. + + +1.1. Licensing considerations + + Parts of MinGW-w64 runtime are statically linked into the binaries + being built. The file COPYING.MinGW-w64-runtime.txt in MinGW-w64 + contains the license notices that apply to some parts of the + runtime. The notices must be distributed alongside the binaries + that have been built with MinGW-w64. + + MinGW-w64 includes getopt_long(). The GNU getopt_long() (LGPLv2.1) + included in XZ Utils isn't used when building with MinGW-w64. + + The code from XZ Utils that ends up liblzma.dll and the *.exe files + is under the BSD Zero Clause License (0BSD) which doesn't require + any copyright or license notices to be included when distributing + the binaries. See the file COPYING in the parent directory. + + +2. MSVCRT or UCRT +----------------- + + Both GCC and Clang/LLVM based MinGW-w64 toolchains come in MSVCRT + and Universal C runtime (UCRT) variants. Use the UCRT variant + unless you have a good reason to why you still need to use MSVCRT. + + MSVCRT is old. 32-bit builds of XZ Utils with MSVCRT should run on + Windows 2000 and later (even Windows 95 should still be possible + with trivial edits to the source code). However, MSVCRT doesn't + support the UTF-8 code page. Under Windows 10 version 1903 and + later, the command line tools of XZ Utils 5.6.3 and later use the + UTF-8 code page. If the command line tools are built against MSVCRT + and used on Win10 v1903 or later, non-ASCII characters may be + displayed incorrectly. Otherwise the tools should still function + correctly, so it's mostly a cosmetic issue. + + UCRT is included in Windows 10, and it's possible to install UCRT + on Windows XP and later. UCRT supports the UTF-8 code page. UCRT is + the preferred choice if out-of-the-box compatibility with Windows + versions older than 10 is not required. Visual Studio 2015 and + later produce binaries that use UCRT. + + If you want to build liblzma.dll for use with your application, + it's recommended to use the same CRT for all components (the UTF-8 + code page issue only affects the command line tools, not liblzma). + If this isn't possible, see the file liblzma-crt-mixing.txt. + + +3. CMake +-------- + + CMake is used for selecting build options and generating makefiles. + It can also be used to extract archives, including .tar.xz and .7z. + + Download a CMake binary package (.zip) from its homepage: + + https://cmake.org/download/ + + Extract it to, for example, C:\devel\cmake so that the executables + end up in C:\devel\cmake\bin. Avoid spaces and other special + characters in the path. + + +4. MinGW-w64 toolchains +----------------------- + + There are a few choices of prebuilt toolchains listed on + the MinGW-w64 homepage: + + https://www.mingw-w64.org/downloads/ + + These instructions list one GCC-based version and one + Clang/LLVM-based version. Both include mingw32-make too. + + +4.1. MinGW-w64 with GCC + + For GCC, download appropriate packages from Mingw-builds depending + on if you want to build 32-bit or 64-bit x86 version of XZ Utils + and if the XZ Utils binaries should link against MSVCRT or UCRT + (use 64-bit UCRT if possible): + + https://github.com/niXman/mingw-builds-binaries/releases + + i686-*-release-win32-*-msvcrt-*.7z 32-bit, uses MSVCRT (old) + i686-*-release-win32-*-ucrt-*.7z 32-bit, uses UCRT (new) + x86_64-*-release-win32-*-msvcrt-*.7z 64-bit, uses MSVCRT (old) + x86_64-*-release-win32-*-ucrt-*.7z 64-bit, uses UCRT (new) + + Extract it, for example, to C:\devel so that the executables are + in C:\devel\mingw32\bin or C:\devel\mingw64\bin. To extract, + you can install 7-Zip from or use CMake + on the command line: + + set PATH=C:\devel\cmake\bin;%PATH% + c: + cd \devel + cmake -E tar xf x86_64-13.1.0-release-win32-seh-ucrt-rt_v11-rev1.7z + + Then skip to the section "Building XZ Utils". + + +4.2. MinGW-w64 with Clang/LLVM + + For Clang/LLVM, download an appropriate package from LLVM-MinGW + (use 64-bit UCRT if possible): + + https://github.com/mstorsjo/llvm-mingw/releases + + llvm-mingw-*-msvcrt-i686.zip 32-bit, uses MSVCRT (old) + llvm-mingw-*-ucrt-i686.zip 32-bit, uses UCRT (new) + llvm-mingw-*-msvcrt-x86_64.zip 64-bit, uses MSVCRT (old) + llvm-mingw-*-ucrt-x86_64.zip 64-bit, uses UCRT (new) + + Extract it, for example, to C:\devel so that the executables end up + in a directory like C:\devel\llvm-mingw-20230919-ucrt-x86_64\bin. + + +5. Building XZ Utils +-------------------- + + For a simple builds, you can use the included build-with-cmake.bat + which takes these arguments: + + %1 = Path to CMake's bin directory. Example: + c:\devel\cmake\bin + + %2 = Path to MinGW-w64's bin directory. Example: + c:\devel\mingw64\bin + + %3 = ON or OFF: Set to ON to build liblzma.dll or OFF for + static liblzma.a. With OFF, the *.exe files won't + depend on liblzma.dll. + + Example: + + build-with-cmake C:\devel\cmake\bin C:\devel\mingw64\bin ON + + If successful, the "build" directory should then contain: + + liblzma.dll liblzma compression library + liblzma.def DEF file for creating an import library + xz.exe xz command line tool + xzdec.exe Decompression-only tool (smaller than xz.exe) + lzmadec.exe Decompression-only tool for legacy .lzma files + lzmainfo.exe Shows header info of legacy .lzma files + + Ignore the other files. :-) + + +5.1. Advanced build options + + For 32-bit x86 builds, adding -msse2 to CFLAGS improves + compression speed a little (but not decompression speed). + There is no runtime detection for SSE2 support. It is + recommended to use 64-bit version when possible. + + It's possible to omit features from the build to reduce code size. + There are several CMake configuration options available. One may + change from CMAKE_BUILD_TYPE=Release to =MinSizeRel as well but + it makes the code slower. + + If building for multiple targets, keep only one toolchain in PATH + at a time. + + +6. Creating an import library for MSVC / Visual Studio +------------------------------------------------------ + + To link against liblzma.dll, you need to create an import library + first. You need the "lib" command from MSVC and liblzma.def. Here + is the command that works on 32-bit x86: + + lib /def:liblzma.def /out:liblzma.lib /machine:ix86 + + On x86-64, the /machine argument has to be changed: + + lib /def:liblzma.def /out:liblzma.lib /machine:x64 + + IMPORTANT: See also the file liblzma-crt-mixing.txt. + diff --git a/cpp/third_party/xz-5.8.3/windows/README-Windows.txt b/cpp/third_party/xz-5.8.3/windows/README-Windows.txt new file mode 100644 index 000000000..c97086ffa --- /dev/null +++ b/cpp/third_party/xz-5.8.3/windows/README-Windows.txt @@ -0,0 +1,100 @@ + +XZ Utils for Windows +==================== + +Introduction +------------ + + This package includes command line tools (xz.exe and a few + others) and the liblzma compression library from XZ Utils. + You can find the latest version and full source code from + . + + The parts of the XZ Utils source code, that are relevant to this + binary package, are under the BSD Zero Clause License (0BSD). + XZ Utils have been built using GCC and MinGW-w64 and linked + statically against the MinGW-w64 runtime libraries. See + COPYING.MinGW-w64-runtime.txt for copyright and license + information that applies to the MinGW-w64 runtime. + + IMPORTANT: You must include COPYING.MinGW-w64-runtime.txt + when distributing these XZ Utils binaries to meet + the license terms of the MinGW-w64 runtime! + + (The file COPYING mentions GNU getopt_long. It's *not* used when + XZ Utils is built with MinGW-w64. Thus GNU LGPLv2.1 doesn't apply.) + + +Package contents +---------------- + + All executables and libraries in this package require + Universal CRT (UCRT). It is included in Windows 10 and later, + and it's possible to install UCRT on Windows XP and later. + + There is a SSE2 optimization in the compression code but this + version of XZ Utils doesn't include run-time processor detection. + The binaries don't work on 32-bit processors without SSE2 support. + + There is one directory for each type of executable and library files: + + bin_i686-sse2 32-bit x86 (i686 with SSE2) + bin_x86-64 64-bit x86-64 + + Each of the above directories have the following files: + + *.exe Command line tools. (It's useless to double-click + these; use the command prompt instead.) These have + been linked statically against liblzma, so they + don't require liblzma.dll. Thus, you can copy e.g. + xz.exe to a directory that is in PATH without + copying any other files from this package. + + NOTE: xzdec.exe and lzmadec.exe are optimized for + size, single-threaded, and slower than xz.exe. + Use xz.exe unless program size is important. + + liblzma.dll Shared version of the liblzma compression library. + This file is mostly useful to developers, although + some non-developers might use it to upgrade their + copy of liblzma. + + The rest of the directories contain architecture-independent files: + + doc Basic documentation in the plain text (TXT) + format. COPYING.txt, COPYING.0BSD.txt, and + COPYING.MinGW-w64-runtime.txt contain + copyright and license information. + liblzma.def is in this directory too. + + doc/manuals The manuals of the command line tools + + doc/examples Example programs for basic liblzma usage. + + include C header files for liblzma. These should be + compatible with most C and C++ compilers. + + +Creating an import library for MSVC / Visual Studio +--------------------------------------------------- + + To link against liblzma.dll, you need to create an import library + first. You need the "lib" command from MSVC and liblzma.def from + the "doc" directory of this package. Here is the command that works + on 32-bit x86: + + lib /def:liblzma.def /out:liblzma.lib /machine:ix86 + + On x86-64, the /machine argument has to be changed: + + lib /def:liblzma.def /out:liblzma.lib /machine:x64 + + IMPORTANT: See also the file liblzma-crt-mixing.txt if your + application isn't using UCRT. + + +Reporting bugs +-------------- + + Report bugs to . + diff --git a/cpp/third_party/xz-5.8.3/windows/build-with-cmake.bat b/cpp/third_party/xz-5.8.3/windows/build-with-cmake.bat new file mode 100644 index 000000000..d843b2a66 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/windows/build-with-cmake.bat @@ -0,0 +1,35 @@ +@rem # SPDX-License-Identifier: 0BSD +@rem # Author: Lasse Collin +@rem # +@rem ######################################################################## +@rem # +@rem # This builds XZ Utils with CMake + MinGW-w64 (GCC or Clang/LLVM). +@rem # See INSTALL-MinGW-w64_with_CMake.txt for detailed instructions. +@rem # +@rem # Summary of command line arguments: +@rem # +@rem # %1 = Path to CMake's bin directory. Example: +@rem # C:\devel\cmake\bin +@rem # +@rem # %2 = Path to MinGW-w64's bin directory. Example: +@rem # C:\devel\mingw64\bin +@rem # +@rem # %3 = ON or OFF: Set to ON to build liblzma.dll or OFF for +@rem # static liblzma.a. With OFF, the *.exe files won't +@rem # depend on liblzma.dll. +@rem # +@rem ######################################################################## + +setlocal +set PATH=%1;%2;%PATH% + +md build || exit /b +cd build || exit /b + +cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DXZ_NLS=OFF -DBUILD_SHARED_LIBS=%3 ..\.. || exit /b +mingw32-make || exit /b +mingw32-make test || exit /b + +@rem liblzma.dll might not exist so ignore errors. +strip xz.exe xzdec.exe lzmadec.exe lzmainfo.exe liblzma.dll +exit /b 0 diff --git a/cpp/third_party/xz-5.8.3/windows/build.bash b/cpp/third_party/xz-5.8.3/windows/build.bash new file mode 100644 index 000000000..395d87fbf --- /dev/null +++ b/cpp/third_party/xz-5.8.3/windows/build.bash @@ -0,0 +1,245 @@ +#!/bin/bash +# SPDX-License-Identifier: 0BSD + +############################################################################### +# +# This build a XZ Utils binary package using the GNU Autotools build system +# +# NOTE: This requires files that are generated as part of "make mydist". +# So if building from xz.git, create a distribution tarball first, +# extract it, and run this script from there. +# +# These were tested and known to work: +# - Cross-compilation with MinGW-w64 v10.0.0 and GCC 12.2.0 from +# GNU/Linux ("make check" will be skipped) +# - MSYS2 with MinGW-w64 and GCC +# - MSYS 1.0.11 (from 2009) with MinGW-w64 v11.0.0 and GCC 13.1.0 +# +# Optionally, 7-Zip is used to create the final .zip and .7z packages. +# If the 7z tool is in PATH or if you have installed it in the default +# directory on Windows, this script should find it automatically. +# +# Before running this script, copy COPYING.MinGW-w64-runtime.txt to +# the 'windows' directory. +# +# NOTE: MinGW-w64 includes getopt_long(). The GNU getopt_long() (LGPLv2.1) +# included in XZ Utils isn't used when building with MinGW-w64. +# +############################################################################### +# +# Author: Lasse Collin +# +############################################################################### + +# Abort immediately if something goes wrong. +set -e + +# White spaces in directory names may break things so catch them immediately. +case $(pwd) in + ' ' | ' ' | ' +') echo "Error: White space in the directory name" >&2; exit 1 ;; +esac + +# This script can be run either at the top-level directory of the package +# or in the same directory containing this script. +if [ ! -f windows/build.bash ]; then + cd .. + if [ ! -f windows/build.bash ]; then + echo "ERROR: You are in a wrong directory. This script" >&2 + echo "can be run either at the top-level directory of" >&2 + echo "the package or in the same directory containing" >&2 + echo "this script." >&2 + exit 1 + fi +fi + +# COPYING.MinGW-w64-runtime.txt needs to be manually copied from MinGW-w64. +if [ ! -f windows/COPYING.MinGW-w64-runtime.txt ]; then + echo "ERROR: The file 'windows/COPYING.MinGW-w64-runtime.txt'" >&2 + echo "doesn't exists. Copy it from MinGW-w64 so that the" >&2 + echo "copyright and license notices of the MinGW-w64 runtime" >&2 + echo "can be included in the package." >&2 + echo "(Or create an empty file if only doing a test build.)" >&2 + exit 1 +fi + +# Number of jobs for "make": +MAKE_JOBS=$(nproc 2> /dev/null || echo 1) + +# "make check" has to be skipped when cross-compiling. +if [ "x$(uname -o)" = xMsys ]; then + IS_NATIVE_BUILD=true +else + IS_NATIVE_BUILD=false +fi + +# Run configure and copy the binaries to the given directory. +# +# The first argument is the directory where to copy the binaries. +# The rest of the arguments are passed to configure. +buildit() +{ + DESTDIR=$1 + TRIPLET=$2 + CFLAGS=$3 + + # In the MinGW-w64 + GCC toolchains running natively on Windows, + # $TRIPLET-windres and $TRIPLET-strip commands might not exist. + # Only the short names "windres" and "strip" might be available. + # If both i686 and x86_64 toolchains are in PATH, wrong windres.exe + # will be used for one of the builds, making the build fail. The + # workaround is to put the directory of $TRIPLET-gcc to the front + # of PATH if $TRIPLET-windres or $TRIPLET-strip is missing. + OLD_PATH=$PATH + if type -P "$TRIPLET-windres" > /dev/null \ + && type -P "$TRIPLET-strip" > /dev/null; then + STRIP=$TRIPLET-strip + else + STRIP=strip + GCC_DIR=$(type -P "$TRIPLET-gcc") + PATH=${GCC_DIR%/*}:$PATH + fi + + # Clean up if it was already configured. + [ -f Makefile ] && make distclean + + # Build the size-optimized binaries. Providing size-optimized liblzma + # could be considered but I don't know if it should only use -Os or + # should it also use --enable-small and if it should support + # threading. So I don't include a size-optimized liblzma for now. + ./configure \ + --prefix= \ + --enable-silent-rules \ + --disable-dependency-tracking \ + --disable-nls \ + --disable-scripts \ + --disable-threads \ + --disable-shared \ + --enable-small \ + --host="$TRIPLET" \ + CFLAGS="$CFLAGS -Os" + make -j"$MAKE_JOBS" + + if "$IS_NATIVE_BUILD"; then + make -j"$MAKE_JOBS" check + fi + + mkdir -pv "$DESTDIR" + cp -v src/xzdec/{xz,lzma}dec.exe src/lzmainfo/lzmainfo.exe "$DESTDIR" + + make distclean + + # Build the normal speed-optimized binaries. The type of threading + # (win95 vs. vista) will be autodetect from the target architecture. + ./configure \ + --prefix= \ + --enable-silent-rules \ + --disable-dependency-tracking \ + --disable-nls \ + --disable-scripts \ + --host="$TRIPLET" \ + CFLAGS="$CFLAGS -O2" + make -j"$MAKE_JOBS" -C src/liblzma + make -j"$MAKE_JOBS" -C src/xz LDFLAGS=-static + + if "$IS_NATIVE_BUILD"; then + make -j"$MAKE_JOBS" -C tests check + fi + + cp -v src/xz/xz.exe "$DESTDIR" + cp -v src/liblzma/.libs/liblzma-5.dll "$DESTDIR/liblzma.dll" + "$STRIP" -v "$DESTDIR/"*.{exe,dll} + + PATH=$OLD_PATH +} + +# Copy files and convert newlines from LF to CR+LF. Optionally add a suffix +# to the destination filename. +# +# The first argument is the destination directory. The second argument is +# the suffix to append to the filenames; use empty string if no extra suffix +# is wanted. The rest of the arguments are the actual filenames. +txtcp() +{ + DESTDIR=$1 + SUFFIX=$2 + shift 2 + for SRCFILE; do + DESTFILE="$DESTDIR/${SRCFILE##*/}$SUFFIX" + echo "Converting '$SRCFILE' -> '$DESTFILE'" + sed s/\$/$'\r'/ < "$SRCFILE" > "$DESTFILE" + done +} + +if type -P i686-w64-mingw32-gcc > /dev/null; then + # 32-bit x86, Win2k or later if using MSVCRT + # + # Uncomment if using MSVCRT and you want the binaries to be compatible + # with old Windows versions on old computers. + #buildit pkg/bin_i686 i686-w64-mingw32 '-march=i686 -mtune=generic' + + # 32-bit x86 with SSE2 (Win2k or later if using MSVCRT) + buildit pkg/bin_i686-sse2 i686-w64-mingw32 \ + '-march=i686 -msse2 -mtune=generic' +else + echo + echo "i686-w64-mingw32-gcc is not in PATH, skipping 32-bit x86 builds" + echo +fi + +if type -P x86_64-w64-mingw32-gcc > /dev/null; then + # x86-64, Windows Vista or later + buildit pkg/bin_x86-64 x86_64-w64-mingw32 \ + '-march=x86-64 -mtune=generic' +else + echo + echo "x86_64-w64-mingw32-gcc is not in PATH, skipping x86-64 build" + echo +fi + +if type -P ps2pdf > /dev/null; then + make pdf +fi + +# Copy the headers, the .def file, and the docs. +# They are the same for all architectures and builds. +mkdir -pv pkg/{include/lzma,doc/{manuals,examples}} +txtcp pkg/include "" src/liblzma/api/lzma.h +txtcp pkg/include/lzma "" src/liblzma/api/lzma/*.h +txtcp pkg/doc "" src/liblzma/liblzma.def +txtcp pkg/doc .txt AUTHORS COPYING COPYING.0BSD NEWS README THANKS +txtcp pkg/doc "" doc/*-file-format.txt \ + windows/README-Windows.txt \ + windows/liblzma-crt-mixing.txt \ + windows/COPYING.MinGW-w64-runtime.txt +txtcp pkg/doc/manuals "" doc/man/txt/{xz,xzdec,lzmainfo}.txt +if [ -d doc/man/pdf-a4 ]; then + cp -v doc/man/pdf-*/{xz,xzdec,lzmainfo}-*.pdf pkg/doc/manuals +fi +# cp -rv doc/api pkg/doc/api +txtcp pkg/doc/examples "" doc/examples/* + +# Create the package. This requires 7z from 7-Zip. +# If it isn't found, this step is skipped. +for SEVENZ in "$(type -P 7z || true)" \ + "$PROGRAMW6432/7-Zip/7z.exe" "$PROGRAMFILES/7-Zip/7z.exe" \ + "/c/Program Files/7-Zip/7z.exe" +do + [ -x "$SEVENZ" ] && break +done + +VER=$(sh build-aux/version.sh) +if [ -x "$SEVENZ" ]; then + cd pkg + "$SEVENZ" a -tzip "../xz-$VER-windows.zip" * + "$SEVENZ" a "../xz-$VER-windows.7z" * +else + echo + echo "NOTE: 7z was not found. xz-$VER-windows.zip" + echo " and xz-$VER-windows.7z were not created." + echo " You can create them yourself from the pkg directory." +fi + +echo +echo "Build completed successfully." +echo diff --git a/cpp/third_party/xz-5.8.3/windows/liblzma-crt-mixing.txt b/cpp/third_party/xz-5.8.3/windows/liblzma-crt-mixing.txt new file mode 100644 index 000000000..4ef2f8ab3 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/windows/liblzma-crt-mixing.txt @@ -0,0 +1,70 @@ + +liblzma.dll and mixing C runtimes (CRTs) +---------------------------------------- + + If possible, liblzma.dll should be linked against the same CRT + (MSVCRT or UCRT) as the application calling the liblzma functions. + When this isn't possible, liblzma.dll will still work but there + are a few API functions that need extra care. + + Each CRT has its own memory allocator, stdio FILE implementation, + mapping of file descriptors from _open() to Windows' HANDLEs, and + so on. Mixing CRTs is a problem if, for example, one library calls + fopen() and then passes the resulting FILE* to a second library and + these two libraries use different CRTs. liblzma doesn't expose FILE + pointers or file descriptors in the API but the problem can occur + with memory allocation with a few specific functions. + + The most commonly-used API functions in liblzma are such that both + memory allocation and deallocation is done internally by liblzma, + thus most applications won't have any problems with mixing CRTs + with liblzma.dll. The following API functions are the exception: + + lzma/block.h: + lzma_block_header_decode + + lzma/filter.h: + lzma_filters_copy + lzma_filters_free + lzma_properties_decode + lzma_filter_flags_decode + lzma_str_to_filters + lzma_str_from_filters + lzma_str_list_filters + + Excluding lzma_filters_free(), the above functions allocate memory + and leave it to the caller to free it. lzma_filters_free() frees + memory given to it, and that memory may have been allocated outside + of liblzma. + + For example, if application calls lzma_str_list_filters(&ptr, ...) + and then uses free(ptr), something bad (memory corruption, crash) + will happen if the application and liblzma.dll aren't using the + same CRT. This can be worked around with a few lines of extra code. + + All these functions (and many others too) take a pointer to + lzma_allocator structure as an argument. Typically it is set to + NULL to let liblzma use malloc() and free() (and also calloc() + as it is faster than malloc() + memset()). A custom lzma_allocator + can be used to wrap malloc() and free() from application's CRT: + + static void * LZMA_API_CALL + my_alloc(void *opaque, size_t nmemb, size_t size) + { + // liblzma guarantees that this won't overflow. + return malloc(nmemb * size); + } + + static void LZMA_API_CALL + my_free(void *opaque, void *ptr) + { + free(ptr); + } + + static const lzma_allocator allocator + = { &my_alloc, &my_free, NULL }; + + By passing &allocator to the problematic functions, CRT mixing + should not cause any problems. There is no need to use &allocator + with functions other than those listed above. + diff --git a/cpp/third_party/zstd-1.5.7/.buckconfig b/cpp/third_party/zstd-1.5.7/.buckconfig new file mode 100644 index 000000000..483f6053b --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.buckconfig @@ -0,0 +1,9 @@ +[cxx] + cppflags = -DXXH_NAMESPACE=ZSTD_ -DZSTD_LEGACY_SUPPORT=4 + cflags = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -Wpointer-arith + cxxppflags = -DXXH_NAMESPACE=ZSTD_ -DZSTD_LEGACY_SUPPORT=4 + cxxflags = -std=c++11 -Wno-deprecated-declarations + gtest_dep = //contrib/pzstd:gtest + +[httpserver] + port = 0 diff --git a/cpp/third_party/zstd-1.5.7/.buckversion b/cpp/third_party/zstd-1.5.7/.buckversion new file mode 100644 index 000000000..892fad966 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.buckversion @@ -0,0 +1 @@ +c8dec2e8da52d483f6dd7c6cd2ad694e8e6fed2b diff --git a/cpp/third_party/zstd-1.5.7/.cirrus.yml b/cpp/third_party/zstd-1.5.7/.cirrus.yml new file mode 100644 index 000000000..745024bc2 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.cirrus.yml @@ -0,0 +1,9 @@ +task: + name: FreeBSD (make check) + freebsd_instance: + matrix: + image_family: freebsd-14-2 + install_script: pkg install -y gmake coreutils + script: | + MOREFLAGS="-Werror" gmake -j all + gmake check diff --git a/cpp/third_party/zstd-1.5.7/.gitattributes b/cpp/third_party/zstd-1.5.7/.gitattributes new file mode 100644 index 000000000..6212bd405 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.gitattributes @@ -0,0 +1,21 @@ +# Set the default behavior +* text eol=lf + +# Explicitly declare source files +*.c text eol=lf +*.h text eol=lf + +# Denote files that should not be modified. +*.odt binary +*.png binary + +# Visual Studio +*.sln text eol=crlf +*.vcxproj* text eol=crlf +*.vcproj* text eol=crlf +*.suo binary +*.rc text eol=crlf + +# Windows +*.bat text eol=crlf +*.cmd text eol=crlf diff --git a/cpp/third_party/zstd-1.5.7/.github/ISSUE_TEMPLATE/bug_report.md b/cpp/third_party/zstd-1.5.7/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..755a46af1 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Downloads data '...' +2. Run '...' with flags '...' +3. Scroll up on the log to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots and charts** +If applicable, add screenshots and charts to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. Mac] + - Version [e.g. 22] + - Compiler [e.g. gcc] + - Flags [e.g. O2] + - Other relevant hardware specs [e.g. Dual-core] + - Build system [e.g. Makefile] + +**Additional context** +Add any other context about the problem here. diff --git a/cpp/third_party/zstd-1.5.7/.github/ISSUE_TEMPLATE/feature_request.md b/cpp/third_party/zstd-1.5.7/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..bbcbbe7d6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/cpp/third_party/zstd-1.5.7/.github/dependabot.yml b/cpp/third_party/zstd-1.5.7/.github/dependabot.yml new file mode 100644 index 000000000..5ace4600a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/cpp/third_party/zstd-1.5.7/.github/workflows/android-ndk-build.yml b/cpp/third_party/zstd-1.5.7/.github/workflows/android-ndk-build.yml new file mode 100644 index 000000000..175add4ff --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/workflows/android-ndk-build.yml @@ -0,0 +1,39 @@ +name: Android NDK Build + +on: + pull_request: + branches: [ dev, release, actionsTest ] + push: + branches: [ actionsTest, '*ndk*' ] + +permissions: read-all + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + + - name: Set up JDK 17 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Android SDK + uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3.2.2 + + - name: Install Android NDK + run: | + sdkmanager --install "ndk;27.0.12077973" + echo "ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk/27.0.12077973" >> $GITHUB_ENV + + - name: Build with NDK + run: | + export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH + make CC=aarch64-linux-android21-clang \ + AR=llvm-ar \ + RANLIB=llvm-ranlib \ + STRIP=llvm-strip + diff --git a/cpp/third_party/zstd-1.5.7/.github/workflows/commit.yml b/cpp/third_party/zstd-1.5.7/.github/workflows/commit.yml new file mode 100644 index 000000000..659072861 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/workflows/commit.yml @@ -0,0 +1,104 @@ +name: facebook/zstd/commit +on: + push: + branches: + - dev + pull_request: + branches: + - dev + +permissions: read-all + +jobs: + short-tests-0: + runs-on: ubuntu-latest + services: + docker: + image: fbopensource/zstd-circleci-primary:0.0.1 + options: --entrypoint /bin/bash + steps: + - uses: actions/checkout@v4 + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install libcurl4-gnutls-dev + - name: Test + run: | + ./tests/test-license.py + cc -v + CFLAGS="-O0 -Werror -pedantic" make allmost; make clean + make c99build; make clean + make c11build; make clean + make -j regressiontest; make clean + make check; make clean + make cxxtest; make clean + + short-tests-1: + runs-on: ubuntu-latest + services: + docker: + image: fbopensource/zstd-circleci-primary:0.0.1 + options: --entrypoint /bin/bash + steps: + - uses: actions/checkout@v4 + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install gcc-powerpc-linux-gnu gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu libc6-dev-ppc64-powerpc-cross libcurl4-gnutls-dev lib64gcc-13-dev-powerpc-cross + - name: gnu90 build + run: make gnu90build && make clean + - name: gnu99 build + run: make gnu99build && make clean + - name: ppc64 build + run: make ppc64build V=1 && make clean + - name: ppc build + run: make ppcbuild V=1 && make clean + - name: arm build + run: make armbuild V=1 && make clean + - name: aarch64 build + run: make aarch64build V=1 && make clean + - name: test-legacy + run: make -C tests test-legacy V=1 && make clean + - name: test-longmatch + run: make -C tests test-longmatch V=1 && make clean + - name: libzstd-nomt build + run: make -C lib libzstd-nomt V=1 && make clean + + regression-test: + runs-on: ubuntu-latest + services: + docker: + image: fbopensource/zstd-circleci-primary:0.0.1 + options: --entrypoint /bin/bash + env: + CIRCLE_ARTIFACTS: "/tmp/circleci-artifacts" + steps: + - uses: actions/checkout@v4 + - name: restore_cache + uses: actions/cache@v4 + with: + key: regression-cache-{{ checksum "tests/regression/data.c" }}-v0 + path: tests/regression/cache + restore-keys: regression-cache-{{ checksum "tests/regression/data.c" }}-v0 + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install libcurl4-gnutls-dev + - name: Regression Test + run: | + make -C programs zstd + make -C tests/regression test + mkdir -p $CIRCLE_ARTIFACTS + ./tests/regression/test \ + --cache tests/regression/cache \ + --output $CIRCLE_ARTIFACTS/results.csv \ + --zstd programs/zstd + echo "NOTE: The new results.csv is uploaded as an artifact to this job" + echo " If this fails, go to the Artifacts pane in CircleCI, " + echo " download /tmp/circleci-artifacts/results.csv, and if they " + echo " are still good, copy it into the repo and commit it." + echo "> diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv" + diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv + - uses: actions/upload-artifact@v4 + with: + path: "/tmp/circleci-artifacts" diff --git a/cpp/third_party/zstd-1.5.7/.github/workflows/dev-long-tests.yml b/cpp/third_party/zstd-1.5.7/.github/workflows/dev-long-tests.yml new file mode 100644 index 000000000..899a57b75 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/workflows/dev-long-tests.yml @@ -0,0 +1,313 @@ +name: dev-long-tests +# Tests longer than 10mn + +concurrency: + group: long-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + branches: [ dev, release, actionsTest ] + +permissions: read-all + +jobs: + make-all: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: make all + run: make all + + # lasts ~24mn + make-test: + runs-on: ubuntu-latest + env: + DEVNULLRIGHTS: 1 + READFROMBLOCKDEVICE: 1 + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: make test + run: make test + + # lasts ~26mn + make-test-macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: make test on macos + run: make test + + # lasts ~24mn + make-test-32bit: + runs-on: ubuntu-latest + env: + DEVNULLRIGHTS: 1 + READFROMBLOCKDEVICE: 1 + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: make test # note: `make -j test success` seems to require a clean state + run: | + sudo apt-get -qqq update + make libc6install + make clean + CFLAGS="-m32 -O2" make -j test V=1 + + no-intrinsics-fuzztest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: no intrinsics fuzztest + run: MOREFLAGS="-DZSTD_NO_INTRINSICS" make -C tests fuzztest + + tsan-zstreamtest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: thread sanitizer zstreamtest + run: CC=clang ZSTREAM_TESTTIME=-T3mn make tsan-test-zstream + + uasan-zstreamtest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: ub + address sanitizer on zstreamtest + run: CC=clang make uasan-test-zstream + + # lasts ~15mn + tsan-fuzztest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: thread sanitizer fuzztest + run: CC=clang make tsan-fuzztest + + + big-tests-zstreamtest32: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: zstream tests in 32bit mode, with big tests + run: | + sudo apt-get -qqq update + make libc6install + CC=clang make -C tests test-zstream32 FUZZER_FLAGS="--big-tests" + + # lasts ~23mn + gcc-8-asan-ubsan-testzstd: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: gcc-8 + ASan + UBSan + Test Zstd + # See https://askubuntu.com/a/1428822 + run: | + echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu focal main universe" | sudo tee -a /etc/apt/sources.list + sudo apt-get -qqq update + make gcc8install + CC=gcc-8 make -j uasan-test-zstd cross.ini < + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=${{matrix.toolset}} + /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} /warnaserror + - name: Build ${{matrix.name}} + working-directory: ${{env.GITHUB_WORKSPACE}} + # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + if: ${{ matrix.arch != '' }} + run: > + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=${{matrix.toolset}} + /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} /warnaserror + /p:InstructionSet=${{matrix.arch}} + + # This tests that we don't accidentally grow the size too much. + # If the size grows intentionally, you can raise these numbers. + # But we do need to think about binary size, since it is a concern. + libzstd-size: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: libzstd size test + run: | + make clean && make -j -C lib libzstd && ./tests/check_size.py lib/libzstd.so 1100000 + make clean && make -j -C lib libzstd ZSTD_LIB_COMPRESSION=0 ZSTD_LIB_DICTBUILDER=0 && ./tests/check_size.py lib/libzstd.so 400000 + make clean && make -j -C lib libzstd ZSTD_LIB_MINIFY=1 && ./tests/check_size.py lib/libzstd.so 300000 + make clean && make -j -C lib libzstd ZSTD_LIB_MINIFY=1 ZSTD_LIB_COMPRESSION=0 ZSTD_LIB_DICTBUILDER=0 && ./tests/check_size.py lib/libzstd.so 80000 + + minimal-decompressor-macros: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: minimal decompressor macros + run: | + make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" + make clean && make check ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" + make clean && make -j all MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X1 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT" + make clean && make check MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X1 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT" + make clean && make -j all MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X2 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG" + make clean && make check MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X2 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG" + make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + make clean && make check ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP=1 MOREFLAGS="-Werror" + make clean && make check ZSTD_LIB_EXCLUDE_COMPRESSORS_GREEDY_AND_UP=1 MOREFLAGS="-Werror" + + dynamic-bmi2: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: dynamic bmi2 tests + run: | + make clean && make -j check MOREFLAGS="-O0 -Werror -mbmi2" + make clean && make -j check MOREFLAGS="-O0 -Werror -DDYNAMIC_BMI2=1" + make clean && make -j check MOREFLAGS="-O0 -Werror -DDYNAMIC_BMI2=1 -mbmi2" + make clean && make -j check MOREFLAGS="-O0 -Werror -DDYNAMIC_BMI2=0" + make clean && make -j check MOREFLAGS="-O0 -Werror -DDYNAMIC_BMI2=0 -mbmi2" + + test-variants: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: make all variants & validate + run: | + make -j -C programs allVariants MOREFLAGS=-O0 + ./tests/test-variants.sh + + qemu-consistency: + name: QEMU ${{ matrix.name }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false # 'false' means Don't stop matrix workflows even if some matrix failed. + matrix: + include: [ + { name: ARM, xcc_pkg: gcc-arm-linux-gnueabi, xcc: arm-linux-gnueabi-gcc, xemu_pkg: qemu-system-arm, xemu: qemu-arm-static }, + { name: ARM64, xcc_pkg: gcc-aarch64-linux-gnu, xcc: aarch64-linux-gnu-gcc, xemu_pkg: qemu-system-aarch64,xemu: qemu-aarch64-static }, + { name: PPC, xcc_pkg: gcc-powerpc-linux-gnu, xcc: powerpc-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc-static }, + { name: PPC64LE, xcc_pkg: gcc-powerpc64le-linux-gnu, xcc: powerpc64le-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc64le-static }, + { name: S390X, xcc_pkg: gcc-s390x-linux-gnu, xcc: s390x-linux-gnu-gcc, xemu_pkg: qemu-system-s390x, xemu: qemu-s390x-static }, + { name: MIPS, xcc_pkg: gcc-mips-linux-gnu, xcc: mips-linux-gnu-gcc, xemu_pkg: qemu-system-mips, xemu: qemu-mips-static }, + { name: RISC-V, xcc_pkg: gcc-riscv64-linux-gnu, xcc: riscv64-linux-gnu-gcc, xemu_pkg: qemu-system-riscv64,xemu: qemu-riscv64-static }, + { name: M68K, xcc_pkg: gcc-m68k-linux-gnu, xcc: m68k-linux-gnu-gcc, xemu_pkg: qemu-system-m68k, xemu: qemu-m68k-static }, + { name: SPARC, xcc_pkg: gcc-sparc64-linux-gnu, xcc: sparc64-linux-gnu-gcc, xemu_pkg: qemu-system-sparc, xemu: qemu-sparc64-static }, + ] + env: # Set environment variables + XCC: ${{ matrix.xcc }} + XEMU: ${{ matrix.xemu }} + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: apt update & install + run: | + sudo apt-get update + sudo apt-get install gcc-multilib g++-multilib qemu-utils qemu-user-static + sudo apt-get install ${{ matrix.xcc_pkg }} ${{ matrix.xemu_pkg }} + - name: Environment info + run: | + echo && which $XCC + echo && $XCC --version + echo && $XCC -v # Show built-in specs + echo && which $XEMU + echo && $XEMU --version + - name: ARM + if: ${{ matrix.name == 'ARM' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: ARM64 + if: ${{ matrix.name == 'ARM64' }} + run: | + make clean + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j check +# This test is only compatible with standard libraries that support BTI (Branch Target Identification). +# Unfortunately, the standard library provided on Ubuntu 24.04 does not have this feature enabled. +# make clean +# LDFLAGS="-static -z force-bti" MOREFLAGS="-mbranch-protection=standard" CC=$XCC QEMU_SYS=$XEMU make check V=1 + - name: PPC + if: ${{ matrix.name == 'PPC' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: PPC64LE + if: ${{ matrix.name == 'PPC64LE' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: S390X + if: ${{ matrix.name == 'S390X' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: MIPS + if: ${{ matrix.name == 'MIPS' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: RISC-V + if: ${{ matrix.name == 'RISC-V' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: M68K + if: ${{ matrix.name == 'M68K' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: SPARC + if: ${{ matrix.name == 'SPARC' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + + mingw-short-test: + runs-on: windows-latest + strategy: + fail-fast: false # 'false' means Don't stop matrix workflows even if some matrix failed. + matrix: + include: [ + { compiler: gcc, msystem: MINGW32, cflags: "-Werror"}, + { compiler: gcc, msystem: MINGW64, cflags: "-Werror"}, + { compiler: clang, msystem: MINGW64, cflags: "--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion -Wno-unused-command-line-argument"}, + ] + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # tag=v2.26.0 + with: + msystem: ${{ matrix.msystem }} + install: make diffutils + update: true + # Based on https://ariya.io/2020/07/on-github-actions-with-msys2 + - name: install mingw gcc i686 + if: ${{ (matrix.msystem == 'MINGW32') && (matrix.compiler == 'gcc') }} + run: pacman --noconfirm -S mingw-w64-i686-gcc + - name: install mingw gcc x86_64 + if: ${{ (matrix.msystem == 'MINGW64') && (matrix.compiler == 'gcc') }} + run: pacman --noconfirm -S mingw-w64-x86_64-gcc + - name: install mingw clang i686 + if: ${{ (matrix.msystem == 'MINGW32') && (matrix.compiler == 'clang') }} + run: pacman --noconfirm -S mingw-w64-i686-clang + - name: install mingw clang x86_64 + if: ${{ (matrix.msystem == 'MINGW64') && (matrix.compiler == 'clang') }} + run: pacman --noconfirm -S mingw-w64-x86_64-clang + - name: run mingw tests + run: | + make -v + export CC=${{ matrix.compiler }} + $CC --version + CFLAGS="${{ matrix.cflags }}" make -j allzstd + echo "Testing $CC ${{ matrix.msystem }}" + make clean + MSYS="" make check + + visual-runtime-tests: + runs-on: windows-latest + strategy: + matrix: + platform: [x64, Win32] + configuration: [Release] + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0 + - name: Build and run tests + working-directory: ${{env.GITHUB_WORKSPACE}} + env: + ZSTD_BIN: ./zstd.exe + DATAGEN_BIN: ./datagen.exe + # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + run: | + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v142 /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} + COPY build\VS2010\bin\${{matrix.platform}}_${{matrix.configuration}}\*.exe tests\ + CD tests + sh -e playTests.sh + .\fuzzer.exe -T2m + + # Following instructions at: https://github.com/marketplace/actions/install-cygwin-action + cygwin-tests: + runs-on: windows-latest + steps: + - run: git config --global core.autocrlf input + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - uses: cygwin/cygwin-install-action@f61179d72284ceddc397ed07ddb444d82bf9e559 # tag=v5 + with: + platform: x86_64 + packages: >- + autoconf, + automake, + gcc-g++, + make, + mingw64-x86_64-gcc-g++, + patch, + perl + - name: cygwin tests + shell: C:\cygwin\bin\bash.exe --noprofile --norc -eo pipefail '{0}' + run: >- + export PATH=/usr/bin:$(cygpath ${SYSTEMROOT})/system32 && + export CFLAGS="-Werror -O1" && + ls && + make -j allzstd && + make -C tests fuzzer && + ./tests/fuzzer.exe -v -T1m + - name: cygwin install test + shell: C:\cygwin\bin\bash.exe --noprofile --norc -eo pipefail '{0}' + run: >- + make -j && + make install + + pkg-config: + runs-on: ubuntu-latest + container: + image: debian:testing + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: Install dependencies + run: | + apt -y update + apt -y install --no-install-recommends gcc libc6-dev make pkg-config + - name: Build and install + run: make -C lib install + - name: Test pkg-config + run: | + cc -Wall -Wextra -Wpedantic -Werror -o simple examples/simple_compression.c $(pkg-config --cflags --libs libzstd) + ./simple LICENSE + + versions-compatibility: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: Versions Compatibility Test + run: | + make -C tests versionsTest + + clangbuild: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: make clangbuild + run: | + make clangbuild + + gcc-pgo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: Build PGO Zstd with GCC + env: + CC: gcc + run: | + make -C programs zstd-pgo + ./programs/zstd -b + + clang-pgo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: Build PGO Zstd with Clang + env: + CC: clang + run: | + sudo apt install -y llvm + llvm-profdata --version + make -C programs zstd-pgo + ./programs/zstd -b + + intel-cet-compatibility: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: Build Zstd + run: | + make -j zstd V=1 + readelf -n zstd + - name: Get Intel SDE + run: | + curl -LO https://downloadmirror.intel.com/813591/sde-external-9.33.0-2024-01-07-lin.tar.xz + tar xJvf sde-external-9.33.0-2024-01-07-lin.tar.xz + - name: Configure Permissions + run: | + echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope + - name: Run Under SDE + run: | + sde-external-9.33.0-2024-01-07-lin/sde -cet -cet-raise 0 -cet-endbr-exe -cet-stderr -cet-abort -- ./zstd -b3 + + icx: + # install instructions: https://www.intel.com/content/www/us/en/docs/oneapi/installation-guide-linux/2025-0/apt-005.html + name: icx-check + runs-on: ubuntu-latest + steps: + - name: install icx + run: | + # download the key to system keyring + wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \ + | gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null + + # add signed entry to apt sources and configure the APT client to use Intel repository: + echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list + sudo apt-get update + sudo apt-get install -y intel-basekit intel-hpckit + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: make check + run: | + source /opt/intel/oneapi/setvars.sh + make CC=icx check diff --git a/cpp/third_party/zstd-1.5.7/.github/workflows/nightly.yml b/cpp/third_party/zstd-1.5.7/.github/workflows/nightly.yml new file mode 100644 index 000000000..5e531d3b6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/workflows/nightly.yml @@ -0,0 +1,38 @@ +name: facebook/zstd/nightly +on: + schedule: + - cron: '0 0 * * *' + push: + branches: + - release + - dev + - '*nightly*' +permissions: read-all +jobs: + regression-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev + - name: Regression Test + run: | + make -C programs zstd + make -C tests/regression test + +# Longer tests + #- make -C tests test-zstd-nolegacy && make clean + #- pyenv global 3.4.4; make -C tests versionsTest && make clean + #- make zlibwrapper && make clean + #- gcc -v; make -C tests test32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean + #- make uasan && make clean + #- make asan32 && make clean + #- make -C tests test32 CC=clang MOREFLAGS="-g -fsanitize=address -I/usr/include/x86_64-linux-gnu" +# Valgrind tests + #- CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make clean + #- make -C tests valgrindTest && make clean +# ARM, AArch64, PowerPC, PowerPC64 tests + #- make ppctest && make clean + #- make ppc64test && make clean + #- make armtest && make clean + #- make aarch64test && make clean diff --git a/cpp/third_party/zstd-1.5.7/.github/workflows/publish-release-artifacts.yml b/cpp/third_party/zstd-1.5.7/.github/workflows/publish-release-artifacts.yml new file mode 100644 index 000000000..f7af27914 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/workflows/publish-release-artifacts.yml @@ -0,0 +1,73 @@ +name: publish-release-artifacts + +on: + release: + types: + - published + +permissions: read-all + +jobs: + publish-release-artifacts: + permissions: + contents: write # to fetch code and upload artifacts + + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3 + + - name: Archive + env: + RELEASE_SIGNING_KEY: ${{ secrets.RELEASE_SIGNING_KEY }} + RELEASE_SIGNING_KEY_PASSPHRASE: ${{ secrets.RELEASE_SIGNING_KEY_PASSPHRASE }} + run: | + # compute file name + export TAG="$(echo "$GITHUB_REF" | sed -n 's_^refs/tags/__p')" + if [ -z "$TAG" ]; then + echo "action must be run on a tag. GITHUB_REF is not a tag: $GITHUB_REF" + exit 1 + fi + # Attempt to extract "1.2.3" from "v1.2.3" to maintain artifact name backwards compat. + # Otherwise, degrade to using full tag. + export VERSION="$(echo "$TAG" | sed 's_^v\([0-9]\+\.[0-9]\+\.[0-9]\+\)$_\1_')" + export ZSTD_VERSION="zstd-$VERSION" + + # archive + git archive $TAG \ + --prefix $ZSTD_VERSION/ \ + --format tar \ + -o $ZSTD_VERSION.tar + + # Do the rest of the work in a sub-dir so we can glob everything we want to publish. + mkdir artifacts/ + mv $ZSTD_VERSION.tar artifacts/ + cd artifacts/ + + # compress + zstd -k -19 $ZSTD_VERSION.tar + gzip -k -9 $ZSTD_VERSION.tar + + # we only publish the compressed tarballs + rm $ZSTD_VERSION.tar + + # hash + sha256sum $ZSTD_VERSION.tar.zst > $ZSTD_VERSION.tar.zst.sha256 + sha256sum $ZSTD_VERSION.tar.gz > $ZSTD_VERSION.tar.gz.sha256 + + # sign + if [ -n "$RELEASE_SIGNING_KEY" ]; then + export GPG_BATCH_OPTS="--batch --no-use-agent --pinentry-mode loopback --no-tty --yes" + echo "$RELEASE_SIGNING_KEY" | gpg $GPG_BATCH_OPTS --import + gpg $GPG_BATCH_OPTS --armor --sign --sign-with signing@zstd.net --detach-sig --passphrase "$RELEASE_SIGNING_KEY_PASSPHRASE" --output $ZSTD_VERSION.tar.zst.sig $ZSTD_VERSION.tar.zst + gpg $GPG_BATCH_OPTS --armor --sign --sign-with signing@zstd.net --detach-sig --passphrase "$RELEASE_SIGNING_KEY_PASSPHRASE" --output $ZSTD_VERSION.tar.gz.sig $ZSTD_VERSION.tar.gz + fi + + - name: Publish + uses: skx/github-action-publish-binaries@b9ca5643b2f1d7371a6cba7f35333f1461bbc703 # tag=release-2.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: artifacts/* diff --git a/cpp/third_party/zstd-1.5.7/.github/workflows/scorecards.yml b/cpp/third_party/zstd-1.5.7/.github/workflows/scorecards.yml new file mode 100644 index 000000000..e532b03bf --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/workflows/scorecards.yml @@ -0,0 +1,64 @@ +name: Scorecards supply-chain security +on: + # Only the default branch is supported. + branch_protection_rule: + schedule: + - cron: '22 21 * * 2' + push: + # TODO: Add release branch when supported? + branches: [ "dev" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecards analysis + if: github.repository == 'facebook/zstd' + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Used to receive a badge. + id-token: write + # Needs for private repositories. + contents: read + actions: read + + steps: + - name: "Checkout code" + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # tag=v2.4.0 + with: + results_file: results.sarif + results_format: sarif + # (Optional) Read-only PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecards on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. + # repo_token: ${{ secrets.SCORECARD_READ_TOKEN }} + + # Publish the results for public repositories to enable scorecard badges. For more details, see + # https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories, `publish_results` will automatically be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # tag=v3.28.9 + with: + sarif_file: results.sarif diff --git a/cpp/third_party/zstd-1.5.7/.github/workflows/windows-artifacts.yml b/cpp/third_party/zstd-1.5.7/.github/workflows/windows-artifacts.yml new file mode 100644 index 000000000..35999476e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.github/workflows/windows-artifacts.yml @@ -0,0 +1,58 @@ +name: windows-artifacts + +on: + push: + branches: [ test_artifacts, win_artifacts ] + release: + types: + - published + +permissions: read-all + +jobs: + windows-artifacts: + # see https://ariya.io/2020/07/on-github-actions-with-msys2 + runs-on: windows-latest + # see https://github.com/msys2/setup-msys2 + strategy: + matrix: + include: + - { msystem: mingw64, env: x86_64, ziparch: win64 } + - { msystem: mingw32, env: i686, ziparch: win32 } + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3 + - uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # tag=v2.26.0 + with: + msystem: ${{ matrix.msystem }} + install: make zlib git p7zip mingw-w64-${{matrix.env}}-gcc + update: true + + - name: display versions + run: | + make -v + cc -v + + - name: Building zlib to static link + run: | + git clone --depth 1 --branch v1.2.11 https://github.com/madler/zlib + make -C zlib -f win32/Makefile.gcc libz.a + + - name: Building zstd programs + run: | + CPPFLAGS=-I../zlib LDFLAGS=../zlib/libz.a make -j allzstd MOREFLAGS=-static V=1 + + - name: Create artifacts + run: | + ./lib/dll/example/build_package.bat + mv bin/ zstd-${{ github.ref_name }}-${{matrix.ziparch}}/ + 7z a -tzip -mx9 zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip zstd-${{ github.ref_name }}-${{matrix.ziparch}}/ + cd .. + + - name: Publish zstd-$VERSION-${{matrix.ziparch}}.zip + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1 + with: + path: ${{ github.workspace }}/zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip + name: zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip diff --git a/cpp/third_party/zstd-1.5.7/.gitignore b/cpp/third_party/zstd-1.5.7/.gitignore new file mode 100644 index 000000000..4b50bb186 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/.gitignore @@ -0,0 +1,63 @@ +# Object files +*.o +*.ko +*.dSYM + +# Libraries +*.lib +*.a + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib +*.framework +*.xcframework + +# Executables +/zstd +zstdmt +*.exe +*.out +*.app + +# Test artefacts +tmp* +*.zst +*.zstd +dictionary. +dictionary +NUL +cmakebuild/ +install/ + +# Build artefacts +contrib/linux-kernel/linux/ +projects/ +bin/ +.buckd/ +buck-out/ +build-* +*.gcda + +# IDE +.clang_complete +compile_flags.txt +.clang-format + +# Other files +.directory +_codelite/ +_zstdbench/ +*.idea +*.swp +.DS_Store +googletest/ +*.d +*.vscode +*.code-workspace +compile_commands.json +.clangd +perf.data +perf.data.old diff --git a/cpp/third_party/zstd-1.5.7/CHANGELOG b/cpp/third_party/zstd-1.5.7/CHANGELOG new file mode 100644 index 000000000..92df0f462 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/CHANGELOG @@ -0,0 +1,863 @@ +V1.5.7 (Feb 2025) +fix: compression bug in 32-bit mode associated with long-lasting sessions +api: new method `ZSTD_compressSequencesAndLiterals()` (#4217, #4232) +api: `ZSTD_getFrameHeader()` works on skippable frames (#4228) +perf: substantial compression speed improvements (up to +30%) on small data, by @TocarIP (#4144) and @cyan4973 (#4165) +perf: improved compression speed (~+5%) for dictionary compression at low levels (#4170) +perf: much faster speed for `--patch-from` at high compression levels (#4276) +perf: higher `--patch-from` compression ratios, notably at high levels (#4288) +perf: better speed for binaries on Windows (@pps83) and when compiled with Visual Studio (@MessyHack) +perf: slight compression ratio improvement thanks to better block boundaries (#4136, #4176, #4178) +perf: slight compression ratio improvement for `dfast`, aka levels 3 and 4 (#4171) +perf: runtime bmi2 detection enabled on x86 32-bit mode (#4251) +cli: multi-threading as default CLI setting, by @daniellerozenblit +cli: new `--max` command (#4290) +build: improve `msbuild` version autodetection, support VS2022, by @ManuelBlanc +build: fix `meson` build by @artem and @Victor-C-Zhang, and on Windows by @bgilbert +build: compatibility with Apple Framework, by @Treata11 +build: improve icc/icx compatibility, by @josepho0918 and @luau-project +build: improve compatibility with Android NDK, by Adenilson Cavalcanti +portability: linux kernel branch, with improved support for Sequence producers (@embg, @gcabiddu, @cyan4973) +portability: improved qnx compatibility, suggested by @rainbowball +portability: improved install script for FreeBSD, by @sunpoet +portability: fixed test suite compatibility with gnu hurd, by @diegonc +doc: clarify specification, by @elasota +misc: improved tests/decodecorpus validation tool (#4102), by antmicro + +V1.5.6 (Mar 2024) +api: Promote `ZSTD_c_targetCBlockSize` to Stable API by @felixhandte +api: new `ZSTD_d_maxBlockSize` experimental parameter, to reduce streaming decompression memory, by @terrelln +perf: improve performance of param `ZSTD_c_targetCBlockSize`, by @Cyan4973 +perf: improved compression of arrays of integers at high compression, by @Cyan4973 +lib: reduce binary size with selective build-time exclusion, by @felixhandte +lib: improved huffman speed on small data and linux kernel, by @terrelln +lib: accept dictionaries with partial literal tables, by @terrelln +lib: fix CCtx size estimation with external sequence producer, by @embg +lib: fix corner case decoder behaviors, by @Cyan4973 and @aimuz +lib: fix zdict prototype mismatch in static_only mode, by @ldv-alt +lib: fix several bugs in magicless-format decoding, by @embg +cli: add common compressed file types to `--exclude-compressed`` by @daniellerozenblit +cli: fix mixing `-c` and `-o` commands with `--rm`, by @Cyan4973 +cli: fix erroneous exclusion of hidden files with `--output-dir-mirror` by @felixhandte +cli: improved time accuracy on BSD, by @felixhandte +cli: better errors on argument parsing, by @KapJI +tests: better compatibility with older versions of `grep`, by @Cyan4973 +tests: lorem ipsum generator as default backup content, by @Cyan4973 +build: cmake improvements by @terrelln, @sighingnow, @gjasny, @JohanMabille, @Saverio976, @gruenich, @teo-tsirpanis +build: bazel support, by @jondo2010 +build: fix cross-compiling for AArch64 with lld by @jcelerier +build: fix Apple platform compatibility, by @nidhijaju +build: fix Visual 2012 and lower compatibility, by @Cyan4973 +build: improve win32 support, by @DimitriPapadopoulos +build: better C90 compliance for zlibWrapper, by @emaste +port: make: fat binaries on macos, by @mredig +port: ARM64EC compatibility for Windows, by @dunhor +port: QNX support by @klausholstjacobsen +port: MSYS2 and Cygwin makefile installation and test support, by @QBos07 +port: risc-v support validation in CI, by @Cyan4973 +port: sparc64 support validation in CI, by @Cyan4973 +port: AIX compatibility, by @likema +port: HP-UX compatibility, by @likema +doc: Improved specification accuracy, by @elasota +bug: Fix and deprecate ZSTD_generateSequences (#3981) + +v1.5.5 (Apr 2023) +fix: fix rare corruption bug affecting the high compression mode, reported by @danlark1 (#3517, @terrelln) +perf: improve mid-level compression speed (#3529, #3533, #3543, @yoniko and #3552, @terrelln) +lib: deprecated bufferless block-level API (#3534) by @terrelln +cli: mmap large dictionaries to save memory, by @daniellerozenblit +cli: improve speed of --patch-from mode (~+50%) (#3545) by @daniellerozenblit +cli: improve i/o speed (~+10%) when processing lots of small files (#3479) by @felixhandte +cli: zstd no longer crashes when requested to write into write-protected directory (#3541) by @felixhandte +cli: fix decompression into block device using -o, reported by @georgmu (#3583) +build: fix zstd CLI compiled with lzma support but not zlib support (#3494) by @Hello71 +build: fix cmake does no longer require 3.18 as minimum version (#3510) by @kou +build: fix MSVC+ClangCL linking issue (#3569) by @tru +build: fix zstd-dll, version of zstd CLI that links to the dynamic library (#3496) by @yoniko +build: fix MSVC warnings (#3495) by @embg +doc: updated zstd specification to clarify corner cases, by @Cyan4973 +doc: document how to create fat binaries for macos (#3568) by @rickmark +misc: improve seekable format ingestion speed (~+100%) for very small chunk sizes (#3544) by @Cyan4973 +misc: tests/fullbench can benchmark multiple files (#3516) by @dloidolt + +v1.5.4 (Feb 2023) +perf: +20% faster huffman decompression for targets that can't compile x64 assembly (#3449, @terrelln) +perf: up to +10% faster streaming compression at levels 1-2 (#3114, @embg) +perf: +4-13% for levels 5-12 by optimizing function generation (#3295, @terrelln) +pref: +3-11% compression speed for `arm` target (#3199, #3164, #3145, #3141, #3138, @JunHe77 and #3139, #3160, @danlark1) +perf: +5-30% faster dictionary compression at levels 1-4 (#3086, #3114, #3152, @embg) +perf: +10-20% cold dict compression speed by prefetching CDict tables (#3177, @embg) +perf: +1% faster compression by removing a branch in ZSTD_fast_noDict (#3129, @felixhandte) +perf: Small compression ratio improvements in high compression mode (#2983, #3391, @Cyan4973 and #3285, #3302, @daniellerozenblit) +perf: small speed improvement by better detecting `STATIC_BMI2` for `clang` (#3080, @TocarIP) +perf: Improved streaming performance when `ZSTD_c_stableInBuffer` is set (#2974, @Cyan4973) +cli: Asynchronous I/O for improved cli speed (#2975, #2985, #3021, #3022, @yoniko) +cli: Change `zstdless` behavior to align with `zless` (#2909, @binhdvo) +cli: Keep original file if `-c` or `--stdout` is given (#3052, @dirkmueller) +cli: Keep original files when result is concatenated into a single output with `-o` (#3450, @Cyan4973) +cli: Preserve Permissions and Ownership of regular files (#3432, @felixhandte) +cli: Print zlib/lz4/lzma library versions with `-vv` (#3030, @terrelln) +cli: Print checksum value for single frame files with `-lv` (#3332, @Cyan4973) +cli: Print `dictID` when present with `-lv` (#3184, @htnhan) +cli: when `stderr` is *not* the console, disable status updates, but preserve final summary (#3458, @Cyan4973) +cli: support `--best` and `--no-name` in `gzip` compatibility mode (#3059, @dirkmueller) +cli: support for `posix` high resolution timer `clock_gettime()`, for improved benchmark accuracy (#3423, @Cyan4973) +cli: improved help/usage (`-h`, `-H`) formatting (#3094, @dirkmueller and #3385, @jonpalmisc) +cli: Fix better handling of bogus numeric values (#3268, @ctkhanhly) +cli: Fix input consists of multiple files _and_ `stdin` (#3222, @yoniko) +cli: Fix tiny files passthrough (#3215, @cgbur) +cli: Fix for `-r` on empty directory (#3027, @brailovich) +cli: Fix empty string as argument for `--output-dir-*` (#3220, @embg) +cli: Fix decompression memory usage reported by `-vv --long` (#3042, @u1f35c, and #3232, @zengyijing) +cli: Fix infinite loop when empty input is passed to trainer (#3081, @terrelln) +cli: Fix `--adapt` doesn't work when `--no-progress` is also set (#3354, @terrelln) +api: Support for Block-Level Sequence Producer (#3333, @embg) +api: Support for in-place decompression (#3432, @terrelln) +api: New `ZSTD_CCtx_setCParams()` function, set all parameters defined in a `ZSTD_compressionParameters` structure (#3403, @Cyan4973) +api: Streaming decompression detects incorrect header ID sooner (#3175, @Cyan4973) +api: Window size resizing optimization for edge case (#3345, @daniellerozenblit) +api: More accurate error codes for busy-loop scenarios (#3413, #3455, @Cyan4973) +api: Fix limit overflow in `compressBound` and `decompressBound` (#3362, #3373, Cyan4973) reported by @nigeltao +api: Deprecate several advanced experimental functions: streaming (#3408, @embg), copy (#3196, @mileshu) +bug: Fix corruption that rarely occurs in 32-bit mode with wlog=25 (#3361, @terrelln) +bug: Fix for block-splitter (#3033, @Cyan4973) +bug: Fixes for Sequence Compression API (#3023, #3040, @Cyan4973) +bug: Fix leaking thread handles on Windows (#3147, @animalize) +bug: Fix timing issues with cmake/meson builds (#3166, #3167, #3170, @Cyan4973) +build: Allow user to select legacy level for cmake (#3050, @shadchin) +build: Enable legacy support by default in cmake (#3079, @niamster) +build: Meson build script improvements (#3039, #3120, #3122, #3327, #3357, @eli-schwartz and #3276, @neheb) +build: Add aarch64 to supported architectures for zstd_trace (#3054, @ooosssososos) +build: support AIX architecture (#3219, @qiongsiwu) +build: Fix `ZSTD_LIB_MINIFY` build macro, which now reduces static library size by half (#3366, @terrelln) +build: Fix Windows issues with Multithreading translation layer (#3364, #3380, @yoniko) and ARM64 target (#3320, @cwoffenden) +build: Fix `cmake` script (#3382, #3392, @terrelln and #3252 @Tachi107 and #3167 @Cyan4973) +doc: Updated man page, providing more details for `--train` mode (#3112, @Cyan4973) +doc: Add decompressor errata document (#3092, @terrelln) +misc: Enable Intel CET (#2992, #2994, @hjl-tools) +misc: Fix `contrib/` seekable format (#3058, @yhoogstrate and #3346, @daniellerozenblit) +misc: Improve speed of the one-file library generator (#3241, @wahern and #3005, @cwoffenden) + +v1.5.3 (dev version, unpublished) + +v1.5.2 (Jan, 2022) +perf: Regain Minimal memset()-ing During Reuse of Compression Contexts (@Cyan4973, #2969) +build: Build Zstd with `noexecstack` on All Architectures (@felixhandte, #2964) +doc: Clarify Licensing (@terrelln, #2981) + +v1.5.1 (Dec, 2021) +perf: rebalanced compression levels, to better match the intended speed/level curve, by @senhuang42 +perf: faster huffman decoder, using x64 assembly, by @terrelln +perf: slightly faster high speed modes (strategies fast & dfast), by @felixhandte +perf: improved binary size and faster compilation times, by @terrelln +perf: new row64 mode, used notably in level 12, by @senhuang42 +perf: faster mid-level compression speed in presence of highly repetitive patterns, by @senhuang42 +perf: minor compression ratio improvements for small data at high levels, by @cyan4973 +perf: reduced stack usage (mostly useful for Linux Kernel), by @terrelln +perf: faster compression speed on incompressible data, by @bindhvo +perf: on-demand reduced ZSTD_DCtx state size, using build macro ZSTD_DECODER_INTERNAL_BUFFER, at a small cost of performance, by @bindhvo +build: allows hiding static symbols in the dynamic library, using build macro, by @skitt +build: support for m68k (Motorola 68000's), by @cyan4973 +build: improved AIX support, by @Helflym +build: improved meson unofficial build, by @eli-schwartz +cli : custom memory limit when training dictionary (#2925), by @embg +cli : report advanced parameters information when compressing in very verbose mode (`-vv`), by @Svetlitski-FB + +v1.5.0 (May 11, 2021) +api: Various functions promoted from experimental to stable API: (#2579-2581, @senhuang42) + `ZSTD_defaultCLevel()` + `ZSTD_getDictID_fromCDict()` +api: Several experimental functions have been deprecated and will emit a compiler warning (#2582, @senhuang42) + `ZSTD_compress_advanced()` + `ZSTD_compress_usingCDict_advanced()` + `ZSTD_compressBegin_advanced()` + `ZSTD_compressBegin_usingCDict_advanced()` + `ZSTD_initCStream_srcSize()` + `ZSTD_initCStream_usingDict()` + `ZSTD_initCStream_usingCDict()` + `ZSTD_initCStream_advanced()` + `ZSTD_initCStream_usingCDict_advanced()` + `ZSTD_resetCStream()` +api: ZSTDMT_NBWORKERS_MAX reduced to 64 for 32-bit environments (@Cyan4973) +perf: Significant speed improvements for middle compression levels (#2494, @senhuang42 @terrelln) +perf: Block splitter to improve compression ratio, enabled by default for high compression levels (#2447, @senhuang42) +perf: Decompression loop refactor, speed improvements on `clang` and for `--long` modes (#2614 #2630, @Cyan4973) +perf: Reduced stack usage during compression and decompression entropy stage (#2522 #2524, @terrelln) +bug: Improve setting permissions of created files (#2525, @felixhandte) +bug: Fix large dictionary non-determinism (#2607, @terrelln) +bug: Fix non-determinism test failures on Linux i686 (#2606, @terrelln) +bug: Fix various dedicated dictionary search bugs (#2540 #2586, @senhuang42 @felixhandte) +bug: Ensure `ZSTD_estimateCCtxSize*() `monotonically increases with compression level (#2538, @senhuang42) +bug: Fix --patch-from mode parameter bound bug with small files (#2637, @occivink) +bug: Fix UBSAN error in decompression (#2625, @terrelln) +bug: Fix superblock compression divide by zero bug (#2592, @senhuang42) +bug: Make the number of physical CPU cores detection more robust (#2517, @PaulBone) +doc: Improve `zdict.h` dictionary training API documentation (#2622, @terrelln) +doc: Note that public `ZSTD_free*()` functions accept NULL pointers (#2521, @animalize) +doc: Add style guide docs for open source contributors (#2626, @Cyan4973) +tests: Better regression test coverage for different dictionary modes (#2559, @senhuang42) +tests: Better test coverage of index reduction (#2603, @terrelln) +tests: OSS-Fuzz coverage for seekable format (#2617, @senhuang42) +tests: Test coverage for ZSTD threadpool API (#2604, @senhuang42) +build: Dynamic library built multithreaded by default (#2584, @senhuang42) +build: Move `zstd_errors.h` and `zdict.h` to `lib/` root (#2597, @terrelln) +build: Allow `ZSTDMT_JOBSIZE_MIN` to be configured at compile-time, reduce default to 512KB (#2611, @Cyan4973) +build: Single file library build script moved to `build/` directory (#2618, @felixhandte) +build: `ZBUFF_*()` is no longer built by default (#2583, @senhuang42) +build: Fixed Meson build (#2548, @SupervisedThinking @kloczek) +build: Fix excessive compiler warnings with clang-cl and CMake (#2600, @nickhutchinson) +build: Detect presence of `md5` on Darwin (#2609, @felixhandte) +build: Avoid SIGBUS on armv6 (#2633, @bmwiedmann) +cli: `--progress` flag added to always display progress bar (#2595, @senhuang42) +cli: Allow reading from block devices with `--force` (#2613, @felixhandte) +cli: Fix CLI filesize display bug (#2550, @Cyan4973) +cli: Fix windows CLI `--filelist` end-of-line bug (#2620, @Cyan4973) +contrib: Various fixes for linux kernel patch (#2539, @terrelln) +contrib: Seekable format - Decompression hanging edge case fix (#2516, @senhuang42) +contrib: Seekable format - New seek table-only API (#2113 #2518, @mdittmer @Cyan4973) +contrib: Seekable format - Fix seek table descriptor check when loading (#2534, @foxeng) +contrib: Seekable format - Decompression fix for large offsets, (#2594, @azat) +misc: Automatically published release tarballs available on Github (#2535, @felixhandte) + +v1.4.9 (Mar 1, 2021) +bug: Use `umask()` to Constrain Created File Permissions (#2495, @felixhandte) +bug: Make Simple Single-Pass Functions Ignore Advanced Parameters (#2498, @terrelln) +api: Add (De)Compression Tracing Functionality (#2482, @terrelln) +api: Support References to Multiple DDicts (#2446, @senhuang42) +api: Add Function to Generate Skippable Frame (#2439, @senhuang42) +perf: New Algorithms for the Long Distance Matcher (#2483, @mpu) +perf: Performance Improvements for Long Distance Matcher (#2464, @mpu) +perf: Don't Shrink Window Log when Streaming with a Dictionary (#2451, @terrelln) +cli: Fix `--output-dir-mirror` rejection of `..` -containing paths (#2512, @felixhandte) +cli: Allow Input From Console When `-f`/`--force` is Passed (#2466, @felixhandte) +cli: Improve Help Message (#2500, @senhuang42) +tests: Remove Flaky Tests (#2455, #2486, #2445, @Cyan4973) +tests: Correctly Invoke md5 Utility on NetBSD (#2492, @niacat) +tests: Avoid Using `stat -c` on NetBSD (#2513, @felixhandte) +build: Zstd CLI Can Now be Linked to Dynamic `libzstd` (#2457, #2454 @Cyan4973) +build: Hide and Avoid Using Static-Only Symbols (#2501, #2504, @skitt) +build: CMake: Enable Only C for lib/ and programs/ Projects (#2498, @concatime) +build: CMake: Use `configure_file()` to Create the `.pc` File (#2462, @lazka) +build: Fix Fuzzer Compiler Detection & Update UBSAN Flags (#2503, @terrelln) +build: Add Guards for `_LARGEFILE_SOURCE` and `_LARGEFILE64_SOURCE` (#2444, @indygreg) +build: Improve `zlibwrapper` Makefile (#2437, @Cyan4973) +contrib: Add `recover_directory` Program (#2473, @terrelln) +doc: Change License Year to 2021 (#2452 & #2465, @terrelln & @senhuang42) +doc: Fix Typos (#2459, @ThomasWaldmann) + +v1.4.8 (Dec 18, 2020) +hotfix: wrong alignment of an internal buffer + +v1.4.7 (Dec 16, 2020) +perf: stronger --long mode at high compression levels, by @senhuang42 +perf: stronger --patch-from at high compression levels, thanks to --long improvements +perf: faster dictionary compression at medium compression levels, by @felixhandte +perf: small speed & memory usage improvements for ZSTD_compress2(), by @terrelln +perf: improved fast compression speeds with Visual Studio, by @animalize +cli : Set nb of threads with environment variable ZSTD_NBTHREADS, by @senhuang42 +cli : accept decompressing files with *.zstd suffix +cli : provide a condensed summary by default when processing multiple files +cli : fix : stdin input no longer confused as user prompt +cli : improve accuracy of several error messages +api : new sequence ingestion API, by @senhuang42 +api : shared thread pool: control total nb of threads used by multiple compression jobs, by @marxin +api : new ZSTD_getDictID_fromCDict(), by @LuAPi +api : zlibWrapper only uses public API, and is compatible with dynamic library, by @terrelln +api : fix : multithreaded compression has predictable output even in special cases (see #2327) (issue not accessible from cli) +api : fix : dictionary compression correctly respects dictionary compression level (see #2303) (issue not accessible from cli) +build: fix cmake script when using path with spaces, by @terrelln +build: improved compile-time detection of aarch64/neon platforms, by @bsdimp +build: Fix building on AIX 5.1, by @likema +build: compile paramgrill with cmake on Windows, requested by @mirh +doc : clarify repcode updates in format specification, by @felixhandte + +v1.4.6 +fix : Always return dstSize_tooSmall when that is the case +fix : Fix ZSTD_initCStream_advanced() with static allocation and no dictionary +perf: Improve small block decompression speed by 20%+, by @terrelln +perf: Reduce compression stack usage by 1 KB, by @terrelln +perf: Improve decompression speed by improving ZSTD_wildcopy, by @helloguo (#2252, #2256) +perf: Improve histogram construction, by @cyan4973 (#2253) +cli : Add --output-dir-mirror option, by @xxie24 (#2219) +cli : Warn when (de)compressing multiple files into a single output, by @senhuang42 (#2279) +cli : Improved progress bar and status summary when (de)compressing multiple files, by @senhuang42 (#2283) +cli : Call stat less often, by @felixhandte (#2262) +cli : Allow --patch-from XXX and --filelist XXX in addition to --patch-from=XXX and --filelist=XXX, by @cyan4973 (#2250) +cli : Allow --patch-from to compress stdin with --stream-size, by @bimbashrestha (#2206) +api : Do not install zbuff.h, since it has long been deprecated, by @cyan4973 (#2166). +api : Fix ZSTD_CCtx_setParameter() with ZSTD_c_compressionLevel to make 0 mean default level, by @i-do-cpp (#2291) +api : Rename ZSTDMT_NBTHREADS_MAX to ZSTDMT_NBWORKERS_MAX, by @marxin (#2228). +build: Install pkg-config file with CMake and MinGW, by @tonytheodore (#2183) +build: Install DLL with CMake on Windows, by @BioDataAnalysis (#2221) +build: Fix DLL install location with CMake, by @xantares and @bimbashrestha (#2186) +build: Add ZSTD_NO_UNUSED_FUNCTIONS macro to hide unused functions +build: Add ZSTD_NO_INTRINSICS macro to avoid explicit intrinsics +build: Add STATIC_BMI2 macro for compile time detection of BMI2 on MSVC, by @Niadb (#2258) +build: Fix -Wcomma warnings, by @cwoffenden +build: Remove distutils requirement for meson build, by @neheb (#2197) +build: Fix cli compilation with uclibc +build: Fix cli compilation without st_mtime, by @ffontaine (#2246) +build: Fix shadowing warnings in library +build: Fix single file library compilation with Enscripten, by @yoshihitoh (#2227) +misc: Improve single file library and include dictBuilder, by @cwoffenden +misc: Allow compression dictionaries with missing symbols +misc: Add freestanding translation script in contrib/freestanding_lib +misc: Collect all of zstd's libc dependencies into zstd_deps.h +doc : Add ZSTD_versionString() to manual, by @animalize +doc : Fix documentation for ZSTD_CCtxParams_setParameter(), by @felixhandte (#2270) + +v1.4.5 (May 22, 2020) +fix : Compression ratio regression on huge files (> 3 GB) using high levels (--ultra) and multithreading, by @terrelln +perf: Improved decompression speed: x64 : +10% (clang) / +5% (gcc); ARM : from +15% to +50%, depending on SoC, by @terrelln +perf: Automatically downsizes ZSTD_DCtx when too large for too long (#2069, by @bimbashreshta) +perf: Improved fast compression speed on aarch64 (#2040, ~+3%, by @caoyzh) +perf: Small level 1 compression speed gains (depending on compiler) +cli : New --patch-from command, create and apply patches from files, by @bimbashreshta +cli : New --filelist= : Provide a list of files to operate upon from a file +cli : -b -d command can now benchmark decompression on multiple files +cli : New --no-content-size command +cli : New --show-default-cparams information command +api : ZDICT_finalizeDictionary() is promoted to stable (#2111) +api : new experimental parameter ZSTD_d_stableOutBuffer (#2094) +build: Generate a single-file libzstd library (#2065, by @cwoffenden) +build: Relative includes no longer require -I compiler flags for zstd lib subdirs (#2103, by @felixhandte) +build: zstd now compiles cleanly under -pedantic (#2099) +build: zstd now compiles with make-4.3 +build: Support mingw cross-compilation from Linux, by @Ericson2314 +build: Meson multi-thread build fix on windows +build: Some misc icc fixes backed by new ci test on travis +misc: bitflip analyzer tool, by @felixhandte +misc: Extend largeNbDicts benchmark to compression +misc: Edit-distance match finder in contrib/ +doc : Improved beginner CONTRIBUTING.md docs +doc : New issue templates for zstd + +v1.4.4 (Nov 6, 2019) +perf: Improved decompression speed, by > 10%, by @terrelln +perf: Better compression speed when re-using a context, by @felixhandte +perf: Fix compression ratio when compressing large files with small dictionary, by @senhuang42 +perf: zstd reference encoder can generate RLE blocks, by @bimbashrestha +perf: minor generic speed optimization, by @davidbolvansky +api: new ability to extract sequences from the parser for analysis, by @bimbashrestha +api: fixed decoding of magic-less frames, by @terrelln +api: fixed ZSTD_initCStream_advanced() performance with fast modes, reported by @QrczakMK +cli: Named pipes support, by @bimbashrestha +cli: short tar's extension support, by @stokito +cli: command --output-dir-flat= , generates target files into requested directory, by @senhuang42 +cli: commands --stream-size=# and --size-hint=#, by @nmagerko +cli: command --exclude-compressed, by @shashank0791 +cli: faster `-t` test mode +cli: improved some error messages, by @vangyzen +cli: fix command `-D dictionary` on Windows, reported by @artyompetrov +cli: fix rare deadlock condition within dictionary builder, by @terrelln +build: single-file decoder with emscripten compilation script, by @cwoffenden +build: fixed zlibWrapper compilation on Visual Studio, reported by @bluenlive +build: fixed deprecation warning for certain gcc version, reported by @jasonma163 +build: fix compilation on old gcc versions, by @cemeyer +build: improved installation directories for cmake script, by Dmitri Shubin +pack: modified pkgconfig, for better integration into openwrt, requested by @neheb +misc: Improved documentation : ZSTD_CLEVEL, DYNAMIC_BMI2, ZSTD_CDict, function deprecation, zstd format +misc: fixed educational decoder : accept larger literals section, and removed UNALIGNED() macro + +v1.4.3 (Aug 20, 2019) +bug: Fix Dictionary Compression Ratio Regression by @cyan4973 (#1709) +bug: Fix Buffer Overflow in legacy v0.3 decompression by @felixhandte (#1722) +build: Add support for IAR C/C++ Compiler for Arm by @joseph0918 (#1705) + +v1.4.2 (Jul 26, 2019) +bug: Fix bug in zstd-0.5 decoder by @terrelln (#1696) +bug: Fix seekable decompression in-memory API by @iburinoc (#1695) +misc: Validate blocks are smaller than size limit by @vivekmg (#1685) +misc: Restructure source files by @ephiepark (#1679) + +v1.4.1 (Jul 20, 2019) +bug: Fix data corruption in niche use cases by @terrelln (#1659) +bug: Fuzz legacy modes, fix uncovered bugs by @terrelln (#1593, #1594, #1595) +bug: Fix out of bounds read by @terrelln (#1590) +perf: Improve decode speed by ~7% @mgrice (#1668) +perf: Slightly improved compression ratio of level 3 and 4 (ZSTD_dfast) by @cyan4973 (#1681) +perf: Slightly faster compression speed when re-using a context by @cyan4973 (#1658) +perf: Improve compression ratio for small windowLog by @cyan4973 (#1624) +perf: Faster compression speed in high compression mode for repetitive data by @terrelln (#1635) +api: Add parameter to generate smaller dictionaries by @tyler-tran (#1656) +cli: Recognize symlinks when built in C99 mode by @felixhandte (#1640) +cli: Expose cpu load indicator for each file on -vv mode by @ephiepark (#1631) +cli: Restrict read permissions on destination files by @chungy (#1644) +cli: zstdgrep: handle -f flag by @felixhandte (#1618) +cli: zstdcat: follow symlinks by @vejnar (#1604) +doc: Remove extra size limit on compressed blocks by @felixhandte (#1689) +doc: Fix typo by @yk-tanigawa (#1633) +doc: Improve documentation on streaming buffer sizes by @cyan4973 (#1629) +build: CMake: support building with LZ4 @leeyoung624 (#1626) +build: CMake: install zstdless and zstdgrep by @leeyoung624 (#1647) +build: CMake: respect existing uninstall target by @j301scott (#1619) +build: Make: skip multithread tests when built without support by @michaelforney (#1620) +build: Make: Fix examples/ test target by @sjnam (#1603) +build: Meson: rename options out of deprecated namespace by @lzutao (#1665) +build: Meson: fix build by @lzutao (#1602) +build: Visual Studio: don't export symbols in static lib by @scharan (#1650) +build: Visual Studio: fix linking by @absotively (#1639) +build: Fix MinGW-W64 build by @myzhang1029 (#1600) +misc: Expand decodecorpus coverage by @ephiepark (#1664) + +v1.4.0 (Apr 17, 2019) +perf: Improve level 1 compression speed in most scenarios by 6% by @gbtucker and @terrelln +api: Move the advanced API, including all functions in the staging section, to the stable section +api: Make ZSTD_e_flush and ZSTD_e_end block for maximum forward progress +api: Rename ZSTD_CCtxParam_getParameter to ZSTD_CCtxParams_getParameter +api: Rename ZSTD_CCtxParam_setParameter to ZSTD_CCtxParams_setParameter +api: Don't export ZSTDMT functions from the shared library by default +api: Require ZSTD_MULTITHREAD to be defined to use ZSTDMT +api: Add ZSTD_decompressBound() to provide an upper bound on decompressed size by @shakeelrao +api: Fix ZSTD_decompressDCtx() corner cases with a dictionary +api: Move ZSTD_getDictID_*() functions to the stable section +api: Add ZSTD_c_literalCompressionMode flag to enable or disable literal compression by @terrelln +api: Allow compression parameters to be set when a dictionary is used +api: Allow setting parameters before or after ZSTD_CCtx_loadDictionary() is called +api: Fix ZSTD_estimateCStreamSize_usingCCtxParams() +api: Setting ZSTD_d_maxWindowLog to 0 means use the default +cli: Ensure that a dictionary is not used to compress itself by @shakeelrao +cli: Add --[no-]compress-literals flag to enable or disable literal compression +doc: Update the examples to use the advanced API +doc: Explain how to transition from old streaming functions to the advanced API in the header +build: Improve the Windows release packages +build: Improve CMake build by @hjmjohnson +build: Build fixes for FreeBSD by @lwhsu +build: Remove redundant warnings by @thatsafunnyname +build: Fix tests on OpenBSD by @bket +build: Extend fuzzer build system to work with the new clang engine +build: CMake now creates the libzstd.so.1 symlink +build: Improve Menson build by @lzutao +misc: Fix symbolic link detection on FreeBSD +misc: Use physical core count for -T0 on FreeBSD by @cemeyer +misc: Fix zstd --list on truncated files by @kostmo +misc: Improve logging in debug mode by @felixhandte +misc: Add CirrusCI tests by @lwhsu +misc: Optimize dictionary memory usage in corner cases +misc: Improve the dictionary builder on small or homogeneous data +misc: Fix spelling across the repo by @jsoref + +v1.3.8 (Dec 28, 2018) +perf: better decompression speed on large files (+7%) and cold dictionaries (+15%) +perf: slightly better compression ratio at high compression modes +api : finalized advanced API, last stage before "stable" status +api : new --rsyncable mode, by @terrelln +api : support decompression of empty frames into NULL (used to be an error) (#1385) +build: new set of macros to build a minimal size decoder, by @felixhandte +build: fix compilation on MIPS32, reported by @clbr (#1441) +build: fix compilation with multiple -arch flags, by @ryandesign +build: highly upgraded meson build, by @lzutao +build: improved buck support, by @obelisk +build: fix cmake script : can create debug build, by @pitrou +build: Makefile : grep works on both colored consoles and systems without color support +build: fixed zstd-pgo, by @bmwiedemann +cli : support ZSTD_CLEVEL environment variable, by @yijinfb (#1423) +cli : --no-progress flag, preserving final summary (#1371), by @terrelln +cli : ensure destination file is not source file (#1422) +cli : clearer error messages, especially when input file not present +doc : clarified zstd_compression_format.md, by @ulikunitz +misc: fixed zstdgrep, returns 1 on failure, by @lzutao +misc: NEWS renamed as CHANGELOG, in accordance with fboss + +v1.3.7 (Oct 20, 2018) +perf: slightly better decompression speed on clang (depending on hardware target) +fix : performance of dictionary compression for small input < 4 KB at levels 9 and 10 +build: no longer build backtrace by default in release mode; restrict further automatic mode +build: control backtrace support through build macro BACKTRACE +misc: added man pages for zstdless and zstdgrep, by @samrussell + +v1.3.6 (Oct 6, 2018) +perf: much faster dictionary builder, by @jenniferliu +perf: faster dictionary compression on small data when using multiple contexts, by @felixhandte +perf: faster dictionary decompression when using a very large number of dictionaries simultaneously +cli : fix : does no longer overwrite destination when source does not exist (#1082) +cli : new command --adapt, for automatic compression level adaptation +api : fix : block api can be streamed with > 4 GB, reported by @catid +api : reduced ZSTD_DDict size by 2 KB +api : minimum negative compression level is defined, and can be queried using ZSTD_minCLevel(). +build: support Haiku target, by @korli +build: Read Legacy format is limited to v0.5+ by default. Can be changed at compile time with macro ZSTD_LEGACY_SUPPORT. +doc : zstd_compression_format.md updated to match wording in IETF RFC 8478 +misc: tests/paramgrill, a parameter optimizer, by @GeorgeLu97 + +v1.3.5 (Jun 29, 2018) +perf: much faster dictionary compression, by @felixhandte +perf: small quality improvement for dictionary generation, by @terrelln +perf: slightly improved high compression levels (notably level 19) +mem : automatic memory release for long duration contexts +cli : fix : overlapLog can be manually set +cli : fix : decoding invalid lz4 frames +api : fix : performance degradation for dictionary compression when using advanced API, by @terrelln +api : change : clarify ZSTD_CCtx_reset() vs ZSTD_CCtx_resetParameters(), by @terrelln +build: select custom libzstd scope through control macros, by @GeorgeLu97 +build: OpenBSD patch, by @bket +build: make and make all are compatible with -j +doc : clarify zstd_compression_format.md, updated for IETF RFC process +misc: pzstd compatible with reproducible compilation, by @lamby + +v1.3.4 (Mar 27, 2018) +perf: faster speed (especially decoding speed) on recent cpus (haswell+) +perf: much better performance associating --long with multi-threading, by @terrelln +perf: better compression at levels 13-15 +cli : asynchronous compression by default, for faster experience (use --single-thread for former behavior) +cli : smoother status report in multi-threading mode +cli : added command --fast=#, for faster compression modes +cli : fix crash when not overwriting existing files, by Pádraig Brady (@pixelb) +api : `nbThreads` becomes `nbWorkers` : 1 triggers asynchronous mode +api : compression levels can be negative, for even more speed +api : ZSTD_getFrameProgression() : get precise progress status of ZSTDMT anytime +api : ZSTDMT can accept new compression parameters during compression +api : implemented all advanced dictionary decompression prototypes +build: improved meson recipe, by Shawn Landden (@shawnl) +build: VS2017 scripts, by @HaydnTrigg +misc: all /contrib projects fixed +misc: added /contrib/docker script by @gyscos + +v1.3.3 (Dec 21, 2017) +perf: faster zstd_opt strategy (levels 16-19) +fix : bug #944 : multithreading with shared dictionary and large data, reported by @gsliepen +cli : fix : content size written in header by default +cli : fix : improved LZ4 format support, by @felixhandte +cli : new : hidden command `-S`, to benchmark multiple files while generating one result per file +api : fix : support large skippable frames, by @terrelln +api : fix : streaming interface was adding a useless 3-bytes null block to small frames +api : change : when setting `pledgedSrcSize`, use `ZSTD_CONTENTSIZE_UNKNOWN` macro value to mean "unknown" +build: fix : compilation under rhel6 and centos6, reported by @pixelb +build: added `check` target + +v1.3.2 (Oct 10, 2017) +new : long range mode, using --long command, by Stella Lau (@stellamplau) +new : ability to generate and decode magicless frames (#591) +changed : maximum nb of threads reduced to 200, to avoid address space exhaustion in 32-bits mode +fix : multi-threading compression works with custom allocators +fix : ZSTD_sizeof_CStream() was over-evaluating memory usage +fix : a rare compression bug when compression generates very large distances and bunch of other conditions (only possible at --ultra -22) +fix : 32-bits build can now decode large offsets (levels 21+) +cli : added LZ4 frame support by default, by Felix Handte (@felixhandte) +cli : improved --list output +cli : new : can split input file for dictionary training, using command -B# +cli : new : clean operation artefact on Ctrl-C interruption +cli : fix : do not change /dev/null permissions when using command -t with root access, reported by @mike155 (#851) +cli : fix : write file size in header in multiple-files mode +api : added macro ZSTD_COMPRESSBOUND() for static allocation +api : experimental : new advanced decompression API +api : fix : sizeof_CCtx() used to over-estimate +build: fix : no-multithread variant compiles without pool.c dependency, reported by Mitchell Blank Jr (@mitchblank) (#819) +build: better compatibility with reproducible builds, by Bernhard M. Wiedemann (@bmwiedemann) (#818) +example : added streaming_memory_usage +license : changed /examples license to BSD + GPLv2 +license : fix a few header files to reflect new license (#825) + +v1.3.1 (Aug 21, 2017) +New license : BSD + GPLv2 +perf: substantially decreased memory usage in Multi-threading mode, thanks to reports by Tino Reichardt (@mcmilk) +perf: Multi-threading supports up to 256 threads. Cap at 256 when more are requested (#760) +cli : improved and fixed --list command, by @ib (#772) +cli : command -vV to list supported formats, by @ib (#771) +build : fixed binary variants, reported by @svenha (#788) +build : fix Visual compilation for non x86/x64 targets, reported by Greg Slazinski (@GregSlazinski) (#718) +API exp : breaking change : ZSTD_getframeHeader() provides more information +API exp : breaking change : pinned down values of error codes +doc : fixed huffman example, by Ulrich Kunitz (@ulikunitz) +new : contrib/adaptive-compression, I/O driven compression strength, by Paul Cruz (@paulcruz74) +new : contrib/long_distance_matching, statistics by Stella Lau (@stellamplau) +updated : contrib/linux-kernel, by Nick Terrell (@terrelln) + +v1.3.0 (Jul 6, 2017) +cli : new : `--list` command, by Paul Cruz +cli : changed : xz/lzma support enabled by default +cli : changed : `-t *` continue processing list after a decompression error +API : added : ZSTD_versionString() +API : promoted to stable status : ZSTD_getFrameContentSize(), by Sean Purcell +API exp : new advanced API : ZSTD_compress_generic(), ZSTD_CCtx_setParameter() +API exp : new : API for static or external allocation : ZSTD_initStatic?Ctx() +API exp : added : ZSTD_decompressBegin_usingDDict(), requested by Guy Riddle (#700) +API exp : clarified memory estimation / measurement functions. +API exp : changed : strongest strategy renamed ZSTD_btultra, fastest strategy ZSTD_fast set to 1 +tools : decodecorpus can generate random dictionary-compressed samples, by Paul Cruz +new : contrib/seekable_format, demo and API, by Sean Purcell +changed : contrib/linux-kernel, updated version and license, by Nick Terrell + +v1.2.0 (May 5, 2017) +cli : changed : Multithreading enabled by default (use target zstd-nomt or HAVE_THREAD=0 to disable) +cli : new : command -T0 means "detect and use nb of cores", by Sean Purcell +cli : new : zstdmt symlink hardwired to `zstd -T0` +cli : new : command --threads=# (#671) +cli : changed : cover dictionary builder by default, for improved quality, by Nick Terrell +cli : new : commands --train-cover and --train-legacy, to select dictionary algorithm and parameters +cli : experimental targets `zstd4` and `xzstd4`, with support for lz4 format, by Sean Purcell +cli : fix : does not output compressed data on console +cli : fix : ignore symbolic links unless --force specified, +API : breaking change : ZSTD_createCDict_advanced(), only use compressionParameters as argument +API : added : prototypes ZSTD_*_usingCDict_advanced(), for direct control over frameParameters. +API : improved: ZSTDMT_compressCCtx() reduced memory usage +API : fix : ZSTDMT_compressCCtx() now provides srcSize in header (#634) +API : fix : src size stored in frame header is controlled at end of frame +API : fix : enforced consistent rules for pledgedSrcSize==0 (#641) +API : fix : error code "GENERIC" replaced by "dstSizeTooSmall" when appropriate +build: improved cmake script, by @Majlen +build: enabled Multi-threading support for *BSD, by Baptiste Daroussin +tools: updated Paramgrill. Command -O# provides best parameters for sample and speed target. +new : contrib/linux-kernel version, by Nick Terrell + +v1.1.4 (Mar 18, 2017) +cli : new : can compress in *.gz format, using --format=gzip command, by Przemyslaw Skibinski +cli : new : advanced benchmark command --priority=rt +cli : fix : write on sparse-enabled file systems in 32-bits mode, by @ds77 +cli : fix : --rm remains silent when input is stdin +cli : experimental : xzstd, with support for xz/lzma decoding, by Przemyslaw Skibinski +speed : improved decompression speed in streaming mode for single shot scenarios (+5%) +memory: DDict (decompression dictionary) memory usage down from 150 KB to 20 KB +arch: 32-bits variant able to generate and decode very long matches (>32 MB), by Sean Purcell +API : new : ZSTD_findFrameCompressedSize(), ZSTD_getFrameContentSize(), ZSTD_findDecompressedSize() +API : changed : dropped support of legacy versions <= v0.3 (can be changed by modifying ZSTD_LEGACY_SUPPORT value) +build : new: meson build system in contrib/meson, by Dima Krasner +build : improved cmake script, by @Majlen +build : added -Wformat-security flag, as recommended by Padraig Brady +doc : new : educational decoder, by Sean Purcell + +v1.1.3 (Feb 7, 2017) +cli : zstd can decompress .gz files (can be disabled with `make zstd-nogz` or `make HAVE_ZLIB=0`) +cli : new : experimental target `make zstdmt`, with multi-threading support +cli : new : improved dictionary builder "cover" (experimental), by Nick Terrell, based on prior work by Giuseppe Ottaviano. +cli : new : advanced commands for detailed parameters, by Przemyslaw Skibinski +cli : fix zstdless on Mac OS-X, by Andrew Janke +cli : fix #232 "compress non-files" +dictBuilder : improved dictionary generation quality, thanks to Nick Terrell +API : new : lib/compress/ZSTDMT_compress.h multithreading API (experimental) +API : new : ZSTD_create?Dict_byReference(), requested by Bartosz Taudul +API : new : ZDICT_finalizeDictionary() +API : fix : ZSTD_initCStream_usingCDict() properly writes dictID into frame header, by Gregory Szorc (#511) +API : fix : all symbols properly exposed in libzstd, by Nick Terrell +build : support for Solaris target, by Przemyslaw Skibinski +doc : clarified specification, by Sean Purcell + +v1.1.2 (Dec 15, 2016) +API : streaming : decompression : changed : automatic implicit reset when chain-decoding new frames without init +API : experimental : added : dictID retrieval functions, and ZSTD_initCStream_srcSize() +API : zbuff : changed : prototypes now generate deprecation warnings +lib : improved : faster decompression speed at ultra compression settings and 32-bits mode +lib : changed : only public ZSTD_ symbols are now exposed +lib : changed : reduced usage of stack memory +lib : fixed : several corner case bugs, by Nick Terrell +cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski +cli : new : preserve file attributes +cli : new : added zstdless and zstdgrep tools +cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) +cli : fixed : zstdcat +zlib_wrapper : added support for gz* functions, by Przemyslaw Skibinski +install : better compatibility with FreeBSD, by Dimitry Andric +source tree : changed : zbuff source files moved to lib/deprecated + +v1.1.1 (Nov 2, 2016) +New : command -M#, --memory=, --memlimit=, --memlimit-decompress= to limit allowed memory consumption +New : doc/zstd_manual.html, by Przemyslaw Skibinski +Improved : slightly better compression ratio at --ultra levels (>= 20) +Improved : better memory usage when using streaming compression API, thanks to @Rogier-5 report +Added : API : ZSTD_initCStream_usingCDict(), ZSTD_initDStream_usingDDict() (experimental section) +Added : example/multiple_streaming_compression.c +Changed : zstd_errors.h is now installed within /include (and replaces errors_public.h) +Updated man page +Fixed : zstd-small, zstd-compress and zstd-decompress compilation targets + +v1.1.0 (Sep 28, 2016) +New : contrib/pzstd, parallel version of zstd, by Nick Terrell +added : NetBSD install target (#338) +Improved : speed for batches of small files +Improved : speed of zlib wrapper, by Przemyslaw Skibinski +Changed : libzstd on Windows supports legacy formats, by Christophe Chevalier +Fixed : CLI -d output to stdout by default when input is stdin (#322) +Fixed : CLI correctly detects console on Mac OS-X +Fixed : CLI supports recursive mode `-r` on Mac OS-X +Fixed : Legacy decoders use unified error codes, reported by benrg (#341), fixed by Przemyslaw Skibinski +Fixed : compatibility with OpenBSD, reported by Juan Francisco Cantero Hurtado (#319) +Fixed : compatibility with Hurd, by Przemyslaw Skibinski (#365) +Fixed : zstd-pgo, reported by octoploid (#329) + +v1.0.0 (Sep 1, 2016) +Change Licensing, all project is now BSD, Copyright Facebook +Small decompression speed improvement +API : Streaming API supports legacy format +API : ZDICT_getDictID(), ZSTD_sizeof_{CCtx, DCtx, CStream, DStream}(), ZSTD_setDStreamParameter() +CLI supports legacy formats v0.4+ +Fixed : compression fails on certain huge files, reported by Jesse McGrew +Enhanced documentation, by Przemyslaw Skibinski + +v0.8.1 (Aug 18, 2016) +New streaming API +Changed : --ultra now enables levels beyond 19 +Changed : -i# now selects benchmark time in second +Fixed : ZSTD_compress* can now compress > 4 GB in a single pass, reported by Nick Terrell +Fixed : speed regression on specific patterns (#272) +Fixed : support for Z_SYNC_FLUSH, by Dmitry Krot (#291) +Fixed : ICC compilation, by Przemyslaw Skibinski + +v0.8.0 (Aug 2, 2016) +Improved : better speed on clang and gcc -O2, thanks to Eric Biggers +New : Build on FreeBSD and DragonFly, thanks to JrMarino +Changed : modified API : ZSTD_compressEnd() +Fixed : legacy mode with ZSTD_HEAPMODE=0, by Christopher Bergqvist +Fixed : premature end of frame when zero-sized raw block, reported by Eric Biggers +Fixed : large dictionaries (> 384 KB), reported by Ilona Papava +Fixed : checksum correctly checked in single-pass mode +Fixed : combined --test amd --rm, reported by Andreas M. Nilsson +Modified : minor compression level adaptations +Updated : compression format specification to v0.2.0 +changed : zstd.h moved to /lib directory + +v0.7.5 (Aug 1, 2016) +Transition version, supporting decoding of v0.8.x + +v0.7.4 (Jul 17, 2016) +Added : homebrew for Mac, by Daniel Cade +Added : more examples +Fixed : segfault when using small dictionaries, reported by Felix Handte +Modified : default compression level for CLI is now 3 +Updated : specification, to v0.1.1 + +v0.7.3 (Jul 9, 2016) +New : compression format specification +New : `--` separator, stating that all following arguments are file names. Suggested by Chip Turner. +New : `ZSTD_getDecompressedSize()` +New : OpenBSD target, by Juan Francisco Cantero Hurtado +New : `examples` directory +fixed : dictBuilder using HC levels, reported by Bartosz Taudul +fixed : legacy support from ZSTD_decompress_usingDDict(), reported by Felix Handte +fixed : multi-blocks decoding with intermediate uncompressed blocks, reported by Greg Slazinski +modified : removed "mem.h" and "error_public.h" dependencies from "zstd.h" (experimental section) +modified : legacy functions no longer need magic number + +v0.7.2 (Jul 4, 2016) +fixed : ZSTD_decompressBlock() using multiple consecutive blocks. Reported by Greg Slazinski. +fixed : potential segfault on very large files (many gigabytes). Reported by Chip Turner. +fixed : CLI displays system error message when destination file cannot be created (#231). Reported by Chip Turner. + +v0.7.1 (Jun 23, 2016) +fixed : ZBUFF_compressEnd() called multiple times with too small `dst` buffer, reported by Christophe Chevalier +fixed : dictBuilder fails if first sample is too small, reported by РуÑлан Ковалёв +fixed : corruption issue, reported by cj +modified : checksum enabled by default in command line mode + +v0.7.0 (Jun 17, 2016) +New : Support for directory compression, using `-r`, thanks to Przemyslaw Skibinski +New : Command `--rm`, to remove source file after successful de/compression +New : Visual build scripts, by Christophe Chevalier +New : Support for Sparse File-systems (do not use space for zero-filled sectors) +New : Frame checksum support +New : Support pass-through mode (when using `-df`) +API : more efficient Dictionary API : `ZSTD_compress_usingCDict()`, `ZSTD_decompress_usingDDict()` +API : create dictionary files from custom content, by Giuseppe Ottaviano +API : support for custom malloc/free functions +New : controllable Dictionary ID +New : Support for skippable frames + +v0.6.1 (May 13, 2016) +New : zlib wrapper API, thanks to Przemyslaw Skibinski +New : Ability to compile compressor / decompressor separately +Changed : new lib directory structure +Fixed : Legacy codec v0.5 compatible with dictionary decompression +Fixed : Decoder corruption error (#173) +Fixed : null-string roundtrip (#176) +New : benchmark mode can select directory as input +Experimental : midipix support, VMS support + +v0.6.0 (Apr 13, 2016) +Stronger high compression modes, thanks to Przemyslaw Skibinski +API : ZSTD_getFrameParams() provides size of decompressed content +New : highest compression modes require `--ultra` command to fully unleash their capacity +Fixed : zstd cli return error code > 0 and removes dst file artifact when decompression fails, thanks to Chip Turner + +v0.5.1 (Feb 18, 2016) +New : Optimal parsing => Very high compression modes, thanks to Przemyslaw Skibinski +Changed : Dictionary builder integrated into libzstd and zstd cli +Changed (!) : zstd cli now uses "multiple input files" as default mode. See `zstd -h`. +Fix : high compression modes for big-endian platforms +New : zstd cli : `-t` | `--test` command + +v0.5.0 (Feb 5, 2016) +New : dictionary builder utility +Changed : streaming & dictionary API +Improved : better compression of small data + +v0.4.7 (Jan 22, 2016) +Improved : small compression speed improvement in HC mode +Changed : `zstd_decompress.c` has ZSTD_LEGACY_SUPPORT to 0 by default +fix : bt search bug + +v0.4.6 (Jan 13, 2016) +fix : fast compression mode on Windows +New : cmake configuration file, thanks to Artyom Dymchenko +Improved : high compression mode on repetitive data +New : block-level API +New : ZSTD_duplicateCCtx() + +v0.4.5 (Dec 18, 2015) +new : -m/--multiple : compress/decompress multiple files + +v0.4.4 (Dec 14, 2015) +Fixed : high compression modes for Windows 32 bits +new : external dictionary API extended to buffered mode and accessible through command line +new : windows DLL project, thanks to Christophe Chevalier + +v0.4.3 (Dec 7, 2015) +new : external dictionary API +new : zstd-frugal + +v0.4.2 (Dec 2, 2015) +Generic minor improvements for small blocks +Fixed : big-endian compatibility, by Peter Harris (#85) + +v0.4.1 (Dec 1, 2015) +Fixed : ZSTD_LEGACY_SUPPORT=0 build mode (reported by Luben) +removed `zstd.c` + +v0.4.0 (Nov 29, 2015) +Command line utility compatible with high compression levels +Removed zstdhc => merged into zstd +Added : ZBUFF API (see zstd_buffered.h) +Rolling buffer support + +v0.3.6 (Nov 10, 2015) +small blocks params + +v0.3.5 (Nov 9, 2015) +minor generic compression improvements + +v0.3.4 (Nov 6, 2015) +Faster fast cLevels + +v0.3.3 (Nov 5, 2015) +Small compression ratio improvement + +v0.3.2 (Nov 2, 2015) +Fixed Visual Studio + +v0.3.1 (Nov 2, 2015) +Small compression ratio improvement + +v0.3 (Oct 30, 2015) +HC mode : compression levels 2-26 + +v0.2.2 (Oct 28, 2015) +Fix : Visual Studio 2013 & 2015 release compilation, by Christophe Chevalier + +v0.2.1 (Oct 24, 2015) +Fix : Read errors, advanced fuzzer tests, by Hanno Böck + +v0.2.0 (Oct 22, 2015) +**Breaking format change** +Faster decompression speed +Can still decode v0.1 format + +v0.1.3 (Oct 15, 2015) +fix uninitialization warning, reported by Evan Nemerson + +v0.1.2 (Sep 11, 2015) +frame concatenation support + +v0.1.1 (Aug 27, 2015) +fix compression bug +detects write-flush errors + +v0.1.0 (Aug 25, 2015) +first release diff --git a/cpp/third_party/zstd-1.5.7/CODE_OF_CONDUCT.md b/cpp/third_party/zstd-1.5.7/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..0f7ad8bfc --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/CODE_OF_CONDUCT.md @@ -0,0 +1,5 @@ +# Code of Conduct + +Facebook has adopted a Code of Conduct that we expect project participants to adhere to. +Please read the [full text](https://code.fb.com/codeofconduct/) +so that you can understand what actions will and will not be tolerated. diff --git a/cpp/third_party/zstd-1.5.7/CONTRIBUTING.md b/cpp/third_party/zstd-1.5.7/CONTRIBUTING.md new file mode 100644 index 000000000..57be94bf5 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/CONTRIBUTING.md @@ -0,0 +1,489 @@ +# Contributing to Zstandard +We want to make contributing to this project as easy and transparent as +possible. + +## Our Development Process +New versions are being developed in the "dev" branch, +or in their own feature branch. +When they are deemed ready for a release, they are merged into "release". + +As a consequence, all contributions must stage first through "dev" +or their own feature branch. + +## Pull Requests +We actively welcome your pull requests. + +1. Fork the repo and create your branch from `dev`. +2. If you've added code that should be tested, add tests. +3. If you've changed APIs, update the documentation. +4. Ensure the test suite passes. +5. Make sure your code lints. +6. If you haven't already, complete the Contributor License Agreement ("CLA"). + +## Contributor License Agreement ("CLA") +In order to accept your pull request, we need you to submit a CLA. You only need +to do this once to work on any of Facebook's open source projects. + +Complete your CLA here: + +## Workflow +Zstd uses a branch-based workflow for making changes to the codebase. Typically, zstd +will use a new branch per sizable topic. For smaller changes, it is okay to lump multiple +related changes into a branch. + +Our contribution process works in three main stages: +1. Local development + * Update: + * Checkout your fork of zstd if you have not already + ``` + git checkout https://github.com//zstd + cd zstd + ``` + * Update your local dev branch + ``` + git pull https://github.com/facebook/zstd dev + git push origin dev + ``` + * Topic and development: + * Make a new branch on your fork about the topic you're developing for + ``` + # branch names should be concise but sufficiently informative + git checkout -b + git push origin + ``` + * Make commits and push + ``` + # make some changes = + git add -u && git commit -m + git push origin + ``` + * Note: run local tests to ensure that your changes didn't break existing functionality + * Quick check + ``` + make check + ``` + * Longer check + ``` + make test + ``` +2. Code Review and CI tests + * Ensure CI tests pass: + * Before sharing anything to the community, create a pull request in your own fork against the dev branch + and make sure that all GitHub Actions CI tests pass. See the Continuous Integration section below for more information. + * Ensure that static analysis passes on your development machine. See the Static Analysis section + below to see how to do this. + * Create a pull request: + * When you are ready to share you changes to the community, create a pull request from your branch + to facebook:dev. You can do this very easily by clicking 'Create Pull Request' on your fork's home + page. + * From there, select the branch where you made changes as your source branch and facebook:dev + as the destination. + * Examine the diff presented between the two branches to make sure there is nothing unexpected. + * Write a good pull request description: + * While there is no strict template that our contributors follow, we would like them to + sufficiently summarize and motivate the changes they are proposing. We recommend all pull requests, + at least indirectly, address the following points. + * Is this pull request important and why? + * Is it addressing an issue? If so, what issue? (provide links for convenience please) + * Is this a new feature? If so, why is it useful and/or necessary? + * Are there background references and documents that reviewers should be aware of to properly assess this change? + * Note: make sure to point out any design and architectural decisions that you made and the rationale behind them. + * Note: if you have been working with a specific user and would like them to review your work, make sure you mention them using (@) + * Submit the pull request and iterate with feedback. +3. Merge and Release + * Getting approval: + * You will have to iterate on your changes with feedback from other collaborators to reach a point + where your pull request can be safely merged. + * To avoid too many comments on style and convention, make sure that you have a + look at our style section below before creating a pull request. + * Eventually, someone from the zstd team will approve your pull request and not long after merge it into + the dev branch. + * Housekeeping: + * Most PRs are linked with one or more Github issues. If this is the case for your PR, make sure + the corresponding issue is mentioned. If your change 'fixes' or completely addresses the + issue at hand, then please indicate this by requesting that an issue be closed by commenting. + * Just because your changes have been merged does not mean the topic or larger issue is complete. Remember + that the change must make it to an official zstd release for it to be meaningful. We recommend + that contributors track the activity on their pull request and corresponding issue(s) page(s) until + their change makes it to the next release of zstd. Users will often discover bugs in your code or + suggest ways to refine and improve your initial changes even after the pull request is merged. + +## Static Analysis +Static analysis is a process for examining the correctness or validity of a program without actually +executing it. It usually helps us find many simple bugs. Zstd uses clang's `scan-build` tool for +static analysis. You can install it by following the instructions for your OS on https://clang-analyzer.llvm.org/scan-build. + +Once installed, you can ensure that our static analysis tests pass on your local development machine +by running: +``` +make staticAnalyze +``` + +In general, you can use `scan-build` to static analyze any build script. For example, to static analyze +just `contrib/largeNbDicts` and nothing else, you can run: + +``` +scan-build make -C contrib/largeNbDicts largeNbDicts +``` + +### Pitfalls of static analysis +`scan-build` is part of our regular CI suite. Other static analyzers are not. + +It can be useful to look at additional static analyzers once in a while (and we do), but it's not a good idea to multiply the nb of analyzers run continuously at each commit and PR. The reasons are : + +- Static analyzers are full of false positive. The signal to noise ratio is actually pretty low. +- A good CI policy is "zero-warning tolerance". That means that all issues must be solved, including false positives. This quickly becomes a tedious workload. +- Multiple static analyzers will feature multiple kind of false positives, sometimes applying to the same code but in different ways leading to : + + tortuous code, trying to please multiple constraints, hurting readability and therefore maintenance. Sometimes, such complexity introduce other more subtle bugs, that are just out of scope of the analyzers. + + sometimes, these constraints are mutually exclusive : if one try to solve one, the other static analyzer will complain, they can't be both happy at the same time. +- As if that was not enough, the list of false positives change with each version. It's hard enough to follow one static analyzer, but multiple ones with their own update agenda, this quickly becomes a massive velocity reducer. + +This is different from running a static analyzer once in a while, looking at the output, and __cherry picking__ a few warnings that seem helpful, either because they detected a genuine risk of bug, or because it helps expressing the code in a way which is more readable or more difficult to misuse. These kinds of reports can be useful, and are accepted. + +## Continuous Integration +CI tests run every time a pull request (PR) is created or updated. The exact tests +that get run will depend on the destination branch you specify. Some tests take +longer to run than others. Currently, our CI is set up to run a short +series of tests when creating a PR to the dev branch and a longer series of tests +when creating a PR to the release branch. You can look in the configuration files +of the respective CI platform for more information on what gets run when. + +Most people will just want to create a PR with the destination set to their local dev +branch of zstd. You can then find the status of the tests on the PR's page. You can also +re-run tests and cancel running tests from the PR page or from the respective CI's dashboard. + +Almost all of zstd's CI runs on GitHub Actions (configured at `.github/workflows`), which will automatically run on PRs to your +own fork. A small number of tests run on other services (e.g. Travis CI, Circle CI, Appveyor). +These require work to set up on your local fork, and (at least for Travis CI) cost money. +Therefore, if the PR on your local fork passes GitHub Actions, feel free to submit a PR +against the main repo. + +### Third-party CI +A small number of tests cannot run on GitHub Actions, or have yet to be migrated. +For these, we use a variety of third-party services (listed below). It is not necessary to set +these up on your fork in order to contribute to zstd; however, we do link to instructions for those +who want earlier signal. + +| Service | Purpose | Setup Links | Config Path | +|-----------|------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------| +| Travis CI | Used for testing on non-x86 architectures such as PowerPC | https://docs.travis-ci.com/user/tutorial/#to-get-started-with-travis-ci-using-github
https://github.com/marketplace/travis-ci | `.travis.yml` | +| AppVeyor | Used for some Windows testing (e.g. cygwin, mingw) | https://www.appveyor.com/blog/2018/10/02/github-apps-integration/
https://github.com/marketplace/appveyor | `appveyor.yml` | +| Cirrus CI | Used for testing on FreeBSD | https://github.com/marketplace/cirrus-ci/ | `.cirrus.yml` | +| Circle CI | Historically was used to provide faster signal,
but we may be able to migrate these to Github Actions | https://circleci.com/docs/2.0/getting-started/#setting-up-circleci
https://youtu.be/Js3hMUsSZ2c
https://circleci.com/docs/2.0/enable-checks/ | `.circleci/config.yml` | + +Note: the instructions linked above mostly cover how to set up a repository with CI from scratch. +The general idea should be the same for setting up CI on your fork of zstd, but you may have to +follow slightly different steps. In particular, please ignore any instructions related to setting up +config files (since zstd already has configs for each of these services). + +## Performance +Performance is extremely important for zstd and we only merge pull requests whose performance +landscape and corresponding trade-offs have been adequately analyzed, reproduced, and presented. +This high bar for performance means that every PR which has the potential to +impact performance takes a very long time for us to properly review. That being said, we +always welcome contributions to improve performance (or worsen performance for the trade-off of +something else). Please keep the following in mind before submitting a performance related PR: + +1. Zstd isn't as old as gzip but it has been around for time now and its evolution is +very well documented via past Github issues and pull requests. It may be the case that your +particular performance optimization has already been considered in the past. Please take some +time to search through old issues and pull requests using keywords specific to your +would-be PR. Of course, just because a topic has already been discussed (and perhaps rejected +on some grounds) in the past, doesn't mean it isn't worth bringing up again. But even in that case, +it will be helpful for you to have context from that topic's history before contributing. +2. The distinction between noise and actual performance gains can unfortunately be very subtle +especially when microbenchmarking extremely small wins or losses. The only remedy to getting +something subtle merged is extensive benchmarking. You will be doing us a great favor if you +take the time to run extensive, long-duration, and potentially cross-(os, platform, process, etc) +benchmarks on your end before submitting a PR. Of course, you will not be able to benchmark +your changes on every single processor and os out there (and neither will we) but do that best +you can:) We've added some things to think about when benchmarking below in the Benchmarking +Performance section which might be helpful for you. +3. Optimizing performance for a certain OS, processor vendor, compiler, or network system is a perfectly +legitimate thing to do as long as it does not harm the overall performance health of Zstd. +This is a hard balance to strike but please keep in mind other aspects of Zstd when +submitting changes that are clang-specific, windows-specific, etc. + +## Benchmarking Performance +Performance microbenchmarking is a tricky subject but also essential for Zstd. We value empirical +testing over theoretical speculation. This guide it not perfect but for most scenarios, it +is a good place to start. + +### Stability +Unfortunately, the most important aspect in being able to benchmark reliably is to have a stable +benchmarking machine. A virtual machine, a machine with shared resources, or your laptop +will typically not be stable enough to obtain reliable benchmark results. If you can get your +hands on a desktop, this is usually a better scenario. + +Of course, benchmarking can be done on non-hyper-stable machines as well. You will just have to +do a little more work to ensure that you are in fact measuring the changes you've made and not +noise. Here are some things you can do to make your benchmarks more stable: + +1. The most simple thing you can do to drastically improve the stability of your benchmark is +to run it multiple times and then aggregate the results of those runs. As a general rule of +thumb, the smaller the change you are trying to measure, the more samples of benchmark runs +you will have to aggregate over to get reliable results. Here are some additional things to keep in +mind when running multiple trials: + * How you aggregate your samples are important. You might be tempted to use the mean of your + results. While this is certainly going to be a more stable number than a raw single sample + benchmark number, you might have more luck by taking the median. The mean is not robust to + outliers whereas the median is. Better still, you could simply take the fastest speed your + benchmark achieved on each run since that is likely the fastest your process will be + capable of running your code. In our experience, this (aggregating by just taking the sample + with the fastest running time) has been the most stable approach. + * The more samples you have, the more stable your benchmarks should be. You can verify + your improved stability by looking at the size of your confidence intervals as you + increase your sample count. These should get smaller and smaller. Eventually hopefully + smaller than the performance win you are expecting. + * Most processors will take some time to get `hot` when running anything. The observations + you collect during that time period will very different from the true performance number. Having + a very large number of sample will help alleviate this problem slightly but you can also + address is directly by simply not including the first `n` iterations of your benchmark in + your aggregations. You can determine `n` by simply looking at the results from each iteration + and then hand picking a good threshold after which the variance in results seems to stabilize. +2. You cannot really get reliable benchmarks if your host machine is simultaneously running +another cpu/memory-intensive application in the background. If you are running benchmarks on your +personal laptop for instance, you should close all applications (including your code editor and +browser) before running your benchmarks. You might also have invisible background applications +running. You can see what these are by looking at either Activity Monitor on Mac or Task Manager +on Windows. You will get more stable benchmark results of you end those processes as well. + * If you have multiple cores, you can even run your benchmark on a reserved core to prevent + pollution from other OS and user processes. There are a number of ways to do this depending + on your OS: + * On linux boxes, you have use https://github.com/lpechacek/cpuset. + * On Windows, you can "Set Processor Affinity" using https://www.thewindowsclub.com/processor-affinity-windows + * On Mac, you can try to use their dedicated affinity API https://developer.apple.com/library/archive/releasenotes/Performance/RN-AffinityAPI/#//apple_ref/doc/uid/TP40006635-CH1-DontLinkElementID_2 +3. To benchmark, you will likely end up writing a separate c/c++ program that will link libzstd. +Dynamically linking your library will introduce some added variation (not a large amount but +definitely some). Statically linking libzstd will be more stable. Static libraries should +be enabled by default when building zstd. +4. Use a profiler with a good high resolution timer. See the section below on profiling for +details on this. +5. Disable frequency scaling, turbo boost and address space randomization (this will vary by OS) +6. Try to avoid storage. On some systems you can use tmpfs. Putting the program, inputs and outputs on +tmpfs avoids touching a real storage system, which can have a pretty big variability. + +Also check our LLVM's guide on benchmarking here: https://llvm.org/docs/Benchmarking.html + +### Zstd benchmark +The fastest signal you can get regarding your performance changes is via the in-build zstd cli +bench option. You can run Zstd as you typically would for your scenario using some set of options +and then additionally also specify the `-b#` option. Doing this will run our benchmarking pipeline +for that options you have just provided. If you want to look at the internals of how this +benchmarking script works, you can check out programs/benchzstd.c + +For example: say you have made a change that you believe improves the speed of zstd level 1. The +very first thing you should use to assess whether you actually achieved any sort of improvement +is `zstd -b`. You might try to do something like this. Note: you can use the `-i` option to +specify a running time for your benchmark in seconds (default is 3 seconds). +Usually, the longer the running time, the more stable your results will be. + +``` +$ git checkout +$ make && cp zstd zstd-old +$ git checkout +$ make && cp zstd zstd-new +$ zstd-old -i5 -b1 + 1 : 8990 -> 3992 (2.252), 302.6 MB/s , 626.4 MB/s +$ zstd-new -i5 -b1 + 1 : 8990 -> 3992 (2.252), 302.8 MB/s , 628.4 MB/s +``` + +Unless your performance win is large enough to be visible despite the intrinsic noise +on your computer, benchzstd alone will likely not be enough to validate the impact of your +changes. For example, the results of the example above indicate that effectively nothing +changed but there could be a small <3% improvement that the noise on the host machine +obscured. So unless you see a large performance win (10-15% consistently) using just +this method of evaluation will not be sufficient. + +### Profiling +There are a number of great profilers out there. We're going to briefly mention how you can +profile your code using `instruments` on mac, `perf` on linux and `visual studio profiler` +on Windows. + +Say you have an idea for a change that you think will provide some good performance gains +for level 1 compression on Zstd. Typically this means, you have identified a section of +code that you think can be made to run faster. + +The first thing you will want to do is make sure that the piece of code is actually taking up +a notable amount of time to run. It is usually not worth optimizing something which accounts for less than +0.0001% of the total running time. Luckily, there are tools to help with this. +Profilers will let you see how much time your code spends inside a particular function. +If your target code snippet is only part of a function, it might be worth trying to +isolate that snippet by moving it to its own function (this is usually not necessary but +might be). + +Most profilers (including the profilers discussed below) will generate a call graph of +functions for you. Your goal will be to find your function of interest in this call graph +and then inspect the time spent inside of it. You might also want to look at the annotated +assembly which most profilers will provide you with. + +#### Instruments +We will once again consider the scenario where you think you've identified a piece of code +whose performance can be improved upon. Follow these steps to profile your code using +Instruments. + +1. Open Instruments +2. Select `Time Profiler` from the list of standard templates +3. Close all other applications except for your instruments window and your terminal +4. Run your benchmarking script from your terminal window + * You will want a benchmark that runs for at least a few seconds (5 seconds will + usually be long enough). This way the profiler will have something to work with + and you will have ample time to attach your profiler to this process:) + * I will just use benchzstd as my benchmarmking script for this example: +``` +$ zstd -b1 -i5 # this will run for 5 seconds +``` +5. Once you run your benchmarking script, switch back over to instruments and attach your +process to the time profiler. You can do this by: + * Clicking on the `All Processes` drop down in the top left of the toolbar. + * Selecting your process from the dropdown. In my case, it is just going to be labeled + `zstd` + * Hitting the bright red record circle button on the top left of the toolbar +6. You profiler will now start collecting metrics from your benchmarking script. Once +you think you have collected enough samples (usually this is the case after 3 seconds of +recording), stop your profiler. +7. Make sure that in toolbar of the bottom window, `profile` is selected. +8. You should be able to see your call graph. + * If you don't see the call graph or an incomplete call graph, make sure you have compiled + zstd and your benchmarking script using debug flags. On mac and linux, this just means + you will have to supply the `-g` flag alone with your build script. You might also + have to provide the `-fno-omit-frame-pointer` flag +9. Dig down the graph to find your function call and then inspect it by double clicking +the list item. You will be able to see the annotated source code and the assembly side by +side. + +#### Perf + +This wiki has a pretty detailed tutorial on getting started working with perf so we'll +leave you to check that out of you're getting started: + +https://perf.wiki.kernel.org/index.php/Tutorial + +Some general notes on perf: +* Use `perf stat -r # ` to quickly get some relevant timing and +counter statistics. Perf uses a high resolution timer and this is likely one +of the first things your team will run when assessing your PR. +* Perf has a long list of hardware counters that can be viewed with `perf --list`. +When measuring optimizations, something worth trying is to make sure the hardware +counters you expect to be impacted by your change are in fact being so. For example, +if you expect the L1 cache misses to decrease with your change, you can look at the +counter `L1-dcache-load-misses` +* Perf hardware counters will not work on a virtual machine. + +#### Visual Studio + +TODO + +## Issues +We use GitHub issues to track public bugs. Please ensure your description is +clear and has sufficient instructions to be able to reproduce the issue. + +Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe +disclosure of security bugs. In those cases, please go through the process +outlined on that page and do not file a public issue. + +## Coding Style +It's a pretty long topic, which is difficult to summarize in a single paragraph. +As a rule of thumbs, try to imitate the coding style of +similar lines of codes around your contribution. +The following is a non-exhaustive list of rules employed in zstd code base: + +### C90 +This code base is following strict C90 standard, +with 2 extensions : 64-bit `long long` types, and variadic macros. +This rule is applied strictly to code within `lib/` and `programs/`. +Sub-project in `contrib/` are allowed to use other conventions. + +### C++ direct compatibility : symbol mangling +All public symbol declarations must be wrapped in `extern “C†{ … }`, +so that this project can be compiled as C++98 code, +and linked into C++ applications. + +### Minimal Frugal +This design requirement is fundamental to preserve the portability of the code base. +#### Dependencies +- Reduce dependencies to the minimum possible level. + Any dependency should be considered “bad†by default, + and only tolerated because it provides a service in a better way than can be achieved locally. + The only external dependencies this repository tolerates are + standard C libraries, and in rare cases, system level headers. +- Within `lib/`, this policy is even more drastic. + The only external dependencies allowed are ``, ``, ``, + and even then, not directly. + In particular, no function shall ever allocate on heap directly, + and must use instead `ZSTD_malloc()` and equivalent. + Other accepted non-symbol headers are `` and ``. +- Within the project, there is a strict hierarchy of dependencies that must be respected. + `programs/` is allowed to depend on `lib/`, but only its public API. + Within `lib/`, `lib/common` doesn't depend on any other directory. + `lib/compress` and `lib/decompress` shall not depend on each other. + `lib/dictBuilder` can depend on `lib/common` and `lib/compress`, but not `lib/decompress`. +#### Resources +- Functions in `lib/` must use very little stack space, + several dozens of bytes max. + Everything larger must use the heap allocator, + or require a scratch buffer to be emplaced manually. + +### Naming +* All public symbols are prefixed with `ZSTD_` + + private symbols, with a scope limited to their own unit, are free of this restriction. + However, since `libzstd` source code can be amalgamated, + each symbol name must attempt to be (and remain) unique. + Avoid too generic names that could become ground for future collisions. + This generally implies usage of some form of prefix. +* For symbols (functions and variables), naming convention is `PREFIX_camelCase`. + + In some advanced cases, one can also find : + - `PREFIX_prefix2_camelCase` + - `PREFIX_camelCase_extendedQualifier` +* Multi-words names generally consist of an action followed by object: + - for example : `ZSTD_createCCtx()` +* Prefer positive actions + - `goBackward` rather than `notGoForward` +* Type names (`struct`, etc.) follow similar convention, + except that they are allowed and even invited to start by an Uppercase letter. + Example : `ZSTD_CCtx`, `ZSTD_CDict` +* Macro names are all Capital letters. + The same composition rules (`PREFIX_NAME_QUALIFIER`) apply. +* File names are all lowercase letters. + The convention is `snake_case`. + File names **must** be unique across the entire code base, + even when they stand in clearly separated directories. + +### Qualifiers +* This code base is `const` friendly, if not `const` fanatical. + Any variable that can be `const` (aka. read-only) **must** be `const`. + Any pointer which content will not be modified must be `const`. + This property is then controlled at compiler level. + `const` variables are an important signal to readers that this variable isn't modified. + Conversely, non-const variables are a signal to readers to watch out for modifications later on in the function. +* If a function must be inlined, mention it explicitly, + using project's own portable macros, such as `FORCE_INLINE_ATTR`, + defined in `lib/common/compiler.h`. + +### Debugging +* **Assertions** are welcome, and should be used very liberally, + to control any condition the code expects for its correct execution. + These assertion checks will be run in debug builds, and disabled in production. +* For traces, this project provides its own debug macros, + in particular `DEBUGLOG(level, ...)`, defined in `lib/common/debug.h`. + +### Code documentation +* Avoid code documentation that merely repeats what the code is already stating. + Whenever applicable, prefer employing the code as the primary way to convey explanations. + Example 1 : `int nbTokens = n;` instead of `int i = n; /* i is a nb of tokens *./`. + Example 2 : `assert(size > 0);` instead of `/* here, size should be positive */`. +* At declaration level, the documentation explains how to use the function or variable + and when applicable why it's needed, of the scenarios where it can be useful. +* At implementation level, the documentation explains the general outline of the algorithm employed, + and when applicable why this specific choice was preferred. + +### General layout +* 4 spaces for indentation rather than tabs +* Code documentation shall directly precede function declaration or implementation +* Function implementations and its code documentation should be preceded and followed by an empty line + + +## License +By contributing to Zstandard, you agree that your contributions will be licensed +under both the [LICENSE](LICENSE) file and the [COPYING](COPYING) file in the root directory of this source tree. diff --git a/cpp/third_party/zstd-1.5.7/COPYING b/cpp/third_party/zstd-1.5.7/COPYING new file mode 100644 index 000000000..ecbc05937 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 + + 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) + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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 Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/cpp/third_party/zstd-1.5.7/LICENSE b/cpp/third_party/zstd-1.5.7/LICENSE new file mode 100644 index 000000000..75800288c --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/LICENSE @@ -0,0 +1,30 @@ +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. 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. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, 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 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 HOLDER 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. diff --git a/cpp/third_party/zstd-1.5.7/Makefile b/cpp/third_party/zstd-1.5.7/Makefile new file mode 100644 index 000000000..e8e6bcffe --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/Makefile @@ -0,0 +1,471 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ + +# verbose mode (print commands) on V=1 or VERBOSE=1 +Q = $(if $(filter 1,$(V) $(VERBOSE)),,@) + +PRGDIR = programs +ZSTDDIR = lib +BUILDIR = build +ZWRAPDIR = zlibWrapper +TESTDIR = tests +FUZZDIR = $(TESTDIR)/fuzz + +# Define nul output +VOID = /dev/null + +# When cross-compiling from linux to windows, you might +# need to specify this as "Windows." Fedora build fails +# without it. +# +# Note: mingw-w64 build from linux to windows does not +# fail on other tested distros (ubuntu, debian) even +# without manually specifying the TARGET_SYSTEM. +TARGET_SYSTEM ?= $(OS) +CP ?= cp + +ifneq (,$(filter Windows%,$(TARGET_SYSTEM))) + EXT =.exe +else + EXT = +endif + +## default: Build lib-release and zstd-release +.PHONY: default +default: lib-release zstd-release + +.PHONY: all +all: allmost examples manual contrib + +.PHONY: allmost +allmost: allzstd zlibwrapper + +# skip zwrapper, can't build that on alternate architectures without the proper zlib installed +.PHONY: allzstd +allzstd: lib + $(Q)$(MAKE) -C $(PRGDIR) all + $(Q)$(MAKE) -C $(TESTDIR) all + +.PHONY: all32 +all32: + $(MAKE) -C $(PRGDIR) zstd32 + $(MAKE) -C $(TESTDIR) all32 + +.PHONY: lib lib-release lib-mt lib-nomt +lib lib-release lib-mt lib-nomt: + $(Q)$(MAKE) -C $(ZSTDDIR) $@ + +.PHONY: zstd zstd-release +zstd zstd-release: + $(Q)$(MAKE) -C $(PRGDIR) $@ + $(Q)ln -sf $(PRGDIR)/zstd$(EXT) zstd$(EXT) + +.PHONY: zstdmt +zstdmt: + $(Q)$(MAKE) -C $(PRGDIR) $@ + $(Q)$(CP) $(PRGDIR)/zstd$(EXT) ./zstdmt$(EXT) + +.PHONY: zlibwrapper +zlibwrapper: lib + $(MAKE) -C $(ZWRAPDIR) all + +## test: run long-duration tests +.PHONY: test +DEBUGLEVEL ?= 1 +test: MOREFLAGS += -g -Werror +test: + DEBUGLEVEL=$(DEBUGLEVEL) MOREFLAGS="$(MOREFLAGS)" $(MAKE) -j -C $(PRGDIR) allVariants + $(MAKE) -C $(TESTDIR) $@ + ZSTD=../../programs/zstd $(MAKE) -C doc/educational_decoder $@ + +## check: run basic tests for `zstd` cli +.PHONY: check +check: + $(Q)$(MAKE) -C $(TESTDIR) $@ + +.PHONY: automated_benchmarking +automated_benchmarking: + $(MAKE) -C $(TESTDIR) $@ + +.PHONY: benchmarking +benchmarking: automated_benchmarking + +## examples: build all examples in `examples/` directory +.PHONY: examples +examples: lib + $(MAKE) -C examples all + +## manual: generate API documentation in html format +.PHONY: manual +manual: + $(MAKE) -C contrib/gen_html $@ + +## man: generate man page +.PHONY: man +man: + $(MAKE) -C programs $@ + +## contrib: build all supported projects in `/contrib` directory +.PHONY: contrib +contrib: lib + $(MAKE) -C contrib/pzstd all + $(MAKE) -C contrib/seekable_format/examples all + $(MAKE) -C contrib/seekable_format/tests test + $(MAKE) -C contrib/largeNbDicts all + $(MAKE) -C contrib/externalSequenceProducer all + cd build/single_file_libs/ ; ./build_decoder_test.sh + cd build/single_file_libs/ ; ./build_library_test.sh + +.PHONY: cleanTabs +cleanTabs: + cd contrib; ./cleanTabs + +.PHONY: clean +clean: + $(Q)$(MAKE) -C $(ZSTDDIR) $@ > $(VOID) + $(Q)$(MAKE) -C $(PRGDIR) $@ > $(VOID) + $(Q)$(MAKE) -C $(TESTDIR) $@ > $(VOID) + $(Q)$(MAKE) -C $(ZWRAPDIR) $@ > $(VOID) + $(Q)$(MAKE) -C examples/ $@ > $(VOID) + $(Q)$(MAKE) -C contrib/gen_html $@ > $(VOID) + $(Q)$(MAKE) -C contrib/pzstd $@ > $(VOID) + $(Q)$(MAKE) -C contrib/seekable_format/examples $@ > $(VOID) + $(Q)$(MAKE) -C contrib/seekable_format/tests $@ > $(VOID) + $(Q)$(MAKE) -C contrib/largeNbDicts $@ > $(VOID) + $(Q)$(MAKE) -C contrib/externalSequenceProducer $@ > $(VOID) + $(Q)$(RM) zstd$(EXT) zstdmt$(EXT) tmp* + $(Q)$(RM) -r lz4 cmakebuild mesonbuild install + @echo Cleaning completed + +#------------------------------------------------------------------------------ +# make install is validated only for Linux, macOS, Hurd and some BSD targets +#------------------------------------------------------------------------------ +ifneq (,$(filter Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT% CYGWIN_NT% Haiku AIX,$(shell sh -c 'MSYSTEM="MSYS" uname') )) + +HOST_OS = POSIX + +MKDIR ?= mkdir -p + +HAVE_COLORNEVER = $(shell echo a | egrep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) +EGREP_OPTIONS ?= +ifeq ($(HAVE_COLORNEVER), 1) +EGREP_OPTIONS += --color=never +endif +EGREP = egrep $(EGREP_OPTIONS) + +# Print a two column output of targets and their description. To add a target description, put a +# comment in the Makefile with the format "## : ". For example: +# +## list: Print all targets and their descriptions (if provided) +.PHONY: list +list: + $(Q)TARGETS=$$($(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null \ + | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' \ + | $(EGREP) -v -e '^[^[:alnum:]]' | sort); \ + { \ + printf "Target Name\tDescription\n"; \ + printf "%0.s-" {1..16}; printf "\t"; printf "%0.s-" {1..40}; printf "\n"; \ + for target in $$TARGETS; do \ + line=$$($(EGREP) "^##[[:space:]]+$$target:" $(lastword $(MAKEFILE_LIST))); \ + description=$$(echo $$line | awk '{i=index($$0,":"); print substr($$0,i+1)}' | xargs); \ + printf "$$target\t$$description\n"; \ + done \ + } | column -t -s $$'\t' + +.PHONY: install armtest usan asan uasan msan asan32 +install: + $(Q)$(MAKE) -C $(ZSTDDIR) $@ + $(Q)$(MAKE) -C $(PRGDIR) $@ + +.PHONY: uninstall +uninstall: + $(Q)$(MAKE) -C $(ZSTDDIR) $@ + $(Q)$(MAKE) -C $(PRGDIR) $@ + +.PHONY: travis-install +travis-install: + $(MAKE) install PREFIX=~/install_test_dir + +.PHONY: clangbuild-darwin-fat +clangbuild-darwin-fat: clean + clang -v + CXX=clang++ CC=clang CFLAGS+="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation -arch arm64" $(MAKE) zstd-release + mv programs/zstd programs/zstd_arm64 + CXX=clang++ CC=clang CFLAGS+="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation -arch x86_64" $(MAKE) zstd-release + mv programs/zstd programs/zstd_x64 + lipo -create programs/zstd_x64 programs/zstd_arm64 -output programs/zstd + +.PHONY: gcc5build gcc6build gcc7build clangbuild m32build armbuild aarch64build ppcbuild ppc64build +gcc5build: clean + gcc-5 -v + CC=gcc-5 $(MAKE) all MOREFLAGS="-Werror $(MOREFLAGS)" + +gcc6build: clean + gcc-6 -v + CC=gcc-6 $(MAKE) all MOREFLAGS="-Werror $(MOREFLAGS)" + +gcc7build: clean + gcc-7 -v + CC=gcc-7 $(MAKE) all MOREFLAGS="-Werror $(MOREFLAGS)" + +clangbuild: clean + clang -v + CXX=clang++ CC=clang CFLAGS="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation" $(MAKE) all + +m32build: clean + gcc -v + $(MAKE) all32 + +armbuild: clean + CC=arm-linux-gnueabi-gcc CFLAGS="-Werror" $(MAKE) allzstd + +aarch64build: clean + CC=aarch64-linux-gnu-gcc CFLAGS="-Werror -O0" $(MAKE) allzstd + +ppcbuild: clean + CC=powerpc-linux-gnu-gcc CFLAGS="-m32 -Wno-attributes -Werror" $(MAKE) -j allzstd + +ppc64build: clean + CC=powerpc-linux-gnu-gcc CFLAGS="-m64 -Werror" $(MAKE) -j allzstd + +.PHONY: armfuzz aarch64fuzz ppcfuzz ppc64fuzz +armfuzz: clean + CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static MOREFLAGS="-static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -C $(TESTDIR) fuzztest + +aarch64fuzz: clean + ld -v + CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static MOREFLAGS="-static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -C $(TESTDIR) fuzztest + +ppcfuzz: clean + CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static MOREFLAGS="-static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -C $(TESTDIR) fuzztest + +ppc64fuzz: clean + CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static MOREFLAGS="-m64 -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -C $(TESTDIR) fuzztest + +.PHONY: cxxtest gcc5test gcc6test armtest aarch64test ppctest ppc64test +cxxtest: CXXFLAGS += -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror +cxxtest: clean + $(MAKE) -C $(PRGDIR) all CC="$(CXX) -Wno-deprecated" CFLAGS="$(CXXFLAGS)" # adding -Wno-deprecated to avoid clang++ warning on dealing with C files directly + +gcc5test: clean + gcc-5 -v + $(MAKE) all CC=gcc-5 MOREFLAGS="-Werror $(MOREFLAGS)" + +gcc6test: clean + gcc-6 -v + $(MAKE) all CC=gcc-6 MOREFLAGS="-Werror $(MOREFLAGS)" + +armtest: clean + $(MAKE) -C $(TESTDIR) datagen # use native, faster + $(MAKE) -C $(TESTDIR) test CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" + +aarch64test: + $(MAKE) -C $(TESTDIR) datagen # use native, faster + $(MAKE) -C $(TESTDIR) test CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" + +ppctest: clean + $(MAKE) -C $(TESTDIR) datagen # use native, faster + $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" + +ppc64test: clean + $(MAKE) -C $(TESTDIR) datagen # use native, faster + $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" + +.PHONY: arm-ppc-compilation +arm-ppc-compilation: + $(MAKE) -C $(PRGDIR) clean zstd CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static $(MOREFLAGS)" + $(MAKE) -C $(PRGDIR) clean zstd CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static $(MOREFLAGS)" + $(MAKE) -C $(PRGDIR) clean zstd CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static $(MOREFLAGS)" + $(MAKE) -C $(PRGDIR) clean zstd CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static $(MOREFLAGS)" + +regressiontest: + $(MAKE) -C $(FUZZDIR) regressiontest + +uasanregressiontest: + $(MAKE) -C $(FUZZDIR) regressiontest CC=clang CXX=clang++ CFLAGS="-O3 -fsanitize=address,undefined -Werror" CXXFLAGS="-O3 -fsanitize=address,undefined -Werror" + +msanregressiontest: + $(MAKE) -C $(FUZZDIR) regressiontest CC=clang CXX=clang++ CFLAGS="-O3 -fsanitize=memory -Werror" CXXFLAGS="-O3 -fsanitize=memory -Werror" + +update_regressionResults : REGRESS_RESULTS_DIR := /tmp/regress_results_dir/ +update_regressionResults: + $(MAKE) -j -C programs zstd + $(MAKE) -j -C tests/regression test + $(RM) -r $(REGRESS_RESULTS_DIR) + $(MKDIR) $(REGRESS_RESULTS_DIR) + ./tests/regression/test \ + --cache tests/regression/cache \ + --output $(REGRESS_RESULTS_DIR)/results.csv \ + --zstd programs/zstd + echo "Showing results differences" + ! diff tests/regression/results.csv $(REGRESS_RESULTS_DIR)/results.csv + echo "Updating results.csv" + $(CP) $(REGRESS_RESULTS_DIR)/results.csv tests/regression/results.csv + + +# run UBsan with -fsanitize-recover=pointer-overflow +# this only works with recent compilers such as gcc 8+ +usan: clean + $(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=undefined -Werror $(MOREFLAGS)" + +asan: clean + $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -Werror $(MOREFLAGS)" + +asan-%: clean + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address -Werror $(MOREFLAGS)" $(MAKE) -C $(TESTDIR) $* + +msan: clean + $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer -Werror $(MOREFLAGS)" HAVE_LZMA=0 # datagen.c fails this test for no obvious reason + +msan-%: + $(MAKE) clean + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer -Werror $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -j -C $(TESTDIR) HAVE_LZMA=0 $* + +asan32: clean + $(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address $(MOREFLAGS)" + +uasan: clean + $(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address,undefined -Werror $(MOREFLAGS)" + +uasan-%: clean + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address,undefined -Werror $(MOREFLAGS)" $(MAKE) -C $(TESTDIR) $* + +tsan-%: clean + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread -Werror $(MOREFLAGS)" $(MAKE) -C $(TESTDIR) $* FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" + +.PHONY: apt-install +apt-install: + # TODO: uncomment once issue 3011 is resolved and remove hack from Github Actions .yml + # sudo apt-get update + sudo apt-get -yq --no-install-suggests --no-install-recommends --force-yes install $(APT_PACKAGES) + +.PHONY: apt-add-repo +apt-add-repo: + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-get update -y -qq + +.PHONY: ppcinstall arminstall valgrindinstall libc6install gcc6install gcc7install gcc8install gpp6install clang38install lz4install +ppcinstall: + APT_PACKAGES="qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu" $(MAKE) apt-install + +arminstall: + APT_PACKAGES="qemu-system-arm qemu-user-static gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross" $(MAKE) apt-install + +valgrindinstall: + APT_PACKAGES="valgrind" $(MAKE) apt-install + +libc6install: + APT_PACKAGES="libc6-dev-i386 gcc-multilib" $(MAKE) apt-install + +gcc6install: apt-add-repo + APT_PACKAGES="libc6-dev-i386 gcc-multilib gcc-6 gcc-6-multilib" $(MAKE) apt-install + +gcc7install: apt-add-repo + APT_PACKAGES="libc6-dev-i386 gcc-multilib gcc-7 gcc-7-multilib" $(MAKE) apt-install + +gcc8install: apt-add-repo + APT_PACKAGES="libc6-dev-i386 gcc-multilib gcc-8 gcc-8-multilib" $(MAKE) apt-install + +gpp6install: apt-add-repo + APT_PACKAGES="libc6-dev-i386 g++-multilib gcc-6 g++-6 g++-6-multilib" $(MAKE) apt-install + +clang38install: + APT_PACKAGES="clang-3.8" $(MAKE) apt-install + +# Ubuntu 14.04 ships a too-old lz4 +lz4install: + [ -e lz4 ] || git clone https://github.com/lz4/lz4 && sudo $(MAKE) -C lz4 install + +endif + + +ifneq (,$(filter MSYS%,$(shell sh -c 'MSYSTEM="MSYS" uname') )) +HOST_OS = MSYS +endif + +#------------------------------------------------------------------------ +# target specific tests +#------------------------------------------------------------------------ +ifneq (,$(filter MSYS POSIX,$(HOST_OS))) + +CMAKE ?= cmake +CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON + +ifneq (,$(filter MSYS%,$(shell sh -c 'MSYSTEM="MSYS" uname'))) +CMAKE_PARAMS = -G"MSYS Makefiles" -DZSTD_MULTITHREAD_SUPPORT:BOOL=OFF -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON +endif + +.PHONY: cmakebuild +cmakebuild: + $(CMAKE) --version + $(RM) -r cmakebuild install + $(MKDIR) cmakebuild install + cd cmakebuild; $(CMAKE) -Wdev -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-Werror -O0" -DCMAKE_INSTALL_PREFIX=install $(CMAKE_PARAMS) ../build/cmake + $(CMAKE) --build cmakebuild --target install -- -j V=1 + cd cmakebuild; ctest -V -L Medium + +MESON ?= meson +NINJA ?= ninja + +.PHONY: mesonbuild +mesonbuild: + $(MESON) setup \ + --buildtype=debugoptimized \ + -Db_lundef=false \ + -Dauto_features=enabled \ + -Dbin_programs=true \ + -Dbin_tests=true \ + -Dbin_contrib=true \ + -Ddefault_library=both \ + build/meson mesonbuild + $(NINJA) -C mesonbuild/ + $(MESON) test -C mesonbuild/ --print-errorlogs + $(MESON) install -C mesonbuild --destdir staging/ + +.PHONY: c89build gnu90build c99build gnu99build c11build bmix64build bmix32build bmi32build staticAnalyze +c89build: clean + $(CC) -v + CFLAGS="-std=c89 -Werror -Wno-attributes -Wpedantic -Wno-long-long -Wno-variadic-macros -O0" $(MAKE) lib zstd + +gnu90build: clean + $(CC) -v + CFLAGS="-std=gnu90 -Werror -O0" $(MAKE) allmost + +c99build: clean + $(CC) -v + CFLAGS="-std=c99 -Werror -O0" $(MAKE) allmost + +gnu99build: clean + $(CC) -v + CFLAGS="-std=gnu99 -Werror -O0" $(MAKE) allmost + +c11build: clean + $(CC) -v + CFLAGS="-std=c11 -Werror -O0" $(MAKE) allmost + +bmix64build: clean + $(CC) -v + CFLAGS="-O3 -mbmi -Werror" $(MAKE) -C $(TESTDIR) test + +bmix32build: clean + $(CC) -v + CFLAGS="-O3 -mbmi -mx32 -Werror" $(MAKE) -C $(TESTDIR) test + +bmi32build: clean + $(CC) -v + CFLAGS="-O3 -mbmi -m32 -Werror" $(MAKE) -C $(TESTDIR) test + +# static analyzer test uses clang's scan-build +# does not analyze zlibWrapper, due to detected issues in zlib source code +staticAnalyze: SCANBUILD ?= scan-build +staticAnalyze: + $(CC) -v + CC=$(CC) CPPFLAGS=-g $(SCANBUILD) --status-bugs -v $(MAKE) zstd +endif diff --git a/cpp/third_party/zstd-1.5.7/Package.swift b/cpp/third_party/zstd-1.5.7/Package.swift new file mode 100644 index 000000000..97f2c6a52 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/Package.swift @@ -0,0 +1,36 @@ +// swift-tools-version:5.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "zstd", + platforms: [ + .macOS(.v10_10), .iOS(.v9), .tvOS(.v9) + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "libzstd", + targets: [ "libzstd" ]) + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .target( + name: "libzstd", + path: "lib", + sources: [ "common", "compress", "decompress", "dictBuilder" ], + publicHeadersPath: ".", + cSettings: [ + .headerSearchPath(".") + ]) + ], + swiftLanguageVersions: [.v5], + cLanguageStandard: .gnu11, + cxxLanguageStandard: .gnucxx14 +) diff --git a/cpp/third_party/zstd-1.5.7/README.md b/cpp/third_party/zstd-1.5.7/README.md new file mode 100644 index 000000000..d91ef5df1 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/README.md @@ -0,0 +1,237 @@ +

Zstandard

+ +__Zstandard__, or `zstd` as short version, is a fast lossless compression algorithm, +targeting real-time compression scenarios at zlib-level and better compression ratios. +It's backed by a very fast entropy stage, provided by [Huff0 and FSE library](https://github.com/Cyan4973/FiniteStateEntropy). + +Zstandard's format is stable and documented in [RFC8878](https://datatracker.ietf.org/doc/html/rfc8878). Multiple independent implementations are already available. +This repository represents the reference implementation, provided as an open-source dual [BSD](LICENSE) OR [GPLv2](COPYING) licensed **C** library, +and a command line utility producing and decoding `.zst`, `.gz`, `.xz` and `.lz4` files. +Should your project require another programming language, +a list of known ports and bindings is provided on [Zstandard homepage](https://facebook.github.io/zstd/#other-languages). + +**Development branch status:** + +[![Build Status][travisDevBadge]][travisLink] +[![Build status][CircleDevBadge]][CircleLink] +[![Build status][CirrusDevBadge]][CirrusLink] +[![Fuzzing Status][OSSFuzzBadge]][OSSFuzzLink] + +[travisDevBadge]: https://api.travis-ci.com/facebook/zstd.svg?branch=dev "Continuous Integration test suite" +[travisLink]: https://travis-ci.com/facebook/zstd +[CircleDevBadge]: https://circleci.com/gh/facebook/zstd/tree/dev.svg?style=shield "Short test suite" +[CircleLink]: https://circleci.com/gh/facebook/zstd +[CirrusDevBadge]: https://api.cirrus-ci.com/github/facebook/zstd.svg?branch=dev +[CirrusLink]: https://cirrus-ci.com/github/facebook/zstd +[OSSFuzzBadge]: https://oss-fuzz-build-logs.storage.googleapis.com/badges/zstd.svg +[OSSFuzzLink]: https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:zstd + +## Benchmarks + +For reference, several fast compression algorithms were tested and compared +on a desktop featuring a Core i7-9700K CPU @ 4.9GHz +and running Ubuntu 20.04 (`Linux ubu20 5.15.0-101-generic`), +using [lzbench], an open-source in-memory benchmark by @inikep +compiled with [gcc] 9.4.0, +on the [Silesia compression corpus]. + +[lzbench]: https://github.com/inikep/lzbench +[Silesia compression corpus]: https://sun.aei.polsl.pl//~sdeor/index.php?page=silesia +[gcc]: https://gcc.gnu.org/ + +| Compressor name | Ratio | Compression| Decompress.| +| --------------- | ------| -----------| ---------- | +| **zstd 1.5.6 -1** | 2.887 | 510 MB/s | 1580 MB/s | +| [zlib] 1.2.11 -1 | 2.743 | 95 MB/s | 400 MB/s | +| brotli 1.0.9 -0 | 2.702 | 395 MB/s | 430 MB/s | +| **zstd 1.5.6 --fast=1** | 2.437 | 545 MB/s | 1890 MB/s | +| **zstd 1.5.6 --fast=3** | 2.239 | 650 MB/s | 2000 MB/s | +| quicklz 1.5.0 -1 | 2.238 | 525 MB/s | 750 MB/s | +| lzo1x 2.10 -1 | 2.106 | 650 MB/s | 825 MB/s | +| [lz4] 1.9.4 | 2.101 | 700 MB/s | 4000 MB/s | +| lzf 3.6 -1 | 2.077 | 420 MB/s | 830 MB/s | +| snappy 1.1.9 | 2.073 | 530 MB/s | 1660 MB/s | + +[zlib]: https://www.zlib.net/ +[lz4]: https://lz4.github.io/lz4/ + +The negative compression levels, specified with `--fast=#`, +offer faster compression and decompression speed +at the cost of compression ratio. + +Zstd can also offer stronger compression ratios at the cost of compression speed. +Speed vs Compression trade-off is configurable by small increments. +Decompression speed is preserved and remains roughly the same at all settings, +a property shared by most LZ compression algorithms, such as [zlib] or lzma. + +The following tests were run +on a server running Linux Debian (`Linux version 4.14.0-3-amd64`) +with a Core i7-6700K CPU @ 4.0GHz, +using [lzbench], an open-source in-memory benchmark by @inikep +compiled with [gcc] 7.3.0, +on the [Silesia compression corpus]. + +Compression Speed vs Ratio | Decompression Speed +---------------------------|-------------------- +![Compression Speed vs Ratio](doc/images/CSpeed2.png "Compression Speed vs Ratio") | ![Decompression Speed](doc/images/DSpeed3.png "Decompression Speed") + +A few other algorithms can produce higher compression ratios at slower speeds, falling outside of the graph. +For a larger picture including slow modes, [click on this link](doc/images/DCspeed5.png). + + +## The case for Small Data compression + +Previous charts provide results applicable to typical file and stream scenarios (several MB). Small data comes with different perspectives. + +The smaller the amount of data to compress, the more difficult it is to compress. This problem is common to all compression algorithms, and reason is, compression algorithms learn from past data how to compress future data. But at the beginning of a new data set, there is no "past" to build upon. + +To solve this situation, Zstd offers a __training mode__, which can be used to tune the algorithm for a selected type of data. +Training Zstandard is achieved by providing it with a few samples (one file per sample). The result of this training is stored in a file called "dictionary", which must be loaded before compression and decompression. +Using this dictionary, the compression ratio achievable on small data improves dramatically. + +The following example uses the `github-users` [sample set](https://github.com/facebook/zstd/releases/tag/v1.1.3), created from [github public API](https://developer.github.com/v3/users/#get-all-users). +It consists of roughly 10K records weighing about 1KB each. + +Compression Ratio | Compression Speed | Decompression Speed +------------------|-------------------|-------------------- +![Compression Ratio](doc/images/dict-cr.png "Compression Ratio") | ![Compression Speed](doc/images/dict-cs.png "Compression Speed") | ![Decompression Speed](doc/images/dict-ds.png "Decompression Speed") + + +These compression gains are achieved while simultaneously providing _faster_ compression and decompression speeds. + +Training works if there is some correlation in a family of small data samples. The more data-specific a dictionary is, the more efficient it is (there is no _universal dictionary_). +Hence, deploying one dictionary per type of data will provide the greatest benefits. +Dictionary gains are mostly effective in the first few KB. Then, the compression algorithm will gradually use previously decoded content to better compress the rest of the file. + +### Dictionary compression How To: + +1. Create the dictionary + + `zstd --train FullPathToTrainingSet/* -o dictionaryName` + +2. Compress with dictionary + + `zstd -D dictionaryName FILE` + +3. Decompress with dictionary + + `zstd -D dictionaryName --decompress FILE.zst` + + +## Build instructions + +`make` is the officially maintained build system of this project. +All other build systems are "compatible" and 3rd-party maintained, +they may feature small differences in advanced options. +When your system allows it, prefer using `make` to build `zstd` and `libzstd`. + +### Makefile + +If your system is compatible with standard `make` (or `gmake`), +invoking `make` in root directory will generate `zstd` cli in root directory. +It will also create `libzstd` into `lib/`. + +Other available options include: +- `make install` : create and install zstd cli, library and man pages +- `make check` : create and run `zstd`, test its behavior on local platform + +The `Makefile` follows the [GNU Standard Makefile conventions](https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html), +allowing staged install, standard flags, directory variables and command variables. + +For advanced use cases, specialized compilation flags which control binary generation +are documented in [`lib/README.md`](lib/README.md#modular-build) for the `libzstd` library +and in [`programs/README.md`](programs/README.md#compilation-variables) for the `zstd` CLI. + +### cmake + +A `cmake` project generator is provided within `build/cmake`. +It can generate Makefiles or other build scripts +to create `zstd` binary, and `libzstd` dynamic and static libraries. + +By default, `CMAKE_BUILD_TYPE` is set to `Release`. + +#### Support for Fat (Universal2) Output + +`zstd` can be built and installed with support for both Apple Silicon (M1/M2) as well as Intel by using CMake's Universal2 support. +To perform a Fat/Universal2 build and install use the following commands: + +```bash +cmake -B build-cmake-debug -S build/cmake -G Ninja -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h;arm64" +cd build-cmake-debug +ninja +sudo ninja install +``` + +### Meson + +A Meson project is provided within [`build/meson`](build/meson). Follow +build instructions in that directory. + +You can also take a look at [`.travis.yml`](.travis.yml) file for an +example about how Meson is used to build this project. + +Note that default build type is **release**. + +### VCPKG +You can build and install zstd [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: + + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + ./bootstrap-vcpkg.sh + ./vcpkg integrate install + ./vcpkg install zstd + +The zstd port in vcpkg is kept up to date by Microsoft team members and community contributors. +If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. + +### Conan + +You can install pre-built binaries for zstd or build it from source using [Conan](https://conan.io/). Use the following command: + +```bash +conan install --requires="zstd/[*]" --build=missing +``` + +The zstd Conan recipe is kept up to date by Conan maintainers and community contributors. +If the version is out of date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the ConanCenterIndex repository. + +### Visual Studio (Windows) + +Going into `build` directory, you will find additional possibilities: +- Projects for Visual Studio 2005, 2008 and 2010. + + VS2010 project is compatible with VS2012, VS2013, VS2015 and VS2017. +- Automated build scripts for Visual compiler by [@KrzysFR](https://github.com/KrzysFR), in `build/VS_scripts`, + which will build `zstd` cli and `libzstd` library without any need to open Visual Studio solution. + +### Buck + +You can build the zstd binary via buck by executing: `buck build programs:zstd` from the root of the repo. +The output binary will be in `buck-out/gen/programs/`. + +### Bazel + +You easily can integrate zstd into your Bazel project by using the module hosted on the [Bazel Central Repository](https://registry.bazel.build/modules/zstd). + +## Testing + +You can run quick local smoke tests by running `make check`. +If you can't use `make`, execute the `playTest.sh` script from the `src/tests` directory. +Two env variables `$ZSTD_BIN` and `$DATAGEN_BIN` are needed for the test script to locate the `zstd` and `datagen` binary. +For information on CI testing, please refer to `TESTING.md`. + +## Status + +Zstandard is currently deployed within Facebook and many other large cloud infrastructures. +It is run continuously to compress large amounts of data in multiple formats and use cases. +Zstandard is considered safe for production environments. + +## License + +Zstandard is dual-licensed under [BSD](LICENSE) OR [GPLv2](COPYING). + +## Contributing + +The `dev` branch is the one where all contributions are merged before reaching `release`. +If you plan to propose a patch, please commit into the `dev` branch, or its own feature branch. +Direct commit to `release` are not permitted. +For more information, please read [CONTRIBUTING](CONTRIBUTING.md). diff --git a/cpp/third_party/zstd-1.5.7/SECURITY.md b/cpp/third_party/zstd-1.5.7/SECURITY.md new file mode 100644 index 000000000..a5f9a7e1f --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/SECURITY.md @@ -0,0 +1,15 @@ +# Reporting and Fixing Security Issues + +Please do not open GitHub issues or pull requests - this makes the problem immediately visible to everyone, including malicious actors. Security issues in this open source project can be safely reported via the Meta Bug Bounty program: + +https://www.facebook.com/whitehat + +Meta's security team will triage your report and determine whether or not is it eligible for a bounty under our program. + +# Receiving Vulnerability Notifications + +In the case that a significant security vulnerability is reported to us or discovered by us---without being publicly known---we will, at our discretion, notify high-profile, high-exposure users of Zstandard ahead of our public disclosure of the issue and associated fix. + +If you believe your project would benefit from inclusion in this list, please reach out to one of the maintainers. + + diff --git a/cpp/third_party/zstd-1.5.7/TESTING.md b/cpp/third_party/zstd-1.5.7/TESTING.md new file mode 100644 index 000000000..df842cc94 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/TESTING.md @@ -0,0 +1,43 @@ +Testing +======= + +Zstandard CI testing is split up into three sections: +short, medium, and long tests. + +Short Tests +----------- +Short tests run on CircleCI for new commits on every branch and pull request. +They consist of the following tests: +- Compilation on all supported targets (x86, x86_64, ARM, AArch64, PowerPC, and PowerPC64) +- Compilation on various versions of gcc, clang, and g++ +- `tests/playTests.sh` on x86_64, without the tests on long data (CLI tests) +- Small tests (`tests/legacy.c`, `tests/longmatch.c`) on x64_64 + +Medium Tests +------------ +Medium tests run on every commit and pull request to `dev` branch, on TravisCI. +They consist of the following tests: +- The following tests run with UBsan and Asan on x86_64 and x86, as well as with + Msan on x86_64 + - `tests/playTests.sh --test-large-data` + - Fuzzer tests: `tests/fuzzer.c`, `tests/zstreamtest.c`, and `tests/decodecorpus.c` +- `tests/zstreamtest.c` under Tsan (streaming mode, including multithreaded mode) +- Valgrind Test (`make -C tests test-valgrind`) (testing CLI and fuzzer under `valgrind`) +- Fuzzer tests (see above) on ARM, AArch64, PowerPC, and PowerPC64 + +Long Tests +---------- +Long tests run on all commits to `release` branch, +and once a day on the current version of `dev` branch, +on TravisCI. +They consist of the following tests: +- Entire test suite (including fuzzers and some other specialized tests) on: + - x86_64 and x86 with UBsan and Asan + - x86_64 with Msan + - ARM, AArch64, PowerPC, and PowerPC64 +- Streaming mode fuzzer with Tsan (for the `zstdmt` testing) +- ZlibWrapper tests, including under valgrind +- Versions test (ensuring `zstd` can decode files from all previous versions) +- `pzstd` with asan and tsan, as well as in 32-bits mode +- Testing `zstd` with legacy mode off +- Entire test suite and make install on macOS diff --git a/cpp/third_party/zstd-1.5.7/contrib/VS2005/README.md b/cpp/third_party/zstd-1.5.7/contrib/VS2005/README.md new file mode 100644 index 000000000..ec1ef68a0 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/VS2005/README.md @@ -0,0 +1,3 @@ +## Project Support Notice + +The VS2005 Project directory has been moved to the contrib directory in order to indicate that it will no longer be supported. diff --git a/cpp/third_party/zstd-1.5.7/contrib/VS2005/fullbench/fullbench.vcproj b/cpp/third_party/zstd-1.5.7/contrib/VS2005/fullbench/fullbench.vcproj new file mode 100644 index 000000000..98f859376 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/VS2005/fullbench/fullbench.vcproj @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/third_party/zstd-1.5.7/contrib/VS2005/fuzzer/fuzzer.vcproj b/cpp/third_party/zstd-1.5.7/contrib/VS2005/fuzzer/fuzzer.vcproj new file mode 100644 index 000000000..d182535fe --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/VS2005/fuzzer/fuzzer.vcproj @@ -0,0 +1,488 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstd.sln b/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstd.sln new file mode 100644 index 000000000..0c31ae126 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstd.sln @@ -0,0 +1,55 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstd", "zstd\zstd.vcproj", "{1A2AB08E-5CE7-4C5B-BE55-458157C14051}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcproj", "{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcproj", "{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstdlib", "zstdlib\zstdlib.vcproj", "{99DE2A79-7298-4004-A0ED-030D7A3796CA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|Win32.ActiveCfg = Debug|Win32 + {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|Win32.Build.0 = Debug|Win32 + {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|x64.ActiveCfg = Debug|x64 + {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|x64.Build.0 = Debug|x64 + {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|Win32.ActiveCfg = Release|Win32 + {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|Win32.Build.0 = Release|Win32 + {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|x64.ActiveCfg = Release|x64 + {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|x64.Build.0 = Release|x64 + {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|Win32.Build.0 = Debug|Win32 + {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|x64.ActiveCfg = Debug|x64 + {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|x64.Build.0 = Debug|x64 + {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|Win32.ActiveCfg = Release|Win32 + {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|Win32.Build.0 = Release|Win32 + {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|x64.ActiveCfg = Release|x64 + {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|x64.Build.0 = Release|x64 + {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|Win32.ActiveCfg = Debug|Win32 + {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|Win32.Build.0 = Debug|Win32 + {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|x64.ActiveCfg = Debug|x64 + {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|x64.Build.0 = Debug|x64 + {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|Win32.ActiveCfg = Release|Win32 + {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|Win32.Build.0 = Release|Win32 + {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|x64.ActiveCfg = Release|x64 + {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|x64.Build.0 = Release|x64 + {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|Win32.ActiveCfg = Debug|Win32 + {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|Win32.Build.0 = Debug|Win32 + {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|x64.ActiveCfg = Debug|x64 + {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|x64.Build.0 = Debug|x64 + {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|Win32.ActiveCfg = Release|Win32 + {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|Win32.Build.0 = Release|Win32 + {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|x64.ActiveCfg = Release|x64 + {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstd/zstd.vcproj b/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstd/zstd.vcproj new file mode 100644 index 000000000..e37ebee39 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstd/zstd.vcproj @@ -0,0 +1,552 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstdlib/zstdlib.vcproj b/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstdlib/zstdlib.vcproj new file mode 100644 index 000000000..67ddd2dba --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/VS2005/zstdlib/zstdlib.vcproj @@ -0,0 +1,546 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp/third_party/zstd-1.5.7/contrib/cleanTabs b/cpp/third_party/zstd-1.5.7/contrib/cleanTabs new file mode 100755 index 000000000..215913a90 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/cleanTabs @@ -0,0 +1,2 @@ +#!/bin/sh +sed -i '' $'s/\t/ /g' ../lib/**/*.{h,c} ../programs/*.{h,c} ../tests/*.c ./**/*.{h,cpp} ../examples/*.c ../zlibWrapper/*.{h,c} diff --git a/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/.gitignore b/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/.gitignore new file mode 100644 index 000000000..a8e92b69b --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/.gitignore @@ -0,0 +1 @@ +check_flipped_bits diff --git a/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/Makefile b/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/Makefile new file mode 100644 index 000000000..ecc9e6395 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/Makefile @@ -0,0 +1,35 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +.PHONY: all +all: check_flipped_bits + +ZSTDLIBDIR ?= ../../lib + +CFLAGS ?= -O3 +CFLAGS += -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZSTDLIBDIR)/compress \ + -I$(ZSTDLIBDIR)/decompress +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ + -Wstrict-prototypes -Wundef \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls -Wmissing-prototypes +CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) + +.PHONY: $(ZSTDLIBDIR)/libzstd.a +$(ZSTDLIBDIR)/libzstd.a: + $(MAKE) -C $(ZSTDLIBDIR) libzstd.a + +check_flipped_bits: check_flipped_bits.c $(ZSTDLIBDIR)/libzstd.a + $(CC) $(FLAGS) $< -o $@$(EXT) $(ZSTDLIBDIR)/libzstd.a + +.PHONY: clean +clean: + rm -f check_flipped_bits diff --git a/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/check_flipped_bits.c b/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/check_flipped_bits.c new file mode 100644 index 000000000..09ddd4674 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/diagnose_corruption/check_flipped_bits.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "zstd_errors.h" + +#include +#include +#include +#include +#include +#include + +typedef struct { + char *input; + size_t input_size; + + char *perturbed; /* same size as input */ + + char *output; + size_t output_size; + + const char *dict_file_name; + const char *dict_file_dir_name; + int32_t dict_id; + char *dict; + size_t dict_size; + ZSTD_DDict* ddict; + + ZSTD_DCtx* dctx; + + int success_count; + int error_counts[ZSTD_error_maxCode]; +} stuff_t; + +static void free_stuff(stuff_t* stuff) { + free(stuff->input); + free(stuff->output); + ZSTD_freeDDict(stuff->ddict); + free(stuff->dict); + ZSTD_freeDCtx(stuff->dctx); +} + +static void usage(void) { + fprintf(stderr, "check_flipped_bits input_filename [-d dict] [-D dict_dir]\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Arguments:\n"); + fprintf(stderr, " -d file: path to a dictionary file to use.\n"); + fprintf(stderr, " -D dir : path to a directory, with files containing dictionaries, of the\n" + " form DICTID.zstd-dict, e.g., 12345.zstd-dict.\n"); + exit(1); +} + +static void print_summary(stuff_t* stuff) { + int error_code; + fprintf(stderr, "%9d successful decompressions\n", stuff->success_count); + for (error_code = 0; error_code < ZSTD_error_maxCode; error_code++) { + int count = stuff->error_counts[error_code]; + if (count) { + fprintf( + stderr, "%9d failed decompressions with message: %s\n", + count, ZSTD_getErrorString(error_code)); + } + } +} + +static char* readFile(const char* filename, size_t* size) { + struct stat statbuf; + int ret; + FILE* f; + char *buf; + size_t bytes_read; + + ret = stat(filename, &statbuf); + if (ret != 0) { + fprintf(stderr, "stat failed: %m\n"); + return NULL; + } + if ((statbuf.st_mode & S_IFREG) != S_IFREG) { + fprintf(stderr, "Input must be regular file\n"); + return NULL; + } + + *size = statbuf.st_size; + + f = fopen(filename, "r"); + if (f == NULL) { + fprintf(stderr, "fopen failed: %m\n"); + return NULL; + } + + buf = malloc(*size); + if (buf == NULL) { + fprintf(stderr, "malloc failed\n"); + fclose(f); + return NULL; + } + + bytes_read = fread(buf, 1, *size, f); + if (bytes_read != *size) { + fprintf(stderr, "failed to read whole file\n"); + fclose(f); + free(buf); + return NULL; + } + + ret = fclose(f); + if (ret != 0) { + fprintf(stderr, "fclose failed: %m\n"); + free(buf); + return NULL; + } + + return buf; +} + +static ZSTD_DDict* readDict(const char* filename, char **buf, size_t* size, int32_t* dict_id) { + ZSTD_DDict* ddict; + *buf = readFile(filename, size); + if (*buf == NULL) { + fprintf(stderr, "Opening dictionary file '%s' failed\n", filename); + return NULL; + } + + ddict = ZSTD_createDDict_advanced(*buf, *size, ZSTD_dlm_byRef, ZSTD_dct_auto, ZSTD_defaultCMem); + if (ddict == NULL) { + fprintf(stderr, "Failed to create ddict.\n"); + return NULL; + } + if (dict_id != NULL) { + *dict_id = ZSTD_getDictID_fromDDict(ddict); + } + return ddict; +} + +static ZSTD_DDict* readDictByID(stuff_t *stuff, int32_t dict_id, char **buf, size_t* size) { + if (stuff->dict_file_dir_name == NULL) { + return NULL; + } else { + size_t dir_name_len = strlen(stuff->dict_file_dir_name); + int dir_needs_separator = 0; + size_t dict_file_name_alloc_size = dir_name_len + 1 /* '/' */ + 10 /* max int32_t len */ + strlen(".zstd-dict") + 1 /* '\0' */; + char *dict_file_name = malloc(dict_file_name_alloc_size); + ZSTD_DDict* ddict; + int32_t read_dict_id; + if (dict_file_name == NULL) { + fprintf(stderr, "malloc failed.\n"); + return 0; + } + + if (dir_name_len > 0 && stuff->dict_file_dir_name[dir_name_len - 1] != '/') { + dir_needs_separator = 1; + } + + snprintf( + dict_file_name, + dict_file_name_alloc_size, + "%s%s%u.zstd-dict", + stuff->dict_file_dir_name, + dir_needs_separator ? "/" : "", + dict_id); + + /* fprintf(stderr, "Loading dict %u from '%s'.\n", dict_id, dict_file_name); */ + + ddict = readDict(dict_file_name, buf, size, &read_dict_id); + if (ddict == NULL) { + fprintf(stderr, "Failed to create ddict from '%s'.\n", dict_file_name); + free(dict_file_name); + return 0; + } + if (read_dict_id != dict_id) { + fprintf(stderr, "Read dictID (%u) does not match expected (%u).\n", read_dict_id, dict_id); + free(dict_file_name); + ZSTD_freeDDict(ddict); + return 0; + } + + free(dict_file_name); + return ddict; + } +} + +static int init_stuff(stuff_t* stuff, int argc, char *argv[]) { + const char* input_filename; + + if (argc < 2) { + usage(); + } + + input_filename = argv[1]; + stuff->input_size = 0; + stuff->input = readFile(input_filename, &stuff->input_size); + if (stuff->input == NULL) { + fprintf(stderr, "Failed to read input file.\n"); + return 0; + } + + stuff->perturbed = malloc(stuff->input_size); + if (stuff->perturbed == NULL) { + fprintf(stderr, "malloc failed.\n"); + return 0; + } + memcpy(stuff->perturbed, stuff->input, stuff->input_size); + + stuff->output_size = ZSTD_DStreamOutSize(); + stuff->output = malloc(stuff->output_size); + if (stuff->output == NULL) { + fprintf(stderr, "malloc failed.\n"); + return 0; + } + + stuff->dict_file_name = NULL; + stuff->dict_file_dir_name = NULL; + stuff->dict_id = 0; + stuff->dict = NULL; + stuff->dict_size = 0; + stuff->ddict = NULL; + + if (argc > 2) { + if (!strcmp(argv[2], "-d")) { + if (argc > 3) { + stuff->dict_file_name = argv[3]; + } else { + usage(); + } + } else + if (!strcmp(argv[2], "-D")) { + if (argc > 3) { + stuff->dict_file_dir_name = argv[3]; + } else { + usage(); + } + } else { + usage(); + } + } + + if (stuff->dict_file_dir_name) { + int32_t dict_id = ZSTD_getDictID_fromFrame(stuff->input, stuff->input_size); + if (dict_id != 0) { + stuff->ddict = readDictByID(stuff, dict_id, &stuff->dict, &stuff->dict_size); + if (stuff->ddict == NULL) { + fprintf(stderr, "Failed to create cached ddict.\n"); + return 0; + } + stuff->dict_id = dict_id; + } + } else + if (stuff->dict_file_name) { + stuff->ddict = readDict(stuff->dict_file_name, &stuff->dict, &stuff->dict_size, &stuff->dict_id); + if (stuff->ddict == NULL) { + fprintf(stderr, "Failed to create ddict from '%s'.\n", stuff->dict_file_name); + return 0; + } + } + + stuff->dctx = ZSTD_createDCtx(); + if (stuff->dctx == NULL) { + return 0; + } + + stuff->success_count = 0; + memset(stuff->error_counts, 0, sizeof(stuff->error_counts)); + + return 1; +} + +static int test_decompress(stuff_t* stuff) { + size_t ret; + ZSTD_inBuffer in = {stuff->perturbed, stuff->input_size, 0}; + ZSTD_outBuffer out = {stuff->output, stuff->output_size, 0}; + ZSTD_DCtx* dctx = stuff->dctx; + int32_t custom_dict_id = ZSTD_getDictID_fromFrame(in.src, in.size); + char *custom_dict = NULL; + size_t custom_dict_size = 0; + ZSTD_DDict* custom_ddict = NULL; + + if (custom_dict_id != 0 && custom_dict_id != stuff->dict_id) { + /* fprintf(stderr, "Instead of dict %u, this perturbed blob wants dict %u.\n", stuff->dict_id, custom_dict_id); */ + custom_ddict = readDictByID(stuff, custom_dict_id, &custom_dict, &custom_dict_size); + } + + ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only); + + if (custom_ddict != NULL) { + ZSTD_DCtx_refDDict(dctx, custom_ddict); + } else { + ZSTD_DCtx_refDDict(dctx, stuff->ddict); + } + + while (in.pos != in.size) { + out.pos = 0; + ret = ZSTD_decompressStream(dctx, &out, &in); + + if (ZSTD_isError(ret)) { + unsigned int code = ZSTD_getErrorCode(ret); + if (code >= ZSTD_error_maxCode) { + fprintf(stderr, "Received unexpected error code!\n"); + exit(1); + } + stuff->error_counts[code]++; + /* + fprintf( + stderr, "Decompression failed: %s\n", ZSTD_getErrorName(ret)); + */ + if (custom_ddict != NULL) { + ZSTD_freeDDict(custom_ddict); + free(custom_dict); + } + return 0; + } + } + + stuff->success_count++; + + if (custom_ddict != NULL) { + ZSTD_freeDDict(custom_ddict); + free(custom_dict); + } + return 1; +} + +static int perturb_bits(stuff_t* stuff) { + size_t pos; + size_t bit; + for (pos = 0; pos < stuff->input_size; pos++) { + unsigned char old_val = stuff->input[pos]; + if (pos % 1000 == 0) { + fprintf(stderr, "Perturbing byte %zu / %zu\n", pos, stuff->input_size); + } + for (bit = 0; bit < 8; bit++) { + unsigned char new_val = old_val ^ (1 << bit); + stuff->perturbed[pos] = new_val; + if (test_decompress(stuff)) { + fprintf( + stderr, + "Flipping byte %zu bit %zu (0x%02x -> 0x%02x) " + "produced a successful decompression!\n", + pos, bit, old_val, new_val); + } + } + stuff->perturbed[pos] = old_val; + } + return 1; +} + +static int perturb_bytes(stuff_t* stuff) { + size_t pos; + size_t new_val; + for (pos = 0; pos < stuff->input_size; pos++) { + unsigned char old_val = stuff->input[pos]; + if (pos % 1000 == 0) { + fprintf(stderr, "Perturbing byte %zu / %zu\n", pos, stuff->input_size); + } + for (new_val = 0; new_val < 256; new_val++) { + stuff->perturbed[pos] = new_val; + if (test_decompress(stuff)) { + fprintf( + stderr, + "Changing byte %zu (0x%02x -> 0x%02x) " + "produced a successful decompression!\n", + pos, old_val, (unsigned char)new_val); + } + } + stuff->perturbed[pos] = old_val; + } + return 1; +} + +int main(int argc, char* argv[]) { + stuff_t stuff; + + if(!init_stuff(&stuff, argc, argv)) { + fprintf(stderr, "Failed to init.\n"); + return 1; + } + + if (test_decompress(&stuff)) { + fprintf(stderr, "Blob already decompresses successfully!\n"); + return 1; + } + + perturb_bits(&stuff); + + perturb_bytes(&stuff); + + print_summary(&stuff); + + free_stuff(&stuff); + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/docker/Dockerfile b/cpp/third_party/zstd-1.5.7/contrib/docker/Dockerfile new file mode 100644 index 000000000..912bf1949 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/docker/Dockerfile @@ -0,0 +1,20 @@ +# Dockerfile +# First image to build the binary +FROM alpine@sha256:69665d02cb32192e52e07644d76bc6f25abeb5410edc1c7a81a10ba3f0efb90a as builder + +RUN apk --no-cache add make gcc libc-dev +COPY . /src +RUN mkdir /pkg && cd /src && make && make DESTDIR=/pkg install + +# Second minimal image to only keep the built binary +FROM alpine@sha256:69665d02cb32192e52e07644d76bc6f25abeb5410edc1c7a81a10ba3f0efb90a + +# Copy the built files +COPY --from=builder /pkg / + +# Copy the license as well +RUN mkdir -p /usr/local/share/licenses/zstd +COPY --from=builder /src/LICENSE /usr/local/share/licences/zstd/ + +# Just run `zstd` if no other command is given +CMD ["/usr/local/bin/zstd"] diff --git a/cpp/third_party/zstd-1.5.7/contrib/docker/README.md b/cpp/third_party/zstd-1.5.7/contrib/docker/README.md new file mode 100644 index 000000000..43f6d7a1a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/docker/README.md @@ -0,0 +1,20 @@ + +## Requirement + +The `Dockerfile` script requires a version of `docker` >= 17.05 + +## Installing docker + +The official docker install docs use a ppa with a modern version available: +https://docs.docker.com/install/linux/docker-ce/ubuntu/ + +## How to run + +`docker build -t zstd .` + +## test + +``` +echo foo | docker run -i --rm zstd | docker run -i --rm zstd zstdcat +foo +``` diff --git a/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/.gitignore b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/.gitignore new file mode 100644 index 000000000..147710aee --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/.gitignore @@ -0,0 +1,2 @@ +# build artifacts +externalSequenceProducer diff --git a/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/Makefile b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/Makefile new file mode 100644 index 000000000..0591ae01b --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/Makefile @@ -0,0 +1,40 @@ +# ################################################################ +# Copyright (c) Yann Collet, Meta Platforms, Inc. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +PROGDIR = ../../programs +LIBDIR = ../../lib + +LIBZSTD = $(LIBDIR)/libzstd.a + +CPPFLAGS+= -I$(LIBDIR) -I$(LIBDIR)/compress -I$(LIBDIR)/common + +CFLAGS ?= -O3 +CFLAGS += -std=gnu99 +DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum \ + -Wstrict-prototypes -Wundef -Wpointer-arith \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls +CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) + +default: externalSequenceProducer + +all: externalSequenceProducer + +externalSequenceProducer: sequence_producer.c main.c $(LIBZSTD) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +.PHONY: $(LIBZSTD) +$(LIBZSTD): + $(MAKE) -C $(LIBDIR) libzstd.a CFLAGS="$(CFLAGS)" + +clean: + $(RM) *.o + $(MAKE) -C $(LIBDIR) clean > /dev/null + $(RM) externalSequenceProducer diff --git a/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/README.md b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/README.md new file mode 100644 index 000000000..c16a17007 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/README.md @@ -0,0 +1,14 @@ +externalSequenceProducer +===================== + +`externalSequenceProducer` is a test tool for the Block-Level Sequence Producer API. +It demonstrates how to use the API to perform a simple round-trip test. + +A sample sequence producer is provided in sequence_producer.c, but the user can swap +this out with a different one if desired. The sample sequence producer implements +LZ parsing with a 1KB hashtable. Dictionary-based parsing is not currently supported. + +Command line : +``` +externalSequenceProducer filename +``` diff --git a/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/main.c b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/main.c new file mode 100644 index 000000000..e67e29538 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/main.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) Yann Collet, Meta Platforms, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include +#include +#include +#include + +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "zstd_errors.h" +#include "sequence_producer.h" // simpleSequenceProducer + +#define CHECK(res) \ +do { \ + if (ZSTD_isError(res)) { \ + printf("ERROR: %s\n", ZSTD_getErrorName(res)); \ + return 1; \ + } \ +} while (0) \ + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: externalSequenceProducer \n"); + return 1; + } + + ZSTD_CCtx* const zc = ZSTD_createCCtx(); + + int simpleSequenceProducerState = 0xdeadbeef; + + // Here is the crucial bit of code! + ZSTD_registerSequenceProducer( + zc, + &simpleSequenceProducerState, + simpleSequenceProducer + ); + + { + size_t const res = ZSTD_CCtx_setParameter(zc, ZSTD_c_enableSeqProducerFallback, 1); + CHECK(res); + } + + FILE *f = fopen(argv[1], "rb"); + assert(f); + { + int const ret = fseek(f, 0, SEEK_END); + assert(ret == 0); + } + size_t const srcSize = ftell(f); + { + int const ret = fseek(f, 0, SEEK_SET); + assert(ret == 0); + } + + char* const src = malloc(srcSize + 1); + assert(src); + { + size_t const ret = fread(src, srcSize, 1, f); + assert(ret == 1); + int const ret2 = fclose(f); + assert(ret2 == 0); + } + + size_t const dstSize = ZSTD_compressBound(srcSize); + char* const dst = malloc(dstSize); + assert(dst); + + size_t const cSize = ZSTD_compress2(zc, dst, dstSize, src, srcSize); + CHECK(cSize); + + char* const val = malloc(srcSize); + assert(val); + + { + size_t const res = ZSTD_decompress(val, srcSize, dst, cSize); + CHECK(res); + } + + if (memcmp(src, val, srcSize) == 0) { + printf("Compression and decompression were successful!\n"); + printf("Original size: %lu\n", srcSize); + printf("Compressed size: %lu\n", cSize); + } else { + printf("ERROR: input and validation buffers don't match!\n"); + for (size_t i = 0; i < srcSize; i++) { + if (src[i] != val[i]) { + printf("First bad index: %zu\n", i); + break; + } + } + return 1; + } + + ZSTD_freeCCtx(zc); + free(src); + free(dst); + free(val); + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/sequence_producer.c b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/sequence_producer.c new file mode 100644 index 000000000..60a2f9572 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/sequence_producer.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) Yann Collet, Meta Platforms, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "sequence_producer.h" + +#define HSIZE 1024 +static U32 const HLOG = 10; +static U32 const MLS = 4; +static U32 const BADIDX = 0xffffffff; + +size_t simpleSequenceProducer( + void* sequenceProducerState, + ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel, + size_t windowSize +) { + const BYTE* const istart = (const BYTE*)src; + const BYTE* const iend = istart + srcSize; + const BYTE* ip = istart; + const BYTE* anchor = istart; + size_t seqCount = 0; + U32 hashTable[HSIZE]; + + (void)sequenceProducerState; + (void)dict; + (void)dictSize; + (void)outSeqsCapacity; + (void)compressionLevel; + + { int i; + for (i=0; i < HSIZE; i++) { + hashTable[i] = BADIDX; + } } + + while (ip + MLS < iend) { + size_t const hash = ZSTD_hashPtr(ip, HLOG, MLS); + U32 const matchIndex = hashTable[hash]; + hashTable[hash] = (U32)(ip - istart); + + if (matchIndex != BADIDX) { + const BYTE* const match = istart + matchIndex; + U32 const matchLen = (U32)ZSTD_count(ip, match, iend); + if (matchLen >= ZSTD_MINMATCH_MIN) { + U32 const litLen = (U32)(ip - anchor); + U32 const offset = (U32)(ip - match); + ZSTD_Sequence const seq = { + offset, litLen, matchLen, 0 + }; + + /* Note: it's crucial to stay within the window size! */ + if (offset <= windowSize) { + outSeqs[seqCount++] = seq; + ip += matchLen; + anchor = ip; + continue; + } + } + } + + ip++; + } + + { ZSTD_Sequence const finalSeq = { + 0, (U32)(iend - anchor), 0, 0 + }; + outSeqs[seqCount++] = finalSeq; + } + + return seqCount; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/sequence_producer.h b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/sequence_producer.h new file mode 100644 index 000000000..19f9982ac --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/externalSequenceProducer/sequence_producer.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) Yann Collet, Meta Platforms, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef MATCHFINDER_H +#define MATCHFINDER_H + +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" + +size_t simpleSequenceProducer( + void* sequenceProducerState, + ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel, + size_t windowSize +); + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/freestanding_lib/freestanding.py b/cpp/third_party/zstd-1.5.7/contrib/freestanding_lib/freestanding.py new file mode 100755 index 000000000..df6983245 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/freestanding_lib/freestanding.py @@ -0,0 +1,774 @@ +#!/usr/bin/env python3 +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ########################################################################## + +import argparse +import contextlib +import os +import re +import shutil +import sys +from typing import Optional + + +INCLUDED_SUBDIRS = ["common", "compress", "decompress"] + +SKIPPED_FILES = [ + "common/mem.h", + "common/zstd_deps.h", + "common/pool.c", + "common/pool.h", + "common/threading.c", + "common/threading.h", + "common/zstd_trace.h", + "compress/zstdmt_compress.h", + "compress/zstdmt_compress.c", +] + +XXHASH_FILES = [ + "common/xxhash.c", + "common/xxhash.h", +] + + +class FileLines(object): + def __init__(self, filename): + self.filename = filename + with open(self.filename, "r") as f: + self.lines = f.readlines() + + def write(self): + with open(self.filename, "w") as f: + f.write("".join(self.lines)) + + +class PartialPreprocessor(object): + """ + Looks for simple ifdefs and ifndefs and replaces them. + Handles && and ||. + Has fancy logic to handle translating elifs to ifs. + Only looks for macros in the first part of the expression with no + parens. + Does not handle multi-line macros (only looks in first line). + """ + def __init__(self, defs: [(str, Optional[str])], replaces: [(str, str)], undefs: [str]): + MACRO_GROUP = r"(?P[a-zA-Z_][a-zA-Z_0-9]*)" + ELIF_GROUP = r"(?Pel)?" + OP_GROUP = r"(?P&&|\|\|)?" + + self._defs = {macro:value for macro, value in defs} + self._replaces = {macro:value for macro, value in replaces} + self._defs.update(self._replaces) + self._undefs = set(undefs) + + self._define = re.compile(r"\s*#\s*define") + self._if = re.compile(r"\s*#\s*if") + self._elif = re.compile(r"\s*#\s*(?Pel)if") + self._else = re.compile(r"\s*#\s*(?Pelse)") + self._endif = re.compile(r"\s*#\s*endif") + + self._ifdef = re.compile(fr"\s*#\s*if(?Pn)?def {MACRO_GROUP}\s*") + self._if_defined = re.compile( + fr"\s*#\s*{ELIF_GROUP}if\s+(?P!)?\s*defined\s*\(\s*{MACRO_GROUP}\s*\)\s*{OP_GROUP}" + ) + self._if_defined_value = re.compile( + fr"\s*#\s*{ELIF_GROUP}if\s+defined\s*\(\s*{MACRO_GROUP}\s*\)\s*" + fr"(?P&&)\s*" + fr"(?P\()?\s*" + fr"(?P[a-zA-Z_][a-zA-Z_0-9]*)\s*" + fr"(?P[=>[0-9]*)\s*" + fr"(?P\))?\s*" + ) + self._if_true = re.compile( + fr"\s*#\s*{ELIF_GROUP}if\s+{MACRO_GROUP}\s*{OP_GROUP}" + ) + + self._c_comment = re.compile(r"/\*.*?\*/") + self._cpp_comment = re.compile(r"//") + + def _log(self, *args, **kwargs): + print(*args, **kwargs) + + def _strip_comments(self, line): + # First strip c-style comments (may include //) + while True: + m = self._c_comment.search(line) + if m is None: + break + line = line[:m.start()] + line[m.end():] + + # Then strip cpp-style comments + m = self._cpp_comment.search(line) + if m is not None: + line = line[:m.start()] + + return line + + def _fixup_indentation(self, macro, replace: [str]): + if len(replace) == 0: + return replace + if len(replace) == 1 and self._define.match(replace[0]) is None: + # If there is only one line, only replace defines + return replace + + + all_pound = True + for line in replace: + if not line.startswith('#'): + all_pound = False + if all_pound: + replace = [line[1:] for line in replace] + + min_spaces = len(replace[0]) + for line in replace: + spaces = 0 + for i, c in enumerate(line): + if c != ' ': + # Non-preprocessor line ==> skip the fixup + if not all_pound and c != '#': + return replace + spaces = i + break + min_spaces = min(min_spaces, spaces) + + replace = [line[min_spaces:] for line in replace] + + if all_pound: + replace = ["#" + line for line in replace] + + return replace + + def _handle_if_block(self, macro, idx, is_true, prepend): + """ + Remove the #if or #elif block starting on this line. + """ + REMOVE_ONE = 0 + KEEP_ONE = 1 + REMOVE_REST = 2 + + if is_true: + state = KEEP_ONE + else: + state = REMOVE_ONE + + line = self._inlines[idx] + is_if = self._if.match(line) is not None + assert is_if or self._elif.match(line) is not None + depth = 0 + + start_idx = idx + + idx += 1 + replace = prepend + finished = False + while idx < len(self._inlines): + line = self._inlines[idx] + # Nested if statement + if self._if.match(line): + depth += 1 + idx += 1 + continue + # We're inside a nested statement + if depth > 0: + if self._endif.match(line): + depth -= 1 + idx += 1 + continue + + # We're at the original depth + + # Looking only for an endif. + # We've found a true statement, but haven't + # completely elided the if block, so we just + # remove the remainder. + if state == REMOVE_REST: + if self._endif.match(line): + if is_if: + # Remove the endif because we took the first if + idx += 1 + finished = True + break + idx += 1 + continue + + if state == KEEP_ONE: + m = self._elif.match(line) + if self._endif.match(line): + replace += self._inlines[start_idx + 1:idx] + idx += 1 + finished = True + break + if self._elif.match(line) or self._else.match(line): + replace += self._inlines[start_idx + 1:idx] + state = REMOVE_REST + idx += 1 + continue + + if state == REMOVE_ONE: + m = self._elif.match(line) + if m is not None: + if is_if: + idx += 1 + b = m.start('elif') + e = m.end('elif') + assert e - b == 2 + replace.append(line[:b] + line[e:]) + finished = True + break + m = self._else.match(line) + if m is not None: + if is_if: + idx += 1 + while self._endif.match(self._inlines[idx]) is None: + replace.append(self._inlines[idx]) + idx += 1 + idx += 1 + finished = True + break + if self._endif.match(line): + if is_if: + # Remove the endif because no other elifs + idx += 1 + finished = True + break + idx += 1 + continue + if not finished: + raise RuntimeError("Unterminated if block!") + + replace = self._fixup_indentation(macro, replace) + + self._log(f"\tHardwiring {macro}") + if start_idx > 0: + self._log(f"\t\t {self._inlines[start_idx - 1][:-1]}") + for x in range(start_idx, idx): + self._log(f"\t\t- {self._inlines[x][:-1]}") + for line in replace: + self._log(f"\t\t+ {line[:-1]}") + if idx < len(self._inlines): + self._log(f"\t\t {self._inlines[idx][:-1]}") + + return idx, replace + + def _preprocess_once(self): + outlines = [] + idx = 0 + changed = False + while idx < len(self._inlines): + line = self._inlines[idx] + sline = self._strip_comments(line) + m = self._ifdef.fullmatch(sline) + if_true = False + if m is None: + m = self._if_defined_value.fullmatch(sline) + if m is None: + m = self._if_defined.match(sline) + if m is None: + m = self._if_true.match(sline) + if_true = (m is not None) + if m is None: + outlines.append(line) + idx += 1 + continue + + groups = m.groupdict() + macro = groups['macro'] + op = groups.get('op') + + if not (macro in self._defs or macro in self._undefs): + outlines.append(line) + idx += 1 + continue + + defined = macro in self._defs + + # Needed variables set: + # resolved: Is the statement fully resolved? + # is_true: If resolved, is the statement true? + ifdef = False + if if_true: + if not defined: + outlines.append(line) + idx += 1 + continue + + defined_value = self._defs[macro] + is_int = True + try: + defined_value = int(defined_value) + except TypeError: + is_int = False + except ValueError: + is_int = False + + resolved = is_int + is_true = (defined_value != 0) + + if resolved and op is not None: + if op == '&&': + resolved = not is_true + else: + assert op == '||' + resolved = is_true + + else: + ifdef = groups.get('not') is None + elseif = groups.get('elif') is not None + + macro2 = groups.get('macro2') + cmp = groups.get('cmp') + value = groups.get('value') + openp = groups.get('openp') + closep = groups.get('closep') + + is_true = (ifdef == defined) + resolved = True + if op is not None: + if op == '&&': + resolved = not is_true + else: + assert op == '||' + resolved = is_true + + if macro2 is not None and not resolved: + assert ifdef and defined and op == '&&' and cmp is not None + # If the statement is true, but we have a single value check, then + # check the value. + defined_value = self._defs[macro] + are_ints = True + try: + defined_value = int(defined_value) + value = int(value) + except TypeError: + are_ints = False + except ValueError: + are_ints = False + if ( + macro == macro2 and + ((openp is None) == (closep is None)) and + are_ints + ): + resolved = True + if cmp == '<': + is_true = defined_value < value + elif cmp == '<=': + is_true = defined_value <= value + elif cmp == '==': + is_true = defined_value == value + elif cmp == '!=': + is_true = defined_value != value + elif cmp == '>=': + is_true = defined_value >= value + elif cmp == '>': + is_true = defined_value > value + else: + resolved = False + + if op is not None and not resolved: + # Remove the first op in the line + spaces + if op == '&&': + opre = op + else: + assert op == '||' + opre = r'\|\|' + needle = re.compile(fr"(?P\s*#\s*(el)?if\s+).*?(?P{opre}\s*)") + match = needle.match(line) + assert match is not None + newline = line[:match.end('if')] + line[match.end('op'):] + + self._log(f"\tHardwiring partially resolved {macro}") + self._log(f"\t\t- {line[:-1]}") + self._log(f"\t\t+ {newline[:-1]}") + + outlines.append(newline) + idx += 1 + continue + + # Skip any statements we cannot fully compute + if not resolved: + outlines.append(line) + idx += 1 + continue + + prepend = [] + if macro in self._replaces: + assert not ifdef + assert op is None + value = self._replaces.pop(macro) + prepend = [f"#define {macro} {value}\n"] + + idx, replace = self._handle_if_block(macro, idx, is_true, prepend) + outlines += replace + changed = True + + return changed, outlines + + def preprocess(self, filename): + with open(filename, 'r') as f: + self._inlines = f.readlines() + changed = True + iters = 0 + while changed: + iters += 1 + changed, outlines = self._preprocess_once() + self._inlines = outlines + + with open(filename, 'w') as f: + f.write(''.join(self._inlines)) + + +class Freestanding(object): + def __init__( + self, zstd_deps: str, mem: str, source_lib: str, output_lib: str, + external_xxhash: bool, xxh64_state: Optional[str], + xxh64_prefix: Optional[str], rewritten_includes: [(str, str)], + defs: [(str, Optional[str])], replaces: [(str, str)], + undefs: [str], excludes: [str], seds: [str], spdx: bool, + ): + self._zstd_deps = zstd_deps + self._mem = mem + self._src_lib = source_lib + self._dst_lib = output_lib + self._external_xxhash = external_xxhash + self._xxh64_state = xxh64_state + self._xxh64_prefix = xxh64_prefix + self._rewritten_includes = rewritten_includes + self._defs = defs + self._replaces = replaces + self._undefs = undefs + self._excludes = excludes + self._seds = seds + self._spdx = spdx + + def _dst_lib_file_paths(self): + """ + Yields all the file paths in the dst_lib. + """ + for root, dirname, filenames in os.walk(self._dst_lib): + for filename in filenames: + filepath = os.path.join(root, filename) + yield filepath + + def _log(self, *args, **kwargs): + print(*args, **kwargs) + + def _copy_file(self, lib_path): + suffixes = [".c", ".h", ".S"] + if not any((lib_path.endswith(suffix) for suffix in suffixes)): + return + if lib_path in SKIPPED_FILES: + self._log(f"\tSkipping file: {lib_path}") + return + if self._external_xxhash and lib_path in XXHASH_FILES: + self._log(f"\tSkipping xxhash file: {lib_path}") + return + + src_path = os.path.join(self._src_lib, lib_path) + dst_path = os.path.join(self._dst_lib, lib_path) + self._log(f"\tCopying: {src_path} -> {dst_path}") + shutil.copyfile(src_path, dst_path) + + def _copy_source_lib(self): + self._log("Copying source library into output library") + + assert os.path.exists(self._src_lib) + os.makedirs(self._dst_lib, exist_ok=True) + self._copy_file("zstd.h") + self._copy_file("zstd_errors.h") + for subdir in INCLUDED_SUBDIRS: + src_dir = os.path.join(self._src_lib, subdir) + dst_dir = os.path.join(self._dst_lib, subdir) + + assert os.path.exists(src_dir) + os.makedirs(dst_dir, exist_ok=True) + + for filename in os.listdir(src_dir): + lib_path = os.path.join(subdir, filename) + self._copy_file(lib_path) + + def _copy_zstd_deps(self): + dst_zstd_deps = os.path.join(self._dst_lib, "common", "zstd_deps.h") + self._log(f"Copying zstd_deps: {self._zstd_deps} -> {dst_zstd_deps}") + shutil.copyfile(self._zstd_deps, dst_zstd_deps) + + def _copy_mem(self): + dst_mem = os.path.join(self._dst_lib, "common", "mem.h") + self._log(f"Copying mem: {self._mem} -> {dst_mem}") + shutil.copyfile(self._mem, dst_mem) + + def _hardwire_preprocessor(self, name: str, value: Optional[str] = None, undef=False): + """ + If value=None then hardwire that it is defined, but not what the value is. + If undef=True then value must be None. + If value='' then the macro is defined to '' exactly. + """ + assert not (undef and value is not None) + for filepath in self._dst_lib_file_paths(): + file = FileLines(filepath) + + def _hardwire_defines(self): + self._log("Hardwiring macros") + partial_preprocessor = PartialPreprocessor(self._defs, self._replaces, self._undefs) + for filepath in self._dst_lib_file_paths(): + partial_preprocessor.preprocess(filepath) + + def _remove_excludes(self): + self._log("Removing excluded sections") + for exclude in self._excludes: + self._log(f"\tRemoving excluded sections for: {exclude}") + begin_re = re.compile(f"BEGIN {exclude}") + end_re = re.compile(f"END {exclude}") + for filepath in self._dst_lib_file_paths(): + file = FileLines(filepath) + outlines = [] + skipped = [] + emit = True + for line in file.lines: + if emit and begin_re.search(line) is not None: + assert end_re.search(line) is None + emit = False + if emit: + outlines.append(line) + else: + skipped.append(line) + if end_re.search(line) is not None: + assert begin_re.search(line) is None + self._log(f"\t\tRemoving excluded section: {exclude}") + for s in skipped: + self._log(f"\t\t\t- {s}") + emit = True + skipped = [] + if not emit: + raise RuntimeError("Excluded section unfinished!") + file.lines = outlines + file.write() + + def _rewrite_include(self, original, rewritten): + self._log(f"\tRewriting include: {original} -> {rewritten}") + regex = re.compile(f"\\s*#\\s*include\\s*(?P{original})") + for filepath in self._dst_lib_file_paths(): + file = FileLines(filepath) + for i, line in enumerate(file.lines): + match = regex.match(line) + if match is None: + continue + s = match.start('include') + e = match.end('include') + file.lines[i] = line[:s] + rewritten + line[e:] + file.write() + + def _rewrite_includes(self): + self._log("Rewriting includes") + for original, rewritten in self._rewritten_includes: + self._rewrite_include(original, rewritten) + + def _replace_xxh64_prefix(self): + if self._xxh64_prefix is None: + return + self._log(f"Replacing XXH64 prefix with {self._xxh64_prefix}") + replacements = [] + if self._xxh64_state is not None: + replacements.append( + (re.compile(r"([^\w]|^)(?PXXH64_state_t)([^\w]|$)"), self._xxh64_state) + ) + if self._xxh64_prefix is not None: + replacements.append( + (re.compile(r"([^\w]|^)(?PXXH64)[\(_]"), self._xxh64_prefix) + ) + for filepath in self._dst_lib_file_paths(): + file = FileLines(filepath) + for i, line in enumerate(file.lines): + modified = False + for regex, replacement in replacements: + match = regex.search(line) + while match is not None: + modified = True + b = match.start('orig') + e = match.end('orig') + line = line[:b] + replacement + line[e:] + match = regex.search(line) + if modified: + self._log(f"\t- {file.lines[i][:-1]}") + self._log(f"\t+ {line[:-1]}") + file.lines[i] = line + file.write() + + def _parse_sed(self, sed): + assert sed[0] == 's' + delim = sed[1] + match = re.fullmatch(f's{delim}(.+){delim}(.*){delim}(.*)', sed) + assert match is not None + regex = re.compile(match.group(1)) + format_str = match.group(2) + is_global = match.group(3) == 'g' + return regex, format_str, is_global + + def _process_sed(self, sed): + self._log(f"Processing sed: {sed}") + regex, format_str, is_global = self._parse_sed(sed) + + for filepath in self._dst_lib_file_paths(): + file = FileLines(filepath) + for i, line in enumerate(file.lines): + modified = False + while True: + match = regex.search(line) + if match is None: + break + replacement = format_str.format(match.groups(''), match.groupdict('')) + b = match.start() + e = match.end() + line = line[:b] + replacement + line[e:] + modified = True + if not is_global: + break + if modified: + self._log(f"\t- {file.lines[i][:-1]}") + self._log(f"\t+ {line[:-1]}") + file.lines[i] = line + file.write() + + def _process_seds(self): + self._log("Processing seds") + for sed in self._seds: + self._process_sed(sed) + + def _process_spdx(self): + if not self._spdx: + return + self._log("Processing spdx") + SPDX_C = "// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause\n" + SPDX_H_S = "/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */\n" + for filepath in self._dst_lib_file_paths(): + file = FileLines(filepath) + if file.lines[0] == SPDX_C or file.lines[0] == SPDX_H_S: + continue + for line in file.lines: + if "SPDX-License-Identifier" in line: + raise RuntimeError(f"Unexpected SPDX license identifier: {file.filename} {repr(line)}") + if file.filename.endswith(".c"): + file.lines.insert(0, SPDX_C) + elif file.filename.endswith(".h") or file.filename.endswith(".S"): + file.lines.insert(0, SPDX_H_S) + else: + raise RuntimeError(f"Unexpected file extension: {file.filename}") + file.write() + + + + def go(self): + self._copy_source_lib() + self._copy_zstd_deps() + self._copy_mem() + self._hardwire_defines() + self._remove_excludes() + self._rewrite_includes() + self._replace_xxh64_prefix() + self._process_seds() + self._process_spdx() + + +def parse_optional_pair(defines: [str]) -> [(str, Optional[str])]: + output = [] + for define in defines: + parsed = define.split('=') + if len(parsed) == 1: + output.append((parsed[0], None)) + elif len(parsed) == 2: + output.append((parsed[0], parsed[1])) + else: + raise RuntimeError(f"Bad define: {define}") + return output + + +def parse_pair(rewritten_includes: [str]) -> [(str, str)]: + output = [] + for rewritten_include in rewritten_includes: + parsed = rewritten_include.split('=') + if len(parsed) == 2: + output.append((parsed[0], parsed[1])) + else: + raise RuntimeError(f"Bad rewritten include: {rewritten_include}") + return output + + + +def main(name, args): + parser = argparse.ArgumentParser(prog=name) + parser.add_argument("--zstd-deps", default="zstd_deps.h", help="Zstd dependencies file") + parser.add_argument("--mem", default="mem.h", help="Memory module") + parser.add_argument("--source-lib", default="../../lib", help="Location of the zstd library") + parser.add_argument("--output-lib", default="./freestanding_lib", help="Where to output the freestanding zstd library") + parser.add_argument("--xxhash", default=None, help="Alternate external xxhash include e.g. --xxhash=''. If set xxhash is not included.") + parser.add_argument("--xxh64-state", default=None, help="Alternate XXH64 state type (excluding _) e.g. --xxh64-state='struct xxh64_state'") + parser.add_argument("--xxh64-prefix", default=None, help="Alternate XXH64 function prefix (excluding _) e.g. --xxh64-prefix=xxh64") + parser.add_argument("--rewrite-include", default=[], dest="rewritten_includes", action="append", help="Rewrite an include REGEX=NEW (e.g. '=')") + parser.add_argument("--sed", default=[], dest="seds", action="append", help="Apply a sed replacement. Format: `s/REGEX/FORMAT/[g]`. REGEX is a Python regex. FORMAT is a Python format string formatted by the regex dict.") + parser.add_argument("--spdx", action="store_true", help="Add SPDX License Identifiers") + parser.add_argument("-D", "--define", default=[], dest="defs", action="append", help="Pre-define this macro (can be passed multiple times)") + parser.add_argument("-U", "--undefine", default=[], dest="undefs", action="append", help="Pre-undefine this macro (can be passed multiple times)") + parser.add_argument("-R", "--replace", default=[], dest="replaces", action="append", help="Pre-define this macro and replace the first ifndef block with its definition") + parser.add_argument("-E", "--exclude", default=[], dest="excludes", action="append", help="Exclude all lines between 'BEGIN ' and 'END '") + args = parser.parse_args(args) + + # Always remove threading + if "ZSTD_MULTITHREAD" not in args.undefs: + args.undefs.append("ZSTD_MULTITHREAD") + + args.defs = parse_optional_pair(args.defs) + for name, _ in args.defs: + if name in args.undefs: + raise RuntimeError(f"{name} is both defined and undefined!") + + # Always set tracing to 0 + if "ZSTD_NO_TRACE" not in (arg[0] for arg in args.defs): + args.defs.append(("ZSTD_NO_TRACE", None)) + args.defs.append(("ZSTD_TRACE", "0")) + + args.replaces = parse_pair(args.replaces) + for name, _ in args.replaces: + if name in args.undefs or name in args.defs: + raise RuntimeError(f"{name} is both replaced and (un)defined!") + + args.rewritten_includes = parse_pair(args.rewritten_includes) + + external_xxhash = False + if args.xxhash is not None: + external_xxhash = True + args.rewritten_includes.append(('"(\\.\\./common/)?xxhash.h"', args.xxhash)) + + if args.xxh64_prefix is not None: + if not external_xxhash: + raise RuntimeError("--xxh64-prefix may only be used with --xxhash provided") + + if args.xxh64_state is not None: + if not external_xxhash: + raise RuntimeError("--xxh64-state may only be used with --xxhash provided") + + Freestanding( + args.zstd_deps, + args.mem, + args.source_lib, + args.output_lib, + external_xxhash, + args.xxh64_state, + args.xxh64_prefix, + args.rewritten_includes, + args.defs, + args.replaces, + args.undefs, + args.excludes, + args.seds, + args.spdx, + ).go() + +if __name__ == "__main__": + main(sys.argv[0], sys.argv[1:]) diff --git a/cpp/third_party/zstd-1.5.7/contrib/gen_html/.gitignore b/cpp/third_party/zstd-1.5.7/contrib/gen_html/.gitignore new file mode 100644 index 000000000..344611428 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/gen_html/.gitignore @@ -0,0 +1,3 @@ +# make artefact +gen_html +zstd_manual.html diff --git a/cpp/third_party/zstd-1.5.7/contrib/gen_html/Makefile b/cpp/third_party/zstd-1.5.7/contrib/gen_html/Makefile new file mode 100644 index 000000000..f93669e02 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/gen_html/Makefile @@ -0,0 +1,51 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +CXXFLAGS ?= -O3 +CXXFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wno-comment +CXXFLAGS += $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) + +ZSTDAPI = ../../lib/zstd.h +ZSTDMANUAL = ../../doc/zstd_manual.html +LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(ZSTDAPI)` +LIBVER_MINOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(ZSTDAPI)` +LIBVER_PATCH_SCRIPT:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(ZSTDAPI)` +LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT) +LIBVER := $(shell echo $(LIBVER_SCRIPT)) + + +# Define *.exe as extension for Windows systems +ifneq (,$(filter Windows%,$(OS))) +EXT =.exe +else +EXT = +endif + + +.PHONY: default +default: gen_html + +.PHONY: all +all: manual + +gen_html: gen_html.cpp + $(CXX) $(FLAGS) $^ -o $@$(EXT) + +$(ZSTDMANUAL): gen_html $(ZSTDAPI) + echo "Update zstd manual in /doc" + ./gen_html$(EXT) $(LIBVER) $(ZSTDAPI) $(ZSTDMANUAL) + +.PHONY: manual +manual: gen_html $(ZSTDMANUAL) + +.PHONY: clean +clean: + @$(RM) gen_html$(EXT) + @echo Cleaning completed diff --git a/cpp/third_party/zstd-1.5.7/contrib/gen_html/README.md b/cpp/third_party/zstd-1.5.7/contrib/gen_html/README.md new file mode 100644 index 000000000..63a4caa25 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/gen_html/README.md @@ -0,0 +1,31 @@ +gen_html - a program for automatic generation of zstd manual +============================================================ + +#### Introduction + +This simple C++ program generates a single-page HTML manual from `zstd.h`. + +The format of recognized comment blocks is following: +- comments of type `/*!` mean: this is a function declaration; switch comments with declarations +- comments of type `/**` and `/*-` mean: this is a comment; use a `

` header for the first line +- comments of type `/*=` and `/**=` mean: use a `

` header and show also all functions until first empty line +- comments of type `/*X` where `X` is different from above-mentioned are ignored + +Moreover: +- `ZSTDLIB_API` is removed to improve readability +- `typedef` are detected and included even if uncommented +- comments of type `/**<` and `/*!<` are detected and only function declaration is highlighted (bold) + + +#### Usage + +The program requires 3 parameters: +``` +gen_html [zstd_version] [input_file] [output_html] +``` + +To compile program and generate zstd manual we have used: +``` +make +./gen_html.exe 1.1.1 ../../lib/zstd.h zstd_manual.html +``` diff --git a/cpp/third_party/zstd-1.5.7/contrib/gen_html/gen-zstd-manual.sh b/cpp/third_party/zstd-1.5.7/contrib/gen_html/gen-zstd-manual.sh new file mode 100755 index 000000000..57a8b6ea5 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/gen_html/gen-zstd-manual.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +LIBVER_MAJOR_SCRIPT=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ../../lib/zstd.h` +LIBVER_MINOR_SCRIPT=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ../../lib/zstd.h` +LIBVER_PATCH_SCRIPT=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ../../lib/zstd.h` +LIBVER_SCRIPT=$LIBVER_MAJOR_SCRIPT.$LIBVER_MINOR_SCRIPT.$LIBVER_PATCH_SCRIPT + +echo ZSTD_VERSION=$LIBVER_SCRIPT +./gen_html $LIBVER_SCRIPT ../../lib/zstd.h ./zstd_manual.html diff --git a/cpp/third_party/zstd-1.5.7/contrib/gen_html/gen_html.cpp b/cpp/third_party/zstd-1.5.7/contrib/gen_html/gen_html.cpp new file mode 100644 index 000000000..adf0f41b9 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/gen_html/gen_html.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + +#include +#include +#include +#include +using namespace std; + + +/* trim string at the beginning and at the end */ +void trim(string& s, string characters) +{ + size_t p = s.find_first_not_of(characters); + s.erase(0, p); + + p = s.find_last_not_of(characters); + if (string::npos != p) + s.erase(p+1); +} + + +/* trim C++ style comments */ +void trim_comments(string &s) +{ + size_t spos, epos; + + spos = s.find("/*"); + epos = s.find("*/"); + s = s.substr(spos+3, epos-(spos+3)); +} + + +/* get lines until a given terminator */ +vector get_lines(vector& input, int& linenum, string terminator) +{ + vector out; + string line; + size_t epos; + + while ((size_t)linenum < input.size()) { + line = input[linenum]; + + if (terminator.empty() && line.empty()) { linenum--; break; } + + epos = line.find(terminator); + if (!terminator.empty() && epos!=string::npos) { + out.push_back(line); + break; + } + out.push_back(line); + linenum++; + } + return out; +} + + +/* print line with ZSTDLIB_API removed and C++ comments not bold */ +void print_line(stringstream &sout, string line) +{ + size_t spos; + + if (line.substr(0,12) == "ZSTDLIB_API ") line = line.substr(12); + spos = line.find("/*"); + if (spos!=string::npos) { + sout << line.substr(0, spos); + sout << "" << line.substr(spos) << "" << endl; + } else { + // fprintf(stderr, "lines=%s\n", line.c_str()); + sout << line << endl; + } +} + + +int main(int argc, char *argv[]) { + char exclam; + int linenum, chapter = 1; + vector input, lines, comments, chapters; + string line, version; + size_t spos, l; + stringstream sout; + ifstream istream; + ofstream ostream; + + if (argc < 4) { + cout << "usage: " << argv[0] << " [zstd_version] [input_file] [output_html]" << endl; + return 1; + } + + version = "zstd " + string(argv[1]) + " Manual"; + + istream.open(argv[2], ifstream::in); + if (!istream.is_open()) { + cout << "Error opening file " << argv[2] << endl; + return 1; + } + + ostream.open(argv[3], ifstream::out); + if (!ostream.is_open()) { + cout << "Error opening file " << argv[3] << endl; + return 1; + } + + while (getline(istream, line)) { + input.push_back(line); + } + + for (linenum=0; (size_t)linenum < input.size(); linenum++) { + line = input[linenum]; + + /* typedefs are detected and included even if uncommented */ + if (line.substr(0,7) == "typedef" && line.find("{")!=string::npos) { + lines = get_lines(input, linenum, "}"); + sout << "
";
+            for (l=0; l

" << endl; + continue; + } + + /* comments of type /**< and /*!< are detected and only function declaration is highlighted (bold) */ + if ((line.find("/**<")!=string::npos || line.find("/*!<")!=string::npos) && line.find("*/")!=string::npos) { + sout << "
";
+            print_line(sout, line);
+            sout << "

" << endl; + continue; + } + + spos = line.find("/**="); + if (spos==string::npos) { + spos = line.find("/*!"); + if (spos==string::npos) + spos = line.find("/**"); + if (spos==string::npos) + spos = line.find("/*-"); + if (spos==string::npos) + spos = line.find("/*="); + if (spos==string::npos) + continue; + exclam = line[spos+2]; + } + else exclam = '='; + + comments = get_lines(input, linenum, "*/"); + if (!comments.empty()) comments[0] = line.substr(spos+3); + if (!comments.empty()) comments[comments.size()-1] = comments[comments.size()-1].substr(0, comments[comments.size()-1].find("*/")); + for (l=0; l"; + for (l=0; l

"; + for (l=0; l
" << endl << endl; + } else if (exclam == '=') { /* comments of type /*= and /**= mean: use a

header and show also all functions until first empty line */ + trim(comments[0], " "); + sout << "

" << comments[0] << "

";
+            for (l=1; l
";
+            lines = get_lines(input, ++linenum, "");
+            for (l=0; l
" << endl; + } else { /* comments of type /** and /*- mean: this is a comment; use a

header for the first line */ + if (comments.empty()) continue; + + trim(comments[0], " "); + sout << "

" << comments[0] << "

";
+            chapters.push_back(comments[0]);
+            chapter++;
+
+            for (l=1; l 1)
+                sout << "
" << endl << endl; + else + sout << "
" << endl << endl; + } + } + + ostream << "\n\n\n" << version << "\n\n" << endl; + ostream << "

" << version << "

\n"; + ostream << "Note: the content of this file has been automatically generated by parsing \"zstd.h\" \n"; + + ostream << "
\n

Contents

\n
    \n"; + for (size_t i=0; i" << chapters[i].c_str() << "\n"; + ostream << "
\n
\n"; + + ostream << sout.str(); + ostream << "" << endl << "" << endl; + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/.gitignore b/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/.gitignore new file mode 100644 index 000000000..e77c4e496 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/.gitignore @@ -0,0 +1,2 @@ +# build artifacts +largeNbDicts diff --git a/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/Makefile b/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/Makefile new file mode 100644 index 000000000..40734e62e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/Makefile @@ -0,0 +1,58 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +PROGDIR = ../../programs +LIBDIR = ../../lib + +LIBZSTD = $(LIBDIR)/libzstd.a + +CPPFLAGS+= -I$(LIBDIR) -I$(LIBDIR)/common -I$(LIBDIR)/dictBuilder -I$(PROGDIR) + +CFLAGS ?= -O3 +CFLAGS += -std=gnu99 +DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum \ + -Wstrict-prototypes -Wundef -Wpointer-arith \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls +CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) + + +default: largeNbDicts + +all : largeNbDicts + +largeNbDicts: util.o timefn.o benchfn.o datagen.o xxhash.o largeNbDicts.c $(LIBZSTD) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +.PHONY: $(LIBZSTD) +$(LIBZSTD): + $(MAKE) -C $(LIBDIR) libzstd.a CFLAGS="$(CFLAGS)" + +benchfn.o: $(PROGDIR)/benchfn.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + +timefn.o: $(PROGDIR)/timefn.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + +datagen.o: $(PROGDIR)/datagen.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + +util.o: $(PROGDIR)/util.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + + +xxhash.o : $(LIBDIR)/common/xxhash.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + + +clean: + $(RM) *.o + $(MAKE) -C $(LIBDIR) clean > /dev/null + $(RM) largeNbDicts diff --git a/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/README.md b/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/README.md new file mode 100644 index 000000000..010102c90 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/README.md @@ -0,0 +1,33 @@ +largeNbDicts +===================== + +`largeNbDicts` is a benchmark test tool +dedicated to the specific scenario of +dictionary decompression using a very large number of dictionaries. +When dictionaries are constantly changing, they are always "cold", +suffering from increased latency due to cache misses. + +The tool is created in a bid to investigate performance for this scenario, +and experiment mitigation techniques. + +Command line : +``` +largeNbDicts [Options] filename(s) + +Options : +-z : benchmark compression (default) +-d : benchmark decompression +-r : recursively load all files in subdirectories (default: off) +-B# : split input into blocks of size # (default: no split) +-# : use compression level # (default: 3) +-D # : use # as a dictionary (default: create one) +-i# : nb benchmark rounds (default: 6) +--nbBlocks=#: use # blocks for bench (default: one per file) +--nbDicts=# : create # dictionaries for bench (default: one per block) +-h : help (this text) + +Advanced Options (see zstd.h for documentation) : +--dedicated-dict-search +--dict-content-type=# +--dict-attach-pref=# +``` diff --git a/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/largeNbDicts.c b/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/largeNbDicts.c new file mode 100644 index 000000000..6502f1227 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/largeNbDicts/largeNbDicts.c @@ -0,0 +1,1085 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* largeNbDicts + * This is a benchmark test tool + * dedicated to the specific case of dictionary decompression + * using a very large nb of dictionaries + * thus suffering latency from lots of cache misses. + * It's created in a bid to investigate performance and find optimizations. */ + + +/*--- Dependencies ---*/ + +#include /* size_t */ +#include /* malloc, free, abort, qsort*/ +#include /* fprintf */ +#include /* UINT_MAX */ +#include /* assert */ + +#include "util.h" +#include "benchfn.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "zdict.h" + + +/*--- Constants --- */ + +#define KB *(1<<10) +#define MB *(1<<20) + +#define BLOCKSIZE_DEFAULT 0 /* no slicing into blocks */ +#define DICTSIZE (4 KB) +#define CLEVEL_DEFAULT 3 +#define DICT_LOAD_METHOD ZSTD_dlm_byCopy + +#define BENCH_TIME_DEFAULT_S 6 +#define RUN_TIME_DEFAULT_MS 1000 +#define BENCH_TIME_DEFAULT_MS (BENCH_TIME_DEFAULT_S * RUN_TIME_DEFAULT_MS) + +#define DISPLAY_LEVEL_DEFAULT 3 + +#define BENCH_SIZE_MAX (1200 MB) + + +/*--- Macros ---*/ + +#define CONTROL(c) { if (!(c)) abort(); } +#undef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +/*--- Display Macros ---*/ + +#define DISPLAY(...) fprintf(stdout, __VA_ARGS__) +#define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } } +static int g_displayLevel = DISPLAY_LEVEL_DEFAULT; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */ + + +/*--- buffer_t ---*/ + +typedef struct { + void* ptr; + size_t size; + size_t capacity; +} buffer_t; + +static const buffer_t kBuffNull = { NULL, 0, 0 }; + +/* @return : kBuffNull if any error */ +static buffer_t createBuffer(size_t capacity) +{ + assert(capacity > 0); + void* const ptr = malloc(capacity); + if (ptr==NULL) return kBuffNull; + + buffer_t buffer; + buffer.ptr = ptr; + buffer.capacity = capacity; + buffer.size = 0; + return buffer; +} + +static void freeBuffer(buffer_t buff) +{ + free(buff.ptr); +} + + +static void fillBuffer_fromHandle(buffer_t* buff, FILE* f) +{ + size_t const readSize = fread(buff->ptr, 1, buff->capacity, f); + buff->size = readSize; +} + + +/* @return : kBuffNull if any error */ +static buffer_t createBuffer_fromFile(const char* fileName) +{ + U64 const fileSize = UTIL_getFileSize(fileName); + size_t const bufferSize = (size_t) fileSize; + + if (fileSize == UTIL_FILESIZE_UNKNOWN) return kBuffNull; + assert((U64)bufferSize == fileSize); /* check overflow */ + + { FILE* const f = fopen(fileName, "rb"); + if (f == NULL) return kBuffNull; + + buffer_t buff = createBuffer(bufferSize); + CONTROL(buff.ptr != NULL); + + fillBuffer_fromHandle(&buff, f); + CONTROL(buff.size == buff.capacity); + + fclose(f); /* do nothing specific if fclose() fails */ + return buff; + } +} + + +/* @return : kBuffNull if any error */ +static buffer_t +createDictionaryBuffer(const char* dictionaryName, + const void* srcBuffer, + const size_t* srcBlockSizes, size_t nbBlocks, + size_t requestedDictSize) +{ + if (dictionaryName) { + DISPLAYLEVEL(3, "loading dictionary %s \n", dictionaryName); + return createBuffer_fromFile(dictionaryName); /* note : result might be kBuffNull */ + + } else { + + DISPLAYLEVEL(3, "creating dictionary, of target size %u bytes \n", + (unsigned)requestedDictSize); + void* const dictBuffer = malloc(requestedDictSize); + CONTROL(dictBuffer != NULL); + + assert(nbBlocks <= UINT_MAX); + size_t const dictSize = ZDICT_trainFromBuffer(dictBuffer, requestedDictSize, + srcBuffer, + srcBlockSizes, (unsigned)nbBlocks); + CONTROL(!ZSTD_isError(dictSize)); + + buffer_t result; + result.ptr = dictBuffer; + result.capacity = requestedDictSize; + result.size = dictSize; + return result; + } +} + +/*! BMK_loadFiles() : + * Loads `buffer`, with content from files listed within `fileNamesTable`. + * Fills `buffer` entirely. + * @return : 0 on success, !=0 on error */ +static int loadFiles(void* buffer, size_t bufferSize, + size_t* fileSizes, + const char* const * fileNamesTable, unsigned nbFiles) +{ + size_t pos = 0, totalSize = 0; + + for (unsigned n=0; n 0); + void* const srcBuffer = malloc(loadedSize); + assert(srcBuffer != NULL); + + assert(nbFiles > 0); + size_t* const fileSizes = (size_t*)calloc(nbFiles, sizeof(*fileSizes)); + assert(fileSizes != NULL); + + /* Load input buffer */ + int const errorCode = loadFiles(srcBuffer, loadedSize, + fileSizes, + fileNamesTable, nbFiles); + assert(errorCode == 0); + + void** sliceTable = (void**)malloc(nbFiles * sizeof(*sliceTable)); + assert(sliceTable != NULL); + + char* const ptr = (char*)srcBuffer; + size_t pos = 0; + unsigned fileNb = 0; + for ( ; (pos < loadedSize) && (fileNb < nbFiles); fileNb++) { + sliceTable[fileNb] = ptr + pos; + pos += fileSizes[fileNb]; + } + assert(pos == loadedSize); + assert(fileNb == nbFiles); + + + buffer_t buffer; + buffer.ptr = srcBuffer; + buffer.capacity = loadedSize; + buffer.size = loadedSize; + + slice_collection_t slices; + slices.slicePtrs = sliceTable; + slices.capacities = fileSizes; + slices.nbSlices = nbFiles; + + buffer_collection_t bc; + bc.buffer = buffer; + bc.slices = slices; + return bc; +} + + + + +/*--- ddict_collection_t ---*/ + +typedef struct { + ZSTD_DDict** ddicts; + size_t nbDDict; +} ddict_collection_t; + +typedef struct { + ZSTD_CDict** cdicts; + size_t nbCDict; +} cdict_collection_t; + +static const cdict_collection_t kNullCDictCollection = { NULL, 0 }; + +static void freeCDictCollection(cdict_collection_t cdictc) +{ + for (size_t dictNb=0; dictNb < cdictc.nbCDict; dictNb++) { + ZSTD_freeCDict(cdictc.cdicts[dictNb]); + } + free(cdictc.cdicts); +} + +/* returns .buffers=NULL if operation fails */ +static cdict_collection_t createCDictCollection(const void* dictBuffer, size_t dictSize, size_t nbCDict, ZSTD_dictContentType_e dictContentType, ZSTD_CCtx_params* cctxParams) +{ + ZSTD_CDict** const cdicts = malloc(nbCDict * sizeof(ZSTD_CDict*)); + if (cdicts==NULL) return kNullCDictCollection; + for (size_t dictNb=0; dictNb < nbCDict; dictNb++) { + cdicts[dictNb] = ZSTD_createCDict_advanced2(dictBuffer, dictSize, DICT_LOAD_METHOD, dictContentType, cctxParams, ZSTD_defaultCMem); + CONTROL(cdicts[dictNb] != NULL); + } + cdict_collection_t cdictc; + cdictc.cdicts = cdicts; + cdictc.nbCDict = nbCDict; + return cdictc; +} + +static const ddict_collection_t kNullDDictCollection = { NULL, 0 }; + +static void freeDDictCollection(ddict_collection_t ddictc) +{ + for (size_t dictNb=0; dictNb < ddictc.nbDDict; dictNb++) { + ZSTD_freeDDict(ddictc.ddicts[dictNb]); + } + free(ddictc.ddicts); +} + +/* returns .buffers=NULL if operation fails */ +static ddict_collection_t createDDictCollection(const void* dictBuffer, size_t dictSize, size_t nbDDict) +{ + ZSTD_DDict** const ddicts = malloc(nbDDict * sizeof(ZSTD_DDict*)); + assert(ddicts != NULL); + if (ddicts==NULL) return kNullDDictCollection; + for (size_t dictNb=0; dictNb < nbDDict; dictNb++) { + ddicts[dictNb] = ZSTD_createDDict(dictBuffer, dictSize); + assert(ddicts[dictNb] != NULL); + } + ddict_collection_t ddictc; + ddictc.ddicts = ddicts; + ddictc.nbDDict = nbDDict; + return ddictc; +} + + +/* mess with addresses, so that linear scanning dictionaries != linear address scanning */ +void shuffleCDictionaries(cdict_collection_t dicts) +{ + size_t const nbDicts = dicts.nbCDict; + for (size_t r=0; rcctx, ci->dictionaries.cdicts[ci->dictNb]); + ZSTD_compress2(ci->cctx, + dst, srcSize, + src, srcSize); + + ci->dictNb = ci->dictNb + 1; + if (ci->dictNb >= ci->nbDicts) ci->dictNb = 0; + + return srcSize; +} + +/* benched function */ +size_t decompress(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* payload) +{ + decompressInstructions* const di = (decompressInstructions*) payload; + + size_t const result = ZSTD_decompress_usingDDict(di->dctx, + dst, dstCapacity, + src, srcSize, + di->dictionaries.ddicts[di->dictNb]); + + di->dictNb = di->dictNb + 1; + if (di->dictNb >= di->nbDicts) di->dictNb = 0; + + return result; +} + +typedef enum { + fastest = 0, + median = 1, +} metricAggregatePref_e; + +/* compareFunction() : + * Sort input in decreasing order when used with qsort() */ +int compareFunction(const void *a, const void *b) +{ + double x = *(const double *)a; + double y = *(const double *)b; + if (x < y) + return 1; + else if (x > y) + return -1; + return 0; +} + +double aggregateData(double *data, size_t size, + metricAggregatePref_e metricAggregatePref) +{ + qsort(data, size, sizeof(*data), compareFunction); + if (metricAggregatePref == fastest) + return data[0]; + else /* median */ + return (data[(size - 1) / 2] + data[size / 2]) / 2; +} + +static int benchMem(slice_collection_t dstBlocks, slice_collection_t srcBlocks, + ddict_collection_t ddictionaries, + cdict_collection_t cdictionaries, unsigned nbRounds, + int benchCompression, const char *exeName, + ZSTD_CCtx_params *cctxParams, + metricAggregatePref_e metricAggregatePref) +{ + assert(dstBlocks.nbSlices == srcBlocks.nbSlices); + if (benchCompression) assert(cctxParams); + + unsigned const ms_per_round = RUN_TIME_DEFAULT_MS; + unsigned const total_time_ms = nbRounds * ms_per_round; + + double *const speedPerRound = (double *)malloc(nbRounds * sizeof(double)); + + BMK_timedFnState_t* const benchState = + BMK_createTimedFnState(total_time_ms, ms_per_round); + + decompressInstructions di = createDecompressInstructions(ddictionaries); + compressInstructions ci = + createCompressInstructions(cdictionaries, cctxParams); + void* payload = benchCompression ? (void*)&ci : (void*)&di; + BMK_benchParams_t const bp = { + .benchFn = benchCompression ? compress : decompress, + .benchPayload = payload, + .initFn = NULL, + .initPayload = NULL, + .errorFn = ZSTD_isError, + .blockCount = dstBlocks.nbSlices, + .srcBuffers = (const void* const*) srcBlocks.slicePtrs, + .srcSizes = srcBlocks.capacities, + .dstBuffers = dstBlocks.slicePtrs, + .dstCapacities = dstBlocks.capacities, + .blockResults = NULL + }; + + size_t roundNb = 0; + for (;;) { + BMK_runOutcome_t const outcome = BMK_benchTimedFn(benchState, bp); + CONTROL(BMK_isSuccessful_runOutcome(outcome)); + + BMK_runTime_t const result = BMK_extract_runTime(outcome); + double const dTime_ns = result.nanoSecPerRun; + double const dTime_sec = (double)dTime_ns / 1000000000; + size_t const srcSize = result.sumOfReturn; + double const speed_MBps = (double)srcSize / dTime_sec / (1 MB); + speedPerRound[roundNb] = speed_MBps; + if (benchCompression) + DISPLAY("Compression Speed : %.1f MB/s \r", speed_MBps); + else + DISPLAY("Decompression Speed : %.1f MB/s \r", speed_MBps); + + fflush(stdout); + if (BMK_isCompleted_TimedFn(benchState)) break; + roundNb++; + } + DISPLAY("\n"); + /* BMK_benchTimedFn may not run exactly nbRounds iterations */ + double speedAggregated = + aggregateData(speedPerRound, roundNb + 1, metricAggregatePref); + if (metricAggregatePref == fastest) + DISPLAY("Fastest Speed : %.1f MB/s \n", speedAggregated); + else + DISPLAY("Median Speed : %.1f MB/s \n", speedAggregated); + + char* csvFileName = malloc(strlen(exeName) + 5); + strcpy(csvFileName, exeName); + strcat(csvFileName, ".csv"); + FILE* csvFile = fopen(csvFileName, "r"); + if (!csvFile) { + csvFile = fopen(csvFileName, "wt"); + assert(csvFile); + fprintf(csvFile, "%s\n", exeName); + /* Print table headers */ + fprintf( + csvFile, + "Compression/Decompression,Level,nbDicts,dictAttachPref,metricAggregatePref,Speed\n"); + } else { + fclose(csvFile); + csvFile = fopen(csvFileName, "at"); + assert(csvFile); + } + + int cLevel = -1; + int dictAttachPref = -1; + if (benchCompression) { + ZSTD_CCtxParams_getParameter(cctxParams, ZSTD_c_compressionLevel, + &cLevel); + ZSTD_CCtxParams_getParameter(cctxParams, ZSTD_c_forceAttachDict, + &dictAttachPref); + } + fprintf(csvFile, "%s,%d,%ld,%d,%d,%.1f\n", + benchCompression ? "Compression" : "Decompression", cLevel, + benchCompression ? ci.nbDicts : di.nbDicts, dictAttachPref, + metricAggregatePref, speedAggregated); + fclose(csvFile); + free(csvFileName); + + freeDecompressInstructions(di); + freeCompressInstructions(ci); + BMK_freeTimedFnState(benchState); + + return 0; /* success */ +} + + +/*! bench() : + * fileName : file to load for benchmarking purpose + * dictionary : optional (can be NULL), file to load as dictionary, + * if none provided : will be calculated on the fly by the program. + * @return : 0 is success, 1+ otherwise */ +int bench(const char **fileNameTable, unsigned nbFiles, const char *dictionary, + size_t blockSize, int clevel, unsigned nbDictMax, unsigned nbBlocks, + unsigned nbRounds, int benchCompression, + ZSTD_dictContentType_e dictContentType, ZSTD_CCtx_params *cctxParams, + const char *exeName, metricAggregatePref_e metricAggregatePref) +{ + int result = 0; + + DISPLAYLEVEL(3, "loading %u files... \n", nbFiles); + buffer_collection_t const srcs = createBufferCollection_fromFiles(fileNameTable, nbFiles); + CONTROL(srcs.buffer.ptr != NULL); + buffer_t srcBuffer = srcs.buffer; + size_t const srcSize = srcBuffer.size; + DISPLAYLEVEL(3, "created src buffer of size %.1f MB \n", + (double)srcSize / (1 MB)); + + slice_collection_t const srcSlices = splitSlices(srcs.slices, blockSize, nbBlocks); + nbBlocks = (unsigned)(srcSlices.nbSlices); + DISPLAYLEVEL(3, "split input into %u blocks ", nbBlocks); + if (blockSize) + DISPLAYLEVEL(3, "of max size %u bytes ", (unsigned)blockSize); + DISPLAYLEVEL(3, "\n"); + size_t const totalSrcSlicesSize = sliceCollection_totalCapacity(srcSlices); + + + size_t* const dstCapacities = malloc(nbBlocks * sizeof(*dstCapacities)); + CONTROL(dstCapacities != NULL); + size_t dstBufferCapacity = 0; + for (size_t bnb=0; bnb='0') && (**stringPtr <='9')) { + unsigned const max = (((unsigned)(-1)) / 10) - 1; + assert(result <= max); /* check overflow */ + result *= 10, result += (unsigned)**stringPtr - '0', (*stringPtr)++ ; + } + if ((**stringPtr=='K') || (**stringPtr=='M')) { + unsigned const maxK = ((unsigned)(-1)) >> 10; + assert(result <= maxK); /* check overflow */ + result <<= 10; + if (**stringPtr=='M') { + assert(result <= maxK); /* check overflow */ + result <<= 10; + } + (*stringPtr)++; /* skip `K` or `M` */ + if (**stringPtr=='i') (*stringPtr)++; + if (**stringPtr=='B') (*stringPtr)++; + } + return result; +} + +/** longCommandWArg() : + * check if *stringPtr is the same as longCommand. + * If yes, @return 1 and advances *stringPtr to the position which immediately follows longCommand. + * @return 0 and doesn't modify *stringPtr otherwise. + */ +static int longCommandWArg(const char** stringPtr, const char* longCommand) +{ + size_t const comSize = strlen(longCommand); + int const result = !strncmp(*stringPtr, longCommand, comSize); + if (result) *stringPtr += comSize; + return result; +} + + +int usage(const char* exeName) +{ + DISPLAY (" \n"); + DISPLAY (" %s [Options] filename(s) \n", exeName); + DISPLAY (" \n"); + DISPLAY ("Options : \n"); + DISPLAY ("-z : benchmark compression (default) \n"); + DISPLAY ("-d : benchmark decompression \n"); + DISPLAY ("-r : recursively load all files in subdirectories (default: off) \n"); + DISPLAY ("-B# : split input into blocks of size # (default: no split) \n"); + DISPLAY ("-# : use compression level # (default: %u) \n", CLEVEL_DEFAULT); + DISPLAY ("-D # : use # as a dictionary (default: create one) \n"); + DISPLAY ("-i# : nb benchmark rounds (default: %u) \n", BENCH_TIME_DEFAULT_S); + DISPLAY ("-p# : print speed for all rounds 0=fastest 1=median (default: 0) \n"); + DISPLAY ("--nbBlocks=#: use # blocks for bench (default: one per file) \n"); + DISPLAY ("--nbDicts=# : create # dictionaries for bench (default: one per block) \n"); + DISPLAY ("-h : help (this text) \n"); + DISPLAY (" \n"); + DISPLAY ("Advanced Options (see zstd.h for documentation) : \n"); + DISPLAY ("--dedicated-dict-search\n"); + DISPLAY ("--dict-content-type=#\n"); + DISPLAY ("--dict-attach-pref=#\n"); + return 0; +} + +int bad_usage(const char* exeName) +{ + DISPLAY (" bad usage : \n"); + usage(exeName); + return 1; +} + +int main (int argc, const char** argv) +{ + int recursiveMode = 0; + int benchCompression = 1; + int dedicatedDictSearch = 0; + unsigned nbRounds = BENCH_TIME_DEFAULT_S; + const char* const exeName = argv[0]; + + if (argc < 2) return bad_usage(exeName); + + const char** nameTable = (const char**)malloc((size_t)argc * sizeof(const char*)); + assert(nameTable != NULL); + unsigned nameIdx = 0; + + const char* dictionary = NULL; + int cLevel = CLEVEL_DEFAULT; + size_t blockSize = BLOCKSIZE_DEFAULT; + unsigned nbDicts = 0; /* determine nbDicts automatically: 1 dictionary per block */ + unsigned nbBlocks = 0; /* determine nbBlocks automatically, from source and blockSize */ + ZSTD_dictContentType_e dictContentType = ZSTD_dct_auto; + ZSTD_dictAttachPref_e dictAttachPref = ZSTD_dictDefaultAttach; + ZSTD_ParamSwitch_e prefetchCDictTables = ZSTD_ps_auto; + metricAggregatePref_e metricAggregatePref = fastest; + + for (int argNb = 1; argNb < argc ; argNb++) { + const char* argument = argv[argNb]; + if (!strcmp(argument, "-h")) { free(nameTable); return usage(exeName); } + if (!strcmp(argument, "-d")) { benchCompression = 0; continue; } + if (!strcmp(argument, "-z")) { benchCompression = 1; continue; } + if (!strcmp(argument, "-r")) { recursiveMode = 1; continue; } + if (!strcmp(argument, "-D")) { argNb++; assert(argNb < argc); dictionary = argv[argNb]; continue; } + if (longCommandWArg(&argument, "-i")) { nbRounds = readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "-p")) { metricAggregatePref = (int)readU32FromChar(&argument); continue;} + if (longCommandWArg(&argument, "--dictionary=")) { dictionary = argument; continue; } + if (longCommandWArg(&argument, "-B")) { blockSize = readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "--blockSize=")) { blockSize = readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "--nbDicts=")) { nbDicts = readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "--nbBlocks=")) { nbBlocks = readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "--clevel=")) { cLevel = (int)readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "--dedicated-dict-search")) { dedicatedDictSearch = 1; continue; } + if (longCommandWArg(&argument, "--dict-content-type=")) { dictContentType = (int)readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "--dict-attach-pref=")) { dictAttachPref = (int)readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "--prefetch-cdict-tables=")) { prefetchCDictTables = (int)readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "-")) { cLevel = (int)readU32FromChar(&argument); continue; } + /* anything that's not a command is a filename */ + nameTable[nameIdx++] = argument; + } + + FileNamesTable* filenameTable; + + if (recursiveMode) { +#ifndef UTIL_HAS_CREATEFILELIST + assert(0); /* missing capability, do not run */ +#endif + filenameTable = UTIL_createExpandedFNT(nameTable, nameIdx, 1 /* follow_links */); + } else { + filenameTable = UTIL_assembleFileNamesTable(nameTable, nameIdx, NULL); + nameTable = NULL; /* UTIL_createFileNamesTable() takes ownership of nameTable */ + } + + ZSTD_CCtx_params* cctxParams = ZSTD_createCCtxParams(); + ZSTD_CCtxParams_init(cctxParams, cLevel); + ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_enableDedicatedDictSearch, dedicatedDictSearch); + ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_nbWorkers, 0); + ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_forceAttachDict, dictAttachPref); + ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_prefetchCDictTables, prefetchCDictTables); + + int result = + bench(filenameTable->fileNames, (unsigned)filenameTable->tableSize, + dictionary, blockSize, cLevel, nbDicts, nbBlocks, nbRounds, + benchCompression, dictContentType, cctxParams, exeName, + metricAggregatePref); + + UTIL_freeFileNamesTable(filenameTable); + free(nameTable); + ZSTD_freeCCtxParams(cctxParams); + + return result; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/.gitignore b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/.gitignore new file mode 100644 index 000000000..d8dfeef21 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/.gitignore @@ -0,0 +1,4 @@ +!lib/zstd +!lib/zstd/* +*.o +*.a diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/Makefile b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/Makefile new file mode 100644 index 000000000..63dd15d95 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/Makefile @@ -0,0 +1,108 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ + +.PHONY: libzstd +libzstd: + rm -rf linux + mkdir -p linux + mkdir -p linux/include/linux + mkdir -p linux/lib/zstd + ../freestanding_lib/freestanding.py \ + --source-lib ../../lib \ + --output-lib linux/lib/zstd \ + --xxhash '' \ + --xxh64-state 'struct xxh64_state' \ + --xxh64-prefix 'xxh64' \ + --rewrite-include '=' \ + --rewrite-include '=' \ + --rewrite-include '"\.\./zstd.h"=' \ + --rewrite-include '"(\.\./)?zstd_errors.h"=' \ + --sed 's,/\*\*\*,/* *,g' \ + --sed 's,/\*\*,/*,g' \ + --spdx \ + -DZSTD_NO_INTRINSICS \ + -DZSTD_NO_UNUSED_FUNCTIONS \ + -DZSTD_LEGACY_SUPPORT=0 \ + -DZSTD_STATIC_LINKING_ONLY \ + -DFSE_STATIC_LINKING_ONLY \ + -DXXH_STATIC_LINKING_ONLY \ + -D__GNUC__ \ + -D__linux__=1 \ + -DSTATIC_BMI2=0 \ + -DZSTD_ADDRESS_SANITIZER=0 \ + -DZSTD_MEMORY_SANITIZER=0 \ + -DZSTD_DATAFLOW_SANITIZER=0 \ + -DZSTD_COMPRESS_HEAPMODE=1 \ + -UNO_PREFETCH \ + -U__cplusplus \ + -UZSTD_DLL_EXPORT \ + -UZSTD_DLL_IMPORT \ + -U__ICCARM__ \ + -UZSTD_MULTITHREAD \ + -U_MSC_VER \ + -U_WIN32 \ + -RZSTDLIB_VISIBLE= \ + -RZSTDERRORLIB_VISIBLE= \ + -RZSTD_FALLTHROUGH=fallthrough \ + -DZSTD_HAVE_WEAK_SYMBOLS=0 \ + -DZSTD_TRACE=0 \ + -DZSTD_NO_TRACE \ + -DZSTD_DISABLE_ASM \ + -DZSTD_LINUX_KERNEL + rm linux/lib/zstd/decompress/huf_decompress_amd64.S + mv linux/lib/zstd/zstd.h linux/include/linux/zstd_lib.h + mv linux/lib/zstd/zstd_errors.h linux/include/linux/ + cp linux_zstd.h linux/include/linux/zstd.h + cp zstd_common_module.c linux/lib/zstd + cp zstd_compress_module.c linux/lib/zstd + cp zstd_decompress_module.c linux/lib/zstd + cp decompress_sources.h linux/lib/zstd + cp linux.mk linux/lib/zstd/Makefile + +LINUX ?= $(HOME)/repos/linux + +.PHONY: import +import: libzstd + rm -f $(LINUX)/include/linux/zstd.h + rm -f $(LINUX)/include/linux/zstd_errors.h + rm -rf $(LINUX)/lib/zstd + cp linux/include/linux/zstd.h $(LINUX)/include/linux + cp linux/include/linux/zstd_lib.h $(LINUX)/include/linux + cp linux/include/linux/zstd_errors.h $(LINUX)/include/linux + cp -r linux/lib/zstd $(LINUX)/lib + +import-upstream: + rm -rf $(LINUX)/lib/zstd + mkdir $(LINUX)/lib/zstd + cp ../../lib/zstd.h $(LINUX)/include/linux/zstd_lib.h + cp -r ../../lib/common $(LINUX)/lib/zstd + cp -r ../../lib/compress $(LINUX)/lib/zstd + cp -r ../../lib/decompress $(LINUX)/lib/zstd + mv $(LINUX)/lib/zstd/zstd_errors.h $(LINUX)/include/linux + rm $(LINUX)/lib/zstd/common/threading.* + rm $(LINUX)/lib/zstd/common/pool.* + rm $(LINUX)/lib/zstd/common/xxhash.* + rm $(LINUX)/lib/zstd/compress/zstdmt_* + +DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ + -Wstrict-prototypes -Wundef -Wpointer-arith \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls -Wmissing-prototypes -Wc++-compat \ + -Wimplicit-fallthrough + +.PHONY: test +test: libzstd + $(MAKE) -C test run-test CFLAGS="-O3 $(CFLAGS) $(DEBUGFLAGS) -Werror" -j + +.PHONY: clean +clean: + $(RM) -rf linux + $(MAKE) -C test clean diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/README.md b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/README.md new file mode 100644 index 000000000..bfa070d17 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/README.md @@ -0,0 +1,14 @@ +# Zstd in the Linux Kernel + +This directory contains the scripts needed to transform upstream zstd into the version imported into the kernel. All the transforms are automated and tested by our continuous integration. + +## Upgrading Zstd in the Linux Kernel + +1. `cd` into this directory. +2. Run `make libzstd` and read the output. Make sure that all the diffs printed and changes made by the script are correct. +3. Run `make test` and ensure that it passes. +4. Import zstd into the Linux Kernel `make import LINUX=/path/to/linux/repo` +5. Inspect the diff for sanity. +6. Check the Linux Kernel history for zstd. If any patches were made to the kernel version of zstd, but not to upstream zstd, then port them upstream if necessary. +7. Test the diff. Benchmark if necessary. Make sure to test multiple architectures: At least x86, i386, and arm. +8. Submit the patch to the LKML. diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/btrfs-benchmark.sh b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/btrfs-benchmark.sh new file mode 100755 index 000000000..5e28da9c6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/btrfs-benchmark.sh @@ -0,0 +1,104 @@ +# !/bin/sh +set -e + +# Benchmarks run on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM. +# The VM is running on a Macbook Pro with a 3.1 GHz Intel Core i7 processor and +# 16 GB of RAM and an SSD. + +# silesia is a directory that can be downloaded from +# http://mattmahoney.net/dc/silesia.html +# ls -l silesia/ +# total 203M +# -rwxr-xr-x 1 terrelln 9.8M Apr 12 2002 dickens +# -rwxr-xr-x 1 terrelln 49M May 31 2002 mozilla +# -rwxr-xr-x 1 terrelln 9.6M Mar 20 2003 mr +# -rwxr-xr-x 1 terrelln 32M Apr 2 2002 nci +# -rwxr-xr-x 1 terrelln 5.9M Jul 4 2002 ooffice +# -rwxr-xr-x 1 terrelln 9.7M Apr 11 2002 osdb +# -rwxr-xr-x 1 terrelln 6.4M Apr 2 2002 reymont +# -rwxr-xr-x 1 terrelln 21M Mar 25 2002 samba +# -rwxr-xr-x 1 terrelln 7.0M Mar 24 2002 sao +# -rwxr-xr-x 1 terrelln 40M Mar 25 2002 webster +# -rwxr-xr-x 1 terrelln 8.1M Apr 4 2002 x-ray +# -rwxr-xr-x 1 terrelln 5.1M Nov 30 2000 xml + +# $HOME is on a ext4 filesystem +BENCHMARK_DIR="$HOME/silesia/" +N=10 + +# Normalize the environment +sudo umount /mnt/btrfs 2> /dev/null > /dev/null || true +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs +sudo rm -rf /mnt/btrfs/* +sync +sudo umount /mnt/btrfs +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs + +# Run the benchmark +echo "Compression" +time sh -c "for i in \$(seq $N); do sudo cp -r $BENCHMARK_DIR /mnt/btrfs/\$i; done; sync" + +echo "Approximate compression ratio" +printf "%d / %d\n" \ + $(df /mnt/btrfs --output=used -B 1 | tail -n 1) \ + $(sudo du /mnt/btrfs -b -d 0 | tr '\t' '\n' | head -n 1); + +# Unmount and remount to avoid any caching +sudo umount /mnt/btrfs +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs + +echo "Decompression" +time sudo tar -c /mnt/btrfs 2> /dev/null | wc -c > /dev/null + +sudo rm -rf /mnt/btrfs/* +sudo umount /mnt/btrfs + +# Run for each of -o compress-force={none, lzo, zlib, zstd} 5 times and take the +# min time and ratio. +# Ran zstd with compression levels {1, 3, 6, 9, 12, 15}. +# Original size: 2119415342 B (using du /mnt/btrfs) + +# none +# compress: 4.205 s +# decompress: 3.090 s +# ratio: 0.99 + +# lzo +# compress: 5.328 s +# decompress: 4.793 s +# ratio: 1.66 + +# zlib +# compress: 32.588 s +# decompress: 8.791 s +# ratio : 2.58 + +# zstd 1 +# compress: 8.147 s +# decompress: 5.527 s +# ratio : 2.57 + +# zstd 3 +# compress: 12.207 s +# decompress: 5.195 s +# ratio : 2.71 + +# zstd 6 +# compress: 30.253 s +# decompress: 5.324 s +# ratio : 2.87 + +# zstd 9 +# compress: 49.659 s +# decompress: 5.220 s +# ratio : 2.92 + +# zstd 12 +# compress: 99.245 s +# decompress: 5.193 s +# ratio : 2.93 + +# zstd 15 +# compress: 196.997 s +# decompress: 5.992 s +# ratio : 3.01 diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/btrfs-extract-benchmark.sh b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/btrfs-extract-benchmark.sh new file mode 100755 index 000000000..69721d093 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/btrfs-extract-benchmark.sh @@ -0,0 +1,99 @@ +# !/bin/sh +set -e + +# Benchmarks run on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM. +# The VM is running on a Macbook Pro with a 3.1 GHz Intel Core i7 processor and +# 16 GB of RAM and an SSD. + +# silesia is a directory that can be downloaded from +# http://mattmahoney.net/dc/silesia.html +# ls -l silesia/ +# total 203M +# -rwxr-xr-x 1 terrelln 9.8M Apr 12 2002 dickens +# -rwxr-xr-x 1 terrelln 49M May 31 2002 mozilla +# -rwxr-xr-x 1 terrelln 9.6M Mar 20 2003 mr +# -rwxr-xr-x 1 terrelln 32M Apr 2 2002 nci +# -rwxr-xr-x 1 terrelln 5.9M Jul 4 2002 ooffice +# -rwxr-xr-x 1 terrelln 9.7M Apr 11 2002 osdb +# -rwxr-xr-x 1 terrelln 6.4M Apr 2 2002 reymont +# -rwxr-xr-x 1 terrelln 21M Mar 25 2002 samba +# -rwxr-xr-x 1 terrelln 7.0M Mar 24 2002 sao +# -rwxr-xr-x 1 terrelln 40M Mar 25 2002 webster +# -rwxr-xr-x 1 terrelln 8.1M Apr 4 2002 x-ray +# -rwxr-xr-x 1 terrelln 5.1M Nov 30 2000 xml + +# $HOME is on a ext4 filesystem +BENCHMARK_FILE="linux-4.11.6.tar" +BENCHMARK_DIR="$HOME/$BENCHMARK_FILE" + +# Normalize the environment +sudo umount /mnt/btrfs 2> /dev/null > /dev/null || true +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs +sudo rm -rf /mnt/btrfs/* +sync +sudo umount /mnt/btrfs +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs + +# Run the benchmark +echo "Copy" +time sh -c "sudo cp -r $BENCHMARK_DIR /mnt/btrfs/$BENCHMARK_FILE && sync" + +echo "Approximate tarred compression ratio" +printf "%d / %d\n" \ + $(df /mnt/btrfs --output=used -B 1 | tail -n 1) \ + $(sudo du /mnt/btrfs -b -d 0 | tr '\t' '\n' | head -n 1); + +# Unmount and remount to avoid any caching +sudo umount /mnt/btrfs +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs + +echo "Extract" +time sh -c "sudo tar -C /mnt/btrfs -xf /mnt/btrfs/$BENCHMARK_FILE && sync" + +# Remove the tarball, leaving only the extracted data +sudo rm /mnt/btrfs/$BENCHMARK_FILE +# Unmount and remount to avoid any caching +sudo umount /mnt/btrfs +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs + +echo "Approximate extracted compression ratio" +printf "%d / %d\n" \ + $(df /mnt/btrfs --output=used -B 1 | tail -n 1) \ + $(sudo du /mnt/btrfs -b -d 0 | tr '\t' '\n' | head -n 1); + +echo "Read" +time sudo tar -c /mnt/btrfs 2> /dev/null | wc -c > /dev/null + +sudo rm -rf /mnt/btrfs/* +sudo umount /mnt/btrfs + +# Run for each of -o compress-force={none, lzo, zlib, zstd} 5 times and take the +# min time and ratio. + +# none +# copy: 0.981 s +# extract: 5.501 s +# read: 8.807 s +# tarball ratio: 0.97 +# extracted ratio: 0.78 + +# lzo +# copy: 1.631 s +# extract: 8.458 s +# read: 8.585 s +# tarball ratio: 2.06 +# extracted ratio: 1.38 + +# zlib +# copy: 7.750 s +# extract: 21.544 s +# read: 11.744 s +# tarball ratio : 3.40 +# extracted ratio: 1.86 + +# zstd 1 +# copy: 2.579 s +# extract: 11.479 s +# read: 9.389 s +# tarball ratio : 3.57 +# extracted ratio: 1.85 diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/decompress_sources.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/decompress_sources.h new file mode 100644 index 000000000..8a47eb2a4 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/decompress_sources.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* + * This file includes every .c file needed for decompression. + * It is used by lib/decompress_unzstd.c to include the decompression + * source into the translation-unit, so it can be used for kernel + * decompression. + */ + +/* + * Disable the ASM Huffman implementation because we need to + * include all the sources. + */ +#define ZSTD_DISABLE_ASM 1 + +#include "common/debug.c" +#include "common/entropy_common.c" +#include "common/error_private.c" +#include "common/fse_decompress.c" +#include "common/zstd_common.c" +#include "decompress/huf_decompress.c" +#include "decompress/zstd_ddict.c" +#include "decompress/zstd_decompress.c" +#include "decompress/zstd_decompress_block.c" +#include "zstd_decompress_module.c" diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/linux.mk b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/linux.mk new file mode 100644 index 000000000..be218b5e0 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/linux.mk @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ +obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o +obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o +obj-$(CONFIG_ZSTD_COMMON) += zstd_common.o + +zstd_compress-y := \ + zstd_compress_module.o \ + compress/fse_compress.o \ + compress/hist.o \ + compress/huf_compress.o \ + compress/zstd_compress.o \ + compress/zstd_compress_literals.o \ + compress/zstd_compress_sequences.o \ + compress/zstd_compress_superblock.o \ + compress/zstd_double_fast.o \ + compress/zstd_fast.o \ + compress/zstd_lazy.o \ + compress/zstd_ldm.o \ + compress/zstd_opt.o \ + compress/zstd_preSplit.o \ + +zstd_decompress-y := \ + zstd_decompress_module.o \ + decompress/huf_decompress.o \ + decompress/zstd_ddict.o \ + decompress/zstd_decompress.o \ + decompress/zstd_decompress_block.o \ + +zstd_common-y := \ + zstd_common_module.o \ + common/debug.o \ + common/entropy_common.o \ + common/error_private.o \ + common/fse_decompress.o \ + common/zstd_common.o \ diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/linux_zstd.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/linux_zstd.h new file mode 100644 index 000000000..dda8a2d7d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/linux_zstd.h @@ -0,0 +1,525 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd) and + * the GPLv2 (found in the COPYING file in the root directory of + * https://github.com/facebook/zstd). You may select, at your option, one of the + * above-listed licenses. + */ + +#ifndef LINUX_ZSTD_H +#define LINUX_ZSTD_H + +/** + * This is a kernel-style API that wraps the upstream zstd API, which cannot be + * used directly because the symbols aren't exported. It exposes the minimal + * functionality which is currently required by users of zstd in the kernel. + * Expose extra functions from lib/zstd/zstd.h as needed. + */ + +/* ====== Dependency ====== */ +#include +#include +#include + +/* ====== Helper Functions ====== */ +/** + * zstd_compress_bound() - maximum compressed size in worst case scenario + * @src_size: The size of the data to compress. + * + * Return: The maximum compressed size in the worst case scenario. + */ +size_t zstd_compress_bound(size_t src_size); + +/** + * zstd_is_error() - tells if a size_t function result is an error code + * @code: The function result to check for error. + * + * Return: Non-zero iff the code is an error. + */ +unsigned int zstd_is_error(size_t code); + +/** + * enum zstd_error_code - zstd error codes + */ +typedef ZSTD_ErrorCode zstd_error_code; + +/** + * zstd_get_error_code() - translates an error function result to an error code + * @code: The function result for which zstd_is_error(code) is true. + * + * Return: A unique error code for this error. + */ +zstd_error_code zstd_get_error_code(size_t code); + +/** + * zstd_get_error_name() - translates an error function result to a string + * @code: The function result for which zstd_is_error(code) is true. + * + * Return: An error string corresponding to the error code. + */ +const char *zstd_get_error_name(size_t code); + +/** + * zstd_min_clevel() - minimum allowed compression level + * + * Return: The minimum allowed compression level. + */ +int zstd_min_clevel(void); + +/** + * zstd_max_clevel() - maximum allowed compression level + * + * Return: The maximum allowed compression level. + */ +int zstd_max_clevel(void); + +/* ====== Parameter Selection ====== */ + +/** + * enum zstd_strategy - zstd compression search strategy + * + * From faster to stronger. See zstd_lib.h. + */ +typedef ZSTD_strategy zstd_strategy; + +/** + * struct zstd_compression_parameters - zstd compression parameters + * @windowLog: Log of the largest match distance. Larger means more + * compression, and more memory needed during decompression. + * @chainLog: Fully searched segment. Larger means more compression, + * slower, and more memory (useless for fast). + * @hashLog: Dispatch table. Larger means more compression, + * slower, and more memory. + * @searchLog: Number of searches. Larger means more compression and slower. + * @searchLength: Match length searched. Larger means faster decompression, + * sometimes less compression. + * @targetLength: Acceptable match size for optimal parser (only). Larger means + * more compression, and slower. + * @strategy: The zstd compression strategy. + * + * See zstd_lib.h. + */ +typedef ZSTD_compressionParameters zstd_compression_parameters; + +/** + * struct zstd_frame_parameters - zstd frame parameters + * @contentSizeFlag: Controls whether content size will be present in the + * frame header (when known). + * @checksumFlag: Controls whether a 32-bit checksum is generated at the + * end of the frame for error detection. + * @noDictIDFlag: Controls whether dictID will be saved into the frame + * header when using dictionary compression. + * + * The default value is all fields set to 0. See zstd_lib.h. + */ +typedef ZSTD_frameParameters zstd_frame_parameters; + +/** + * struct zstd_parameters - zstd parameters + * @cParams: The compression parameters. + * @fParams: The frame parameters. + */ +typedef ZSTD_parameters zstd_parameters; + +/** + * zstd_get_params() - returns zstd_parameters for selected level + * @level: The compression level + * @estimated_src_size: The estimated source size to compress or 0 + * if unknown. + * + * Return: The selected zstd_parameters. + */ +zstd_parameters zstd_get_params(int level, + unsigned long long estimated_src_size); + +typedef ZSTD_CCtx zstd_cctx; +typedef ZSTD_cParameter zstd_cparameter; + +/** + * zstd_cctx_set_param() - sets a compression parameter + * @cctx: The context. Must have been initialized with zstd_init_cctx(). + * @param: The parameter to set. + * @value: The value to set the parameter to. + * + * Return: Zero or an error, which can be checked using zstd_is_error(). + */ +size_t zstd_cctx_set_param(zstd_cctx *cctx, zstd_cparameter param, int value); + +/* ====== Single-pass Compression ====== */ + +/** + * zstd_cctx_workspace_bound() - max memory needed to initialize a zstd_cctx + * @parameters: The compression parameters to be used. + * + * If multiple compression parameters might be used, the caller must call + * zstd_cctx_workspace_bound() for each set of parameters and use the maximum + * size. + * + * Return: A lower bound on the size of the workspace that is passed to + * zstd_init_cctx(). + */ +size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *parameters); + +/** + * zstd_cctx_workspace_bound_with_ext_seq_prod() - max memory needed to + * initialize a zstd_cctx when using the block-level external sequence + * producer API. + * @parameters: The compression parameters to be used. + * + * If multiple compression parameters might be used, the caller must call + * this function for each set of parameters and use the maximum size. + * + * Return: A lower bound on the size of the workspace that is passed to + * zstd_init_cctx(). + */ +size_t zstd_cctx_workspace_bound_with_ext_seq_prod(const zstd_compression_parameters *parameters); + +/** + * zstd_init_cctx() - initialize a zstd compression context + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspace_size: The size of workspace. Use zstd_cctx_workspace_bound() to + * determine how large the workspace must be. + * + * Return: A zstd compression context or NULL on error. + */ +zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size); + +/** + * zstd_compress_cctx() - compress src into dst with the initialized parameters + * @cctx: The context. Must have been initialized with zstd_init_cctx(). + * @dst: The buffer to compress src into. + * @dst_capacity: The size of the destination buffer. May be any size, but + * ZSTD_compressBound(srcSize) is guaranteed to be large enough. + * @src: The data to compress. + * @src_size: The size of the data to compress. + * @parameters: The compression parameters to be used. + * + * Return: The compressed size or an error, which can be checked using + * zstd_is_error(). + */ +size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity, + const void *src, size_t src_size, const zstd_parameters *parameters); + +/* ====== Single-pass Decompression ====== */ + +typedef ZSTD_DCtx zstd_dctx; + +/** + * zstd_dctx_workspace_bound() - max memory needed to initialize a zstd_dctx + * + * Return: A lower bound on the size of the workspace that is passed to + * zstd_init_dctx(). + */ +size_t zstd_dctx_workspace_bound(void); + +/** + * zstd_init_dctx() - initialize a zstd decompression context + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspace_size: The size of workspace. Use zstd_dctx_workspace_bound() to + * determine how large the workspace must be. + * + * Return: A zstd decompression context or NULL on error. + */ +zstd_dctx *zstd_init_dctx(void *workspace, size_t workspace_size); + +/** + * zstd_decompress_dctx() - decompress zstd compressed src into dst + * @dctx: The decompression context. + * @dst: The buffer to decompress src into. + * @dst_capacity: The size of the destination buffer. Must be at least as large + * as the decompressed size. If the caller cannot upper bound the + * decompressed size, then it's better to use the streaming API. + * @src: The zstd compressed data to decompress. Multiple concatenated + * frames and skippable frames are allowed. + * @src_size: The exact size of the data to decompress. + * + * Return: The decompressed size or an error, which can be checked using + * zstd_is_error(). + */ +size_t zstd_decompress_dctx(zstd_dctx *dctx, void *dst, size_t dst_capacity, + const void *src, size_t src_size); + +/* ====== Streaming Buffers ====== */ + +/** + * struct zstd_in_buffer - input buffer for streaming + * @src: Start of the input buffer. + * @size: Size of the input buffer. + * @pos: Position where reading stopped. Will be updated. + * Necessarily 0 <= pos <= size. + * + * See zstd_lib.h. + */ +typedef ZSTD_inBuffer zstd_in_buffer; + +/** + * struct zstd_out_buffer - output buffer for streaming + * @dst: Start of the output buffer. + * @size: Size of the output buffer. + * @pos: Position where writing stopped. Will be updated. + * Necessarily 0 <= pos <= size. + * + * See zstd_lib.h. + */ +typedef ZSTD_outBuffer zstd_out_buffer; + +/* ====== Streaming Compression ====== */ + +typedef ZSTD_CStream zstd_cstream; + +/** + * zstd_cstream_workspace_bound() - memory needed to initialize a zstd_cstream + * @cparams: The compression parameters to be used for compression. + * + * Return: A lower bound on the size of the workspace that is passed to + * zstd_init_cstream(). + */ +size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams); + +/** + * zstd_cstream_workspace_bound_with_ext_seq_prod() - memory needed to initialize + * a zstd_cstream when using the block-level external sequence producer API. + * @cparams: The compression parameters to be used for compression. + * + * Return: A lower bound on the size of the workspace that is passed to + * zstd_init_cstream(). + */ +size_t zstd_cstream_workspace_bound_with_ext_seq_prod(const zstd_compression_parameters *cparams); + +/** + * zstd_init_cstream() - initialize a zstd streaming compression context + * @parameters The zstd parameters to use for compression. + * @pledged_src_size: If params.fParams.contentSizeFlag == 1 then the caller + * must pass the source size (zero means empty source). + * Otherwise, the caller may optionally pass the source + * size, or zero if unknown. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspace_size: The size of workspace. + * Use zstd_cstream_workspace_bound(params->cparams) to + * determine how large the workspace must be. + * + * Return: The zstd streaming compression context or NULL on error. + */ +zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters, + unsigned long long pledged_src_size, void *workspace, size_t workspace_size); + +/** + * zstd_reset_cstream() - reset the context using parameters from creation + * @cstream: The zstd streaming compression context to reset. + * @pledged_src_size: Optionally the source size, or zero if unknown. + * + * Resets the context using the parameters from creation. Skips dictionary + * loading, since it can be reused. If `pledged_src_size` is non-zero the frame + * content size is always written into the frame header. + * + * Return: Zero or an error, which can be checked using + * zstd_is_error(). + */ +size_t zstd_reset_cstream(zstd_cstream *cstream, + unsigned long long pledged_src_size); + +/** + * zstd_compress_stream() - streaming compress some of input into output + * @cstream: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * @input: Source buffer. `input->pos` is updated to indicate how much data + * was read. Note that it may not consume the entire input, in which + * case `input->pos < input->size`, and it's up to the caller to + * present remaining data again. + * + * The `input` and `output` buffers may be any size. Guaranteed to make some + * forward progress if `input` and `output` are not empty. + * + * Return: A hint for the number of bytes to use as the input for the next + * function call or an error, which can be checked using + * zstd_is_error(). + */ +size_t zstd_compress_stream(zstd_cstream *cstream, zstd_out_buffer *output, + zstd_in_buffer *input); + +/** + * zstd_flush_stream() - flush internal buffers into output + * @cstream: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * + * zstd_flush_stream() must be called until it returns 0, meaning all the data + * has been flushed. Since zstd_flush_stream() causes a block to be ended, + * calling it too often will degrade the compression ratio. + * + * Return: The number of bytes still present within internal buffers or an + * error, which can be checked using zstd_is_error(). + */ +size_t zstd_flush_stream(zstd_cstream *cstream, zstd_out_buffer *output); + +/** + * zstd_end_stream() - flush internal buffers into output and end the frame + * @cstream: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * + * zstd_end_stream() must be called until it returns 0, meaning all the data has + * been flushed and the frame epilogue has been written. + * + * Return: The number of bytes still present within internal buffers or an + * error, which can be checked using zstd_is_error(). + */ +size_t zstd_end_stream(zstd_cstream *cstream, zstd_out_buffer *output); + +/* ====== Streaming Decompression ====== */ + +typedef ZSTD_DStream zstd_dstream; + +/** + * zstd_dstream_workspace_bound() - memory needed to initialize a zstd_dstream + * @max_window_size: The maximum window size allowed for compressed frames. + * + * Return: A lower bound on the size of the workspace that is passed + * to zstd_init_dstream(). + */ +size_t zstd_dstream_workspace_bound(size_t max_window_size); + +/** + * zstd_init_dstream() - initialize a zstd streaming decompression context + * @max_window_size: The maximum window size allowed for compressed frames. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. + * Use zstd_dstream_workspace_bound(max_window_size) to + * determine how large the workspace must be. + * + * Return: The zstd streaming decompression context. + */ +zstd_dstream *zstd_init_dstream(size_t max_window_size, void *workspace, + size_t workspace_size); + +/** + * zstd_reset_dstream() - reset the context using parameters from creation + * @dstream: The zstd streaming decompression context to reset. + * + * Resets the context using the parameters from creation. Skips dictionary + * loading, since it can be reused. + * + * Return: Zero or an error, which can be checked using zstd_is_error(). + */ +size_t zstd_reset_dstream(zstd_dstream *dstream); + +/** + * zstd_decompress_stream() - streaming decompress some of input into output + * @dstream: The zstd streaming decompression context. + * @output: Destination buffer. `output.pos` is updated to indicate how much + * decompressed data was written. + * @input: Source buffer. `input.pos` is updated to indicate how much data was + * read. Note that it may not consume the entire input, in which case + * `input.pos < input.size`, and it's up to the caller to present + * remaining data again. + * + * The `input` and `output` buffers may be any size. Guaranteed to make some + * forward progress if `input` and `output` are not empty. + * zstd_decompress_stream() will not consume the last byte of the frame until + * the entire frame is flushed. + * + * Return: Returns 0 iff a frame is completely decoded and fully flushed. + * Otherwise returns a hint for the number of bytes to use as the + * input for the next function call or an error, which can be checked + * using zstd_is_error(). The size hint will never load more than the + * frame. + */ +size_t zstd_decompress_stream(zstd_dstream *dstream, zstd_out_buffer *output, + zstd_in_buffer *input); + +/* ====== Frame Inspection Functions ====== */ + +/** + * zstd_find_frame_compressed_size() - returns the size of a compressed frame + * @src: Source buffer. It should point to the start of a zstd encoded + * frame or a skippable frame. + * @src_size: The size of the source buffer. It must be at least as large as the + * size of the frame. + * + * Return: The compressed size of the frame pointed to by `src` or an error, + * which can be check with zstd_is_error(). + * Suitable to pass to ZSTD_decompress() or similar functions. + */ +size_t zstd_find_frame_compressed_size(const void *src, size_t src_size); + +/** + * zstd_register_sequence_producer() - exposes the zstd library function + * ZSTD_registerSequenceProducer(). This is used for the block-level external + * sequence producer API. See upstream zstd.h for detailed documentation. + */ +typedef ZSTD_sequenceProducer_F zstd_sequence_producer_f; +void zstd_register_sequence_producer( + zstd_cctx *cctx, + void* sequence_producer_state, + zstd_sequence_producer_f sequence_producer +); + +/** + * struct zstd_frame_params - zstd frame parameters stored in the frame header + * @frameContentSize: The frame content size, or ZSTD_CONTENTSIZE_UNKNOWN if not + * present. + * @windowSize: The window size, or 0 if the frame is a skippable frame. + * @blockSizeMax: The maximum block size. + * @frameType: The frame type (zstd or skippable) + * @headerSize: The size of the frame header. + * @dictID: The dictionary id, or 0 if not present. + * @checksumFlag: Whether a checksum was used. + * + * See zstd_lib.h. + */ +typedef ZSTD_FrameHeader zstd_frame_header; + +/** + * zstd_get_frame_header() - extracts parameters from a zstd or skippable frame + * @params: On success the frame parameters are written here. + * @src: The source buffer. It must point to a zstd or skippable frame. + * @src_size: The size of the source buffer. + * + * Return: 0 on success. If more data is required it returns how many bytes + * must be provided to make forward progress. Otherwise it returns + * an error, which can be checked using zstd_is_error(). + */ +size_t zstd_get_frame_header(zstd_frame_header *params, const void *src, + size_t src_size); + +/** + * struct zstd_sequence - a sequence of literals or a match + * + * @offset: The offset of the match + * @litLength: The literal length of the sequence + * @matchLength: The match length of the sequence + * @rep: Represents which repeat offset is used + */ +typedef ZSTD_Sequence zstd_sequence; + +/** + * zstd_compress_sequences_and_literals() - compress an array of zstd_sequence and literals + * + * @cctx: The zstd compression context. + * @dst: The buffer to compress the data into. + * @dst_capacity: The size of the destination buffer. + * @in_seqs: The array of zstd_sequence to compress. + * @in_seqs_size: The number of sequences in in_seqs. + * @literals: The literals associated to the sequences to be compressed. + * @lit_size: The size of the literals in the literals buffer. + * @lit_capacity: The size of the literals buffer. + * @decompressed_size: The size of the input data + * + * Return: The compressed size or an error, which can be checked using + * zstd_is_error(). + */ +size_t zstd_compress_sequences_and_literals(zstd_cctx *cctx, void* dst, size_t dst_capacity, + const zstd_sequence *in_seqs, size_t in_seqs_size, + const void* literals, size_t lit_size, size_t lit_capacity, + size_t decompressed_size); + +#endif /* LINUX_ZSTD_H */ diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/mem.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/mem.h new file mode 100644 index 000000000..d9bd752fe --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/mem.h @@ -0,0 +1,262 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef MEM_H_MODULE +#define MEM_H_MODULE + +/*-**************************************** +* Dependencies +******************************************/ +#include /* get_unaligned, put_unaligned* */ +#include /* inline */ +#include /* swab32, swab64 */ +#include /* size_t, ptrdiff_t */ +#include "debug.h" /* DEBUG_STATIC_ASSERT */ + +/*-**************************************** +* Compiler specifics +******************************************/ +#undef MEM_STATIC /* may be already defined from common/compiler.h */ +#define MEM_STATIC static inline + +/*-************************************************************** +* Basic Types +*****************************************************************/ +typedef uint8_t BYTE; +typedef uint8_t U8; +typedef int8_t S8; +typedef uint16_t U16; +typedef int16_t S16; +typedef uint32_t U32; +typedef int32_t S32; +typedef uint64_t U64; +typedef int64_t S64; + +/*-************************************************************** +* Memory I/O API +*****************************************************************/ +/*=== Static platform detection ===*/ +MEM_STATIC unsigned MEM_32bits(void); +MEM_STATIC unsigned MEM_64bits(void); +MEM_STATIC unsigned MEM_isLittleEndian(void); + +/*=== Native unaligned read/write ===*/ +MEM_STATIC U16 MEM_read16(const void* memPtr); +MEM_STATIC U32 MEM_read32(const void* memPtr); +MEM_STATIC U64 MEM_read64(const void* memPtr); +MEM_STATIC size_t MEM_readST(const void* memPtr); + +MEM_STATIC void MEM_write16(void* memPtr, U16 value); +MEM_STATIC void MEM_write32(void* memPtr, U32 value); +MEM_STATIC void MEM_write64(void* memPtr, U64 value); + +/*=== Little endian unaligned read/write ===*/ +MEM_STATIC U16 MEM_readLE16(const void* memPtr); +MEM_STATIC U32 MEM_readLE24(const void* memPtr); +MEM_STATIC U32 MEM_readLE32(const void* memPtr); +MEM_STATIC U64 MEM_readLE64(const void* memPtr); +MEM_STATIC size_t MEM_readLEST(const void* memPtr); + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val); +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val); +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val); + +/*=== Big endian unaligned read/write ===*/ +MEM_STATIC U32 MEM_readBE32(const void* memPtr); +MEM_STATIC U64 MEM_readBE64(const void* memPtr); +MEM_STATIC size_t MEM_readBEST(const void* memPtr); + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val); + +/*=== Byteswap ===*/ +MEM_STATIC U32 MEM_swap32(U32 in); +MEM_STATIC U64 MEM_swap64(U64 in); +MEM_STATIC size_t MEM_swapST(size_t in); + +/*-************************************************************** +* Memory I/O Implementation +*****************************************************************/ +MEM_STATIC unsigned MEM_32bits(void) +{ + return sizeof(size_t) == 4; +} + +MEM_STATIC unsigned MEM_64bits(void) +{ + return sizeof(size_t) == 8; +} + +#if defined(__LITTLE_ENDIAN) +#define MEM_LITTLE_ENDIAN 1 +#else +#define MEM_LITTLE_ENDIAN 0 +#endif + +MEM_STATIC unsigned MEM_isLittleEndian(void) +{ + return MEM_LITTLE_ENDIAN; +} + +MEM_STATIC U16 MEM_read16(const void *memPtr) +{ + return get_unaligned((const U16 *)memPtr); +} + +MEM_STATIC U32 MEM_read32(const void *memPtr) +{ + return get_unaligned((const U32 *)memPtr); +} + +MEM_STATIC U64 MEM_read64(const void *memPtr) +{ + return get_unaligned((const U64 *)memPtr); +} + +MEM_STATIC size_t MEM_readST(const void *memPtr) +{ + return get_unaligned((const size_t *)memPtr); +} + +MEM_STATIC void MEM_write16(void *memPtr, U16 value) +{ + put_unaligned(value, (U16 *)memPtr); +} + +MEM_STATIC void MEM_write32(void *memPtr, U32 value) +{ + put_unaligned(value, (U32 *)memPtr); +} + +MEM_STATIC void MEM_write64(void *memPtr, U64 value) +{ + put_unaligned(value, (U64 *)memPtr); +} + +/*=== Little endian r/w ===*/ + +MEM_STATIC U16 MEM_readLE16(const void *memPtr) +{ + return get_unaligned_le16(memPtr); +} + +MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val) +{ + put_unaligned_le16(val, memPtr); +} + +MEM_STATIC U32 MEM_readLE24(const void *memPtr) +{ + return MEM_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16); +} + +MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val) +{ + MEM_writeLE16(memPtr, (U16)val); + ((BYTE *)memPtr)[2] = (BYTE)(val >> 16); +} + +MEM_STATIC U32 MEM_readLE32(const void *memPtr) +{ + return get_unaligned_le32(memPtr); +} + +MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32) +{ + put_unaligned_le32(val32, memPtr); +} + +MEM_STATIC U64 MEM_readLE64(const void *memPtr) +{ + return get_unaligned_le64(memPtr); +} + +MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64) +{ + put_unaligned_le64(val64, memPtr); +} + +MEM_STATIC size_t MEM_readLEST(const void *memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readLE32(memPtr); + else + return (size_t)MEM_readLE64(memPtr); +} + +MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeLE32(memPtr, (U32)val); + else + MEM_writeLE64(memPtr, (U64)val); +} + +/*=== Big endian r/w ===*/ + +MEM_STATIC U32 MEM_readBE32(const void *memPtr) +{ + return get_unaligned_be32(memPtr); +} + +MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32) +{ + put_unaligned_be32(val32, memPtr); +} + +MEM_STATIC U64 MEM_readBE64(const void *memPtr) +{ + return get_unaligned_be64(memPtr); +} + +MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64) +{ + put_unaligned_be64(val64, memPtr); +} + +MEM_STATIC size_t MEM_readBEST(const void *memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readBE32(memPtr); + else + return (size_t)MEM_readBE64(memPtr); +} + +MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeBE32(memPtr, (U32)val); + else + MEM_writeBE64(memPtr, (U64)val); +} + +MEM_STATIC U32 MEM_swap32(U32 in) +{ + return swab32(in); +} + +MEM_STATIC U64 MEM_swap64(U64 in) +{ + return swab64(in); +} + +MEM_STATIC size_t MEM_swapST(size_t in) +{ + if (MEM_32bits()) + return (size_t)MEM_swap32((U32)in); + else + return (size_t)MEM_swap64((U64)in); +} + +#endif /* MEM_H_MODULE */ diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/squashfs-benchmark.sh b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/squashfs-benchmark.sh new file mode 100755 index 000000000..02dfd7325 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/squashfs-benchmark.sh @@ -0,0 +1,39 @@ +# !/bin/sh +set -e + +# Benchmarks run on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM. +# The VM is running on a Macbook Pro with a 3.1 GHz Intel Core i7 processor and +# 16 GB of RAM and an SSD. + +# $BENCHMARK_DIR is generated with the following commands, from the Ubuntu image +# ubuntu-16.10-desktop-amd64.iso. +# > mkdir mnt +# > sudo mount -o loop ubuntu-16.10-desktop-amd64.iso mnt +# > cp mnt/casper/filesystem.squashfs . +# > sudo unsquashfs filesystem.squashfs + +# $HOME is on a ext4 filesystem +BENCHMARK_DIR="$HOME/squashfs-root/" +BENCHMARK_FS="$HOME/filesystem.squashfs" + +# Normalize the environment +sudo rm -f $BENCHMARK_FS 2> /dev/null > /dev/null || true +sudo umount /mnt/squashfs 2> /dev/null > /dev/null || true + +# Run the benchmark +echo "Compression" +echo "sudo mksquashfs $BENCHMARK_DIR $BENCHMARK_FS $@" +time sudo mksquashfs $BENCHMARK_DIR $BENCHMARK_FS $@ 2> /dev/null > /dev/null + +echo "Approximate compression ratio" +printf "%d / %d\n" \ + $(sudo du -sx --block-size=1 $BENCHMARK_DIR | cut -f1) \ + $(sudo du -sx --block-size=1 $BENCHMARK_FS | cut -f1); + +# Mount the filesystem +sudo mount -t squashfs $BENCHMARK_FS /mnt/squashfs + +echo "Decompression" +time sudo tar -c /mnt/squashfs 2> /dev/null | wc -c > /dev/null + +sudo umount /mnt/squashfs diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/Makefile b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/Makefile new file mode 100644 index 000000000..67b55e665 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/Makefile @@ -0,0 +1,49 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ + +LINUX := ../linux +LINUX_ZSTDLIB := $(LINUX)/lib/zstd + +CPPFLAGS += -I$(LINUX)/include -I$(LINUX_ZSTDLIB) -Iinclude -DNDEBUG -Wno-deprecated-declarations +# Don't poison the workspace, it currently doesn't work with static allocation and workspace reuse +CPPFLAGS += -DZSTD_ASAN_DONT_POISON_WORKSPACE + +LINUX_ZSTD_MODULE := $(wildcard $(LINUX_ZSTDLIB)/*.c) +LINUX_ZSTD_COMMON := $(wildcard $(LINUX_ZSTDLIB)/common/*.c) +LINUX_ZSTD_COMPRESS := $(wildcard $(LINUX_ZSTDLIB)/compress/*.c) +LINUX_ZSTD_DECOMPRESS := $(wildcard $(LINUX_ZSTDLIB)/decompress/*.c $(LINUX_ZSTDLIB)/decompress/*.S) +LINUX_ZSTD_FILES := $(LINUX_ZSTD_MODULE) $(LINUX_ZSTD_COMMON) $(LINUX_ZSTD_COMPRESS) $(LINUX_ZSTD_DECOMPRESS) +LINUX_ZSTD_OBJECTS0 := $(LINUX_ZSTD_FILES:.c=.o) +LINUX_ZSTD_OBJECTS := $(LINUX_ZSTD_OBJECTS0:.S=.o) + +%.o: %.S + $(COMPILE.S) $(OUTPUT_OPTION) $< + +liblinuxzstd.a: $(LINUX_ZSTD_OBJECTS) + $(AR) $(ARFLAGS) $@ $^ + +test: test.c liblinuxzstd.a + $(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $^ -o $@ + +static_test: static_test.c + $(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $^ -o $@ + +run-test: test static_test + ./macro-test.sh + ./test + ./static_test + +.PHONY: +clean: + $(RM) -f $(LINUX_ZSTDLIB)/*.o + $(RM) -f $(LINUX_ZSTDLIB)/**/*.o + $(RM) -f *.o *.a + $(RM) -f static_test + $(RM) -f test diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/compiler.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/compiler.h new file mode 100644 index 000000000..988ce4a20 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/compiler.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_COMPILER_H +#define LINUX_COMPILER_H + +#ifndef inline +#define inline __inline __attribute__((unused)) +#endif + +#ifndef noinline +#define noinline __attribute__((noinline)) +#endif + +#define fallthrough __attribute__((__fallthrough__)) + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/errno.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/errno.h new file mode 100644 index 000000000..b4bdcba0e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/errno.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_ERRNO_H +#define LINUX_ERRNO_H + +#define EINVAL 22 + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/kernel.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/kernel.h new file mode 100644 index 000000000..a4d791cd1 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/kernel.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_KERNEL_H +#define LINUX_KERNEL_H + +#define WARN_ON(x) + +#define PTR_ALIGN(p, a) (typeof(p))ALIGN((unsigned long long)(p), (a)) +#define ALIGN(x, a) ALIGN_MASK((x), (a) - 1) +#define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/limits.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/limits.h new file mode 100644 index 000000000..574aa7b34 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/limits.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_LIMITS_H +#define LINUX_LIMITS_H + +#include + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/math64.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/math64.h new file mode 100644 index 000000000..7f6713e73 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/math64.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_MATH64_H +#define LINUX_MATH64_H + +#define div_u64(dividend, divisor) ((dividend) / (divisor)) + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/module.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/module.h new file mode 100644 index 000000000..06ef56f9e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/module.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_MODULE_H +#define LINUX_MODULE_H + +#define EXPORT_SYMBOL(symbol) \ + void* __##symbol = symbol +#define EXPORT_SYMBOL_GPL(symbol) \ + void* __##symbol = symbol +#define MODULE_LICENSE(license) +#define MODULE_DESCRIPTION(description) + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/printk.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/printk.h new file mode 100644 index 000000000..92a25278e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/printk.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_PRINTK_H +#define LINUX_PRINTK_H + +#define pr_debug(...) + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/stddef.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/stddef.h new file mode 100644 index 000000000..15c7408fc --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/stddef.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_STDDEF_H +#define LINUX_STDDEF_H + +#include + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/swab.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/swab.h new file mode 100644 index 000000000..2b48b434c --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/swab.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_SWAB_H +#define LINUX_SWAB_H + +#define swab32(x) __builtin_bswap32((x)) +#define swab64(x) __builtin_bswap64((x)) + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/types.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/types.h new file mode 100644 index 000000000..b413db6f9 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/types.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#ifndef LINUX_TYPES_H +#define LINUX_TYPES_H + +#include +#include + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/unaligned.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/unaligned.h new file mode 100644 index 000000000..86ec4ca38 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/unaligned.h @@ -0,0 +1,187 @@ +#ifndef ASM_UNALIGNED_H +#define ASM_UNALIGNED_H + +#include +#include + +#ifndef __LITTLE_ENDIAN +# if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN__) +# define __LITTLE_ENDIAN 1 +# endif +#endif + +#ifdef __LITTLE_ENDIAN +# define _IS_LITTLE_ENDIAN 1 +#else +# define _IS_LITTLE_ENDIAN 0 +#endif + +static unsigned _isLittleEndian(void) +{ + const union { uint32_t u; uint8_t c[4]; } one = { 1 }; + assert(_IS_LITTLE_ENDIAN == one.c[0]); + (void)one; + return _IS_LITTLE_ENDIAN; +} + +static uint16_t _swap16(uint16_t in) +{ + return ((in & 0xF) << 8) + ((in & 0xF0) >> 8); +} + +static uint32_t _swap32(uint32_t in) +{ + return __builtin_bswap32(in); +} + +static uint64_t _swap64(uint64_t in) +{ + return __builtin_bswap64(in); +} + +/* Little endian */ +static uint16_t get_unaligned_le16(const void* memPtr) +{ + uint16_t val; + __builtin_memcpy(&val, memPtr, sizeof(val)); + if (!_isLittleEndian()) _swap16(val); + return val; +} + +static uint32_t get_unaligned_le32(const void* memPtr) +{ + uint32_t val; + __builtin_memcpy(&val, memPtr, sizeof(val)); + if (!_isLittleEndian()) _swap32(val); + return val; +} + +static uint64_t get_unaligned_le64(const void* memPtr) +{ + uint64_t val; + __builtin_memcpy(&val, memPtr, sizeof(val)); + if (!_isLittleEndian()) _swap64(val); + return val; +} + +static void put_unaligned_le16(uint16_t value, void* memPtr) +{ + if (!_isLittleEndian()) value = _swap16(value); + __builtin_memcpy(memPtr, &value, sizeof(value)); +} + +static void put_unaligned_le32(uint32_t value, void* memPtr) +{ + if (!_isLittleEndian()) value = _swap32(value); + __builtin_memcpy(memPtr, &value, sizeof(value)); +} + +static void put_unaligned_le64(uint64_t value, void* memPtr) +{ + if (!_isLittleEndian()) value = _swap64(value); + __builtin_memcpy(memPtr, &value, sizeof(value)); +} + +/* big endian */ +static uint32_t get_unaligned_be32(const void* memPtr) +{ + uint32_t val; + __builtin_memcpy(&val, memPtr, sizeof(val)); + if (_isLittleEndian()) _swap32(val); + return val; +} + +static uint64_t get_unaligned_be64(const void* memPtr) +{ + uint64_t val; + __builtin_memcpy(&val, memPtr, sizeof(val)); + if (_isLittleEndian()) _swap64(val); + return val; +} + +static void put_unaligned_be32(uint32_t value, void* memPtr) +{ + if (_isLittleEndian()) value = _swap32(value); + __builtin_memcpy(memPtr, &value, sizeof(value)); +} + +static void put_unaligned_be64(uint64_t value, void* memPtr) +{ + if (_isLittleEndian()) value = _swap64(value); + __builtin_memcpy(memPtr, &value, sizeof(value)); +} + +/* generic */ +extern void __bad_unaligned_access_size(void); + +#define __get_unaligned_le(ptr) ((typeof(*(ptr)))({ \ + __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \ + __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \ + __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \ + __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \ + __bad_unaligned_access_size())))); \ + })) + +#define __get_unaligned_be(ptr) ((typeof(*(ptr)))({ \ + __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \ + __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \ + __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \ + __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \ + __bad_unaligned_access_size())))); \ + })) + +#define __put_unaligned_le(val, ptr) \ + ({ \ + void *__gu_p = (ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + *(uint8_t *)__gu_p = (uint8_t)(val); \ + break; \ + case 2: \ + put_unaligned_le16((uint16_t)(val), __gu_p); \ + break; \ + case 4: \ + put_unaligned_le32((uint32_t)(val), __gu_p); \ + break; \ + case 8: \ + put_unaligned_le64((uint64_t)(val), __gu_p); \ + break; \ + default: \ + __bad_unaligned_access_size(); \ + break; \ + } \ + (void)0; \ + }) + +#define __put_unaligned_be(val, ptr) \ + ({ \ + void *__gu_p = (ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + *(uint8_t *)__gu_p = (uint8_t)(val); \ + break; \ + case 2: \ + put_unaligned_be16((uint16_t)(val), __gu_p); \ + break; \ + case 4: \ + put_unaligned_be32((uint32_t)(val), __gu_p); \ + break; \ + case 8: \ + put_unaligned_be64((uint64_t)(val), __gu_p); \ + break; \ + default: \ + __bad_unaligned_access_size(); \ + break; \ + } \ + (void)0; \ + }) + +#if _IS_LITTLE_ENDIAN +# define get_unaligned __get_unaligned_le +# define put_unaligned __put_unaligned_le +#else +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be +#endif + +#endif // ASM_UNALIGNED_H diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/xxhash.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/xxhash.h new file mode 100644 index 000000000..f993eb9ee --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/include/linux/xxhash.h @@ -0,0 +1,745 @@ +/* + * xxHash - Extremely Fast Hash algorithm + * Copyright (C) 2012-2016, Yann Collet. + * + * BSD 2-Clause License (https://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. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at: + * - xxHash homepage: https://cyan4973.github.io/xxHash/ + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ + +/* + * Notice extracted from xxHash homepage: + * + * xxHash is an extremely fast Hash algorithm, running at RAM speed limits. + * It also successfully passes all tests from the SMHasher suite. + * + * Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 + * Duo @3GHz) + * + * Name Speed Q.Score Author + * xxHash 5.4 GB/s 10 + * CrapWow 3.2 GB/s 2 Andrew + * MumurHash 3a 2.7 GB/s 10 Austin Appleby + * SpookyHash 2.0 GB/s 10 Bob Jenkins + * SBox 1.4 GB/s 9 Bret Mulvey + * Lookup3 1.2 GB/s 9 Bob Jenkins + * SuperFastHash 1.2 GB/s 1 Paul Hsieh + * CityHash64 1.05 GB/s 10 Pike & Alakuijala + * FNV 0.55 GB/s 5 Fowler, Noll, Vo + * CRC32 0.43 GB/s 9 + * MD5-32 0.33 GB/s 10 Ronald L. Rivest + * SHA1-32 0.28 GB/s 10 + * + * Q.Score is a measure of quality of the hash function. + * It depends on successfully passing SMHasher test set. + * 10 is a perfect score. + * + * A 64-bits version, named xxh64 offers much better speed, + * but for 64-bits applications only. + * Name Speed on 64 bits Speed on 32 bits + * xxh64 13.8 GB/s 1.9 GB/s + * xxh32 6.8 GB/s 6.0 GB/s + */ + +#ifndef XXHASH_H +#define XXHASH_H + +#include + +#define XXH_API static inline __attribute__((unused)) +/*-**************************** + * Simple Hash Functions + *****************************/ + +/** + * xxh32() - calculate the 32-bit hash of the input with a given seed. + * + * @input: The data to hash. + * @length: The length of the data to hash. + * @seed: The seed can be used to alter the result predictably. + * + * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s + * + * Return: The 32-bit hash of the data. + */ +XXH_API uint32_t xxh32(const void *input, size_t length, uint32_t seed); + +/** + * xxh64() - calculate the 64-bit hash of the input with a given seed. + * + * @input: The data to hash. + * @length: The length of the data to hash. + * @seed: The seed can be used to alter the result predictably. + * + * This function runs 2x faster on 64-bit systems, but slower on 32-bit systems. + * + * Return: The 64-bit hash of the data. + */ +XXH_API uint64_t xxh64(const void *input, size_t length, uint64_t seed); + +/** + * xxhash() - calculate wordsize hash of the input with a given seed + * @input: The data to hash. + * @length: The length of the data to hash. + * @seed: The seed can be used to alter the result predictably. + * + * If the hash does not need to be comparable between machines with + * different word sizes, this function will call whichever of xxh32() + * or xxh64() is faster. + * + * Return: wordsize hash of the data. + */ + +static inline unsigned long xxhash(const void *input, size_t length, + uint64_t seed) +{ + if (sizeof(size_t) == 8) + return xxh64(input, length, seed); + else + return xxh32(input, length, seed); +} + +/*-**************************** + * Streaming Hash Functions + *****************************/ + +/* + * These definitions are only meant to allow allocation of XXH state + * statically, on stack, or in a struct for example. + * Do not use members directly. + */ + +/** + * struct xxh32_state - private xxh32 state, do not use members directly + */ +struct xxh32_state { + uint32_t total_len_32; + uint32_t large_len; + uint32_t v1; + uint32_t v2; + uint32_t v3; + uint32_t v4; + uint32_t mem32[4]; + uint32_t memsize; +}; + +/** + * struct xxh32_state - private xxh64 state, do not use members directly + */ +struct xxh64_state { + uint64_t total_len; + uint64_t v1; + uint64_t v2; + uint64_t v3; + uint64_t v4; + uint64_t mem64[4]; + uint32_t memsize; +}; + +/** + * xxh32_reset() - reset the xxh32 state to start a new hashing operation + * + * @state: The xxh32 state to reset. + * @seed: Initialize the hash state with this seed. + * + * Call this function on any xxh32_state to prepare for a new hashing operation. + */ +XXH_API void xxh32_reset(struct xxh32_state *state, uint32_t seed); + +/** + * xxh32_update() - hash the data given and update the xxh32 state + * + * @state: The xxh32 state to update. + * @input: The data to hash. + * @length: The length of the data to hash. + * + * After calling xxh32_reset() call xxh32_update() as many times as necessary. + * + * Return: Zero on success, otherwise an error code. + */ +XXH_API int xxh32_update(struct xxh32_state *state, const void *input, size_t length); + +/** + * xxh32_digest() - produce the current xxh32 hash + * + * @state: Produce the current xxh32 hash of this state. + * + * A hash value can be produced at any time. It is still possible to continue + * inserting input into the hash state after a call to xxh32_digest(), and + * generate new hashes later on, by calling xxh32_digest() again. + * + * Return: The xxh32 hash stored in the state. + */ +XXH_API uint32_t xxh32_digest(const struct xxh32_state *state); + +/** + * xxh64_reset() - reset the xxh64 state to start a new hashing operation + * + * @state: The xxh64 state to reset. + * @seed: Initialize the hash state with this seed. + */ +XXH_API void xxh64_reset(struct xxh64_state *state, uint64_t seed); + +/** + * xxh64_update() - hash the data given and update the xxh64 state + * @state: The xxh64 state to update. + * @input: The data to hash. + * @length: The length of the data to hash. + * + * After calling xxh64_reset() call xxh64_update() as many times as necessary. + * + * Return: Zero on success, otherwise an error code. + */ +XXH_API int xxh64_update(struct xxh64_state *state, const void *input, size_t length); + +/** + * xxh64_digest() - produce the current xxh64 hash + * + * @state: Produce the current xxh64 hash of this state. + * + * A hash value can be produced at any time. It is still possible to continue + * inserting input into the hash state after a call to xxh64_digest(), and + * generate new hashes later on, by calling xxh64_digest() again. + * + * Return: The xxh64 hash stored in the state. + */ +XXH_API uint64_t xxh64_digest(const struct xxh64_state *state); + +/*-************************** + * Utils + ***************************/ + +/** + * xxh32_copy_state() - copy the source state into the destination state + * + * @src: The source xxh32 state. + * @dst: The destination xxh32 state. + */ +XXH_API void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src); + +/** + * xxh64_copy_state() - copy the source state into the destination state + * + * @src: The source xxh64 state. + * @dst: The destination xxh64 state. + */ +XXH_API void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src); + +/* + * xxHash - Extremely Fast Hash algorithm + * Copyright (C) 2012-2016, Yann Collet. + * + * BSD 2-Clause License (https://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. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at: + * - xxHash homepage: https://cyan4973.github.io/xxHash/ + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ + +#include +#include +#include +#include +#include + +/*-************************************* + * Macros + **************************************/ +#define xxh_rotl32(x, r) ((x << r) | (x >> (32 - r))) +#define xxh_rotl64(x, r) ((x << r) | (x >> (64 - r))) + +#ifdef __LITTLE_ENDIAN +# define XXH_CPU_LITTLE_ENDIAN 1 +#else +# define XXH_CPU_LITTLE_ENDIAN 0 +#endif + +/*-************************************* + * Constants + **************************************/ +static const uint32_t PRIME32_1 = 2654435761U; +static const uint32_t PRIME32_2 = 2246822519U; +static const uint32_t PRIME32_3 = 3266489917U; +static const uint32_t PRIME32_4 = 668265263U; +static const uint32_t PRIME32_5 = 374761393U; + +static const uint64_t PRIME64_1 = 11400714785074694791ULL; +static const uint64_t PRIME64_2 = 14029467366897019727ULL; +static const uint64_t PRIME64_3 = 1609587929392839161ULL; +static const uint64_t PRIME64_4 = 9650029242287828579ULL; +static const uint64_t PRIME64_5 = 2870177450012600261ULL; + +/*-************************** + * Utils + ***************************/ +XXH_API void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src) +{ + __builtin_memcpy(dst, src, sizeof(*dst)); +} + +XXH_API void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src) +{ + __builtin_memcpy(dst, src, sizeof(*dst)); +} + +/*-*************************** + * Simple Hash Functions + ****************************/ +static uint32_t xxh32_round(uint32_t seed, const uint32_t input) +{ + seed += input * PRIME32_2; + seed = xxh_rotl32(seed, 13); + seed *= PRIME32_1; + return seed; +} + +XXH_API uint32_t xxh32(const void *input, const size_t len, const uint32_t seed) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *b_end = p + len; + uint32_t h32; + + if (len >= 16) { + const uint8_t *const limit = b_end - 16; + uint32_t v1 = seed + PRIME32_1 + PRIME32_2; + uint32_t v2 = seed + PRIME32_2; + uint32_t v3 = seed + 0; + uint32_t v4 = seed - PRIME32_1; + + do { + v1 = xxh32_round(v1, get_unaligned_le32(p)); + p += 4; + v2 = xxh32_round(v2, get_unaligned_le32(p)); + p += 4; + v3 = xxh32_round(v3, get_unaligned_le32(p)); + p += 4; + v4 = xxh32_round(v4, get_unaligned_le32(p)); + 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 += (uint32_t)len; + + while (p + 4 <= b_end) { + h32 += get_unaligned_le32(p) * PRIME32_3; + h32 = xxh_rotl32(h32, 17) * PRIME32_4; + p += 4; + } + + while (p < b_end) { + h32 += (*p) * PRIME32_5; + h32 = xxh_rotl32(h32, 11) * PRIME32_1; + p++; + } + + h32 ^= h32 >> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + +static uint64_t xxh64_round(uint64_t acc, const uint64_t input) +{ + acc += input * PRIME64_2; + acc = xxh_rotl64(acc, 31); + acc *= PRIME64_1; + return acc; +} + +static uint64_t xxh64_merge_round(uint64_t acc, uint64_t val) +{ + val = xxh64_round(0, val); + acc ^= val; + acc = acc * PRIME64_1 + PRIME64_4; + return acc; +} + +XXH_API uint64_t xxh64(const void *input, const size_t len, const uint64_t seed) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *const b_end = p + len; + uint64_t h64; + + if (len >= 32) { + const uint8_t *const limit = b_end - 32; + uint64_t v1 = seed + PRIME64_1 + PRIME64_2; + uint64_t v2 = seed + PRIME64_2; + uint64_t v3 = seed + 0; + uint64_t v4 = seed - PRIME64_1; + + do { + v1 = xxh64_round(v1, get_unaligned_le64(p)); + p += 8; + v2 = xxh64_round(v2, get_unaligned_le64(p)); + p += 8; + v3 = xxh64_round(v3, get_unaligned_le64(p)); + p += 8; + v4 = xxh64_round(v4, get_unaligned_le64(p)); + p += 8; + } while (p <= limit); + + h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) + + xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18); + h64 = xxh64_merge_round(h64, v1); + h64 = xxh64_merge_round(h64, v2); + h64 = xxh64_merge_round(h64, v3); + h64 = xxh64_merge_round(h64, v4); + + } else { + h64 = seed + PRIME64_5; + } + + h64 += (uint64_t)len; + + while (p + 8 <= b_end) { + const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p)); + + h64 ^= k1; + h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4; + p += 8; + } + + if (p + 4 <= b_end) { + h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1; + h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p += 4; + } + + while (p < b_end) { + h64 ^= (*p) * PRIME64_5; + h64 = xxh_rotl64(h64, 11) * PRIME64_1; + p++; + } + + h64 ^= h64 >> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + +/*-************************************************** + * Advanced Hash Functions + ***************************************************/ +XXH_API void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed) +{ + /* use a local state for memcpy() to avoid strict-aliasing warnings */ + struct xxh32_state state; + + __builtin_memset(&state, 0, sizeof(state)); + state.v1 = seed + PRIME32_1 + PRIME32_2; + state.v2 = seed + PRIME32_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME32_1; + __builtin_memcpy(statePtr, &state, sizeof(state)); +} + +XXH_API void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed) +{ + /* use a local state for memcpy() to avoid strict-aliasing warnings */ + struct xxh64_state state; + + __builtin_memset(&state, 0, sizeof(state)); + state.v1 = seed + PRIME64_1 + PRIME64_2; + state.v2 = seed + PRIME64_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME64_1; + __builtin_memcpy(statePtr, &state, sizeof(state)); +} + +XXH_API int xxh32_update(struct xxh32_state *state, const void *input, const size_t len) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *const b_end = p + len; + + if (input == NULL) + return -EINVAL; + + state->total_len_32 += (uint32_t)len; + state->large_len |= (len >= 16) | (state->total_len_32 >= 16); + + if (state->memsize + len < 16) { /* fill in tmp buffer */ + __builtin_memcpy((uint8_t *)(state->mem32) + state->memsize, input, len); + state->memsize += (uint32_t)len; + return 0; + } + + if (state->memsize) { /* some data left from previous update */ + const uint32_t *p32 = state->mem32; + + __builtin_memcpy((uint8_t *)(state->mem32) + state->memsize, input, + 16 - state->memsize); + + state->v1 = xxh32_round(state->v1, get_unaligned_le32(p32)); + p32++; + state->v2 = xxh32_round(state->v2, get_unaligned_le32(p32)); + p32++; + state->v3 = xxh32_round(state->v3, get_unaligned_le32(p32)); + p32++; + state->v4 = xxh32_round(state->v4, get_unaligned_le32(p32)); + p32++; + + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= b_end - 16) { + const uint8_t *const limit = b_end - 16; + uint32_t v1 = state->v1; + uint32_t v2 = state->v2; + uint32_t v3 = state->v3; + uint32_t v4 = state->v4; + + do { + v1 = xxh32_round(v1, get_unaligned_le32(p)); + p += 4; + v2 = xxh32_round(v2, get_unaligned_le32(p)); + p += 4; + v3 = xxh32_round(v3, get_unaligned_le32(p)); + p += 4; + v4 = xxh32_round(v4, get_unaligned_le32(p)); + p += 4; + } while (p <= limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < b_end) { + __builtin_memcpy(state->mem32, p, (size_t)(b_end-p)); + state->memsize = (uint32_t)(b_end-p); + } + + return 0; +} + +XXH_API uint32_t xxh32_digest(const struct xxh32_state *state) +{ + const uint8_t *p = (const uint8_t *)state->mem32; + const uint8_t *const b_end = (const uint8_t *)(state->mem32) + + state->memsize; + uint32_t h32; + + if (state->large_len) { + h32 = xxh_rotl32(state->v1, 1) + xxh_rotl32(state->v2, 7) + + xxh_rotl32(state->v3, 12) + xxh_rotl32(state->v4, 18); + } else { + h32 = state->v3 /* == seed */ + PRIME32_5; + } + + h32 += state->total_len_32; + + while (p + 4 <= b_end) { + h32 += get_unaligned_le32(p) * PRIME32_3; + h32 = xxh_rotl32(h32, 17) * PRIME32_4; + p += 4; + } + + while (p < b_end) { + h32 += (*p) * PRIME32_5; + h32 = xxh_rotl32(h32, 11) * PRIME32_1; + p++; + } + + h32 ^= h32 >> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + +XXH_API int xxh64_update(struct xxh64_state *state, const void *input, const size_t len) +{ + const uint8_t *p = (const uint8_t *)input; + const uint8_t *const b_end = p + len; + + if (input == NULL) + return -EINVAL; + + state->total_len += len; + + if (state->memsize + len < 32) { /* fill in tmp buffer */ + __builtin_memcpy(((uint8_t *)state->mem64) + state->memsize, input, len); + state->memsize += (uint32_t)len; + return 0; + } + + if (state->memsize) { /* tmp buffer is full */ + uint64_t *p64 = state->mem64; + + __builtin_memcpy(((uint8_t *)p64) + state->memsize, input, + 32 - state->memsize); + + state->v1 = xxh64_round(state->v1, get_unaligned_le64(p64)); + p64++; + state->v2 = xxh64_round(state->v2, get_unaligned_le64(p64)); + p64++; + state->v3 = xxh64_round(state->v3, get_unaligned_le64(p64)); + p64++; + state->v4 = xxh64_round(state->v4, get_unaligned_le64(p64)); + + p += 32 - state->memsize; + state->memsize = 0; + } + + if (p + 32 <= b_end) { + const uint8_t *const limit = b_end - 32; + uint64_t v1 = state->v1; + uint64_t v2 = state->v2; + uint64_t v3 = state->v3; + uint64_t v4 = state->v4; + + do { + v1 = xxh64_round(v1, get_unaligned_le64(p)); + p += 8; + v2 = xxh64_round(v2, get_unaligned_le64(p)); + p += 8; + v3 = xxh64_round(v3, get_unaligned_le64(p)); + p += 8; + v4 = xxh64_round(v4, get_unaligned_le64(p)); + p += 8; + } while (p <= limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < b_end) { + __builtin_memcpy(state->mem64, p, (size_t)(b_end-p)); + state->memsize = (uint32_t)(b_end - p); + } + + return 0; +} + +XXH_API uint64_t xxh64_digest(const struct xxh64_state *state) +{ + const uint8_t *p = (const uint8_t *)state->mem64; + const uint8_t *const b_end = (const uint8_t *)state->mem64 + + state->memsize; + uint64_t h64; + + if (state->total_len >= 32) { + const uint64_t v1 = state->v1; + const uint64_t v2 = state->v2; + const uint64_t v3 = state->v3; + const uint64_t v4 = state->v4; + + h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) + + xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18); + h64 = xxh64_merge_round(h64, v1); + h64 = xxh64_merge_round(h64, v2); + h64 = xxh64_merge_round(h64, v3); + h64 = xxh64_merge_round(h64, v4); + } else { + h64 = state->v3 + PRIME64_5; + } + + h64 += (uint64_t)state->total_len; + + while (p + 8 <= b_end) { + const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p)); + + h64 ^= k1; + h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4; + p += 8; + } + + if (p + 4 <= b_end) { + h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1; + h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p += 4; + } + + while (p < b_end) { + h64 ^= (*p) * PRIME64_5; + h64 = xxh_rotl64(h64, 11) * PRIME64_1; + p++; + } + + h64 ^= h64 >> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + +#endif /* XXHASH_H */ diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/macro-test.sh b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/macro-test.sh new file mode 100755 index 000000000..9ea84aa66 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/macro-test.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env sh + +set -e + +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) +INCLUDE_DIR="$SCRIPT_DIR/../linux/include" +LIB_DIR="$SCRIPT_DIR/../linux/lib" + + +print() { + printf '%b' "${*}" +} + +println() { + printf '%b\n' "${*}" +} + +die() { + println "$@" 1>&2 + exit 1 +} + +test_not_present() { + print "Testing that '$1' is not present... " + grep -r $1 "$INCLUDE_DIR" "$LIB_DIR" && die "Fail!" + println "Okay" +} + +println "This test checks that the macro removal process worked as expected" +println "If this test fails, then freestanding.py wasn't able to remove one of these" +println "macros from the source code completely. You'll either need to rewrite the check" +println "or improve freestanding.py." +println "" + +test_not_present "ZSTD_NO_INTRINSICS" +test_not_present "ZSTD_NO_UNUSED_FUNCTIONS" +test_not_present "ZSTD_LEGACY_SUPPORT" +test_not_present "STATIC_BMI2" +test_not_present "ZSTD_DLL_EXPORT" +test_not_present "ZSTD_DLL_IMPORT" +test_not_present "__ICCARM__" +test_not_present "_MSC_VER" +test_not_present "_WIN32" +test_not_present "__linux__" diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/static_test.c b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/static_test.c new file mode 100644 index 000000000..ba4a420d4 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/static_test.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#include +#include +#include +#include + +#include "decompress_sources.h" +#include + +#define CONTROL(x) \ + do { \ + if (!(x)) { \ + fprintf(stderr, "%s:%u: %s failed!\n", __FUNCTION__, __LINE__, #x); \ + abort(); \ + } \ + } while (0) + + +static const char kEmptyZstdFrame[] = { + 0x28, 0xb5, 0x2f, 0xfd, 0x24, 0x00, 0x01, 0x00, 0x00, 0x99, 0xe9, 0xd8, 0x51 +}; + +static void test_decompress_unzstd(void) { + fprintf(stderr, "Testing decompress unzstd... "); + { + size_t const wkspSize = zstd_dctx_workspace_bound(); + void* wksp = malloc(wkspSize); + ZSTD_DCtx* dctx = zstd_init_dctx(wksp, wkspSize); + CONTROL(wksp != NULL); + CONTROL(dctx != NULL); + { + size_t const dSize = zstd_decompress_dctx(dctx, NULL, 0, kEmptyZstdFrame, sizeof(kEmptyZstdFrame)); + CONTROL(!zstd_is_error(dSize)); + CONTROL(dSize == 0); + } + free(wksp); + } + fprintf(stderr, "Ok\n"); +} + +int main(void) { + test_decompress_unzstd(); + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/test.c b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/test.c new file mode 100644 index 000000000..0f4ba3f45 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/test/test.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#include +#include +#include +#include + +#include + +#define CONTROL(x) \ + do { \ + if (!(x)) { \ + fprintf(stderr, "%s:%u: %s failed!\n", __FUNCTION__, __LINE__, #x); \ + abort(); \ + } \ + } while (0) + +typedef struct { + char *data; + char *data2; + size_t dataSize; + char *comp; + size_t compSize; +} test_data_t; + +static test_data_t create_test_data(void) { + test_data_t data; + data.dataSize = 128 * 1024; + data.data = (char*)malloc(data.dataSize); + CONTROL(data.data != NULL); + data.data2 = (char*)malloc(data.dataSize); + CONTROL(data.data2 != NULL); + data.compSize = zstd_compress_bound(data.dataSize); + data.comp = (char*)malloc(data.compSize); + CONTROL(data.comp != NULL); + memset(data.data, 0, data.dataSize); + return data; +} + +static void free_test_data(test_data_t const *data) { + free(data->data); + free(data->data2); + free(data->comp); +} + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +static void test_btrfs(test_data_t const *data) { + size_t const size = MIN(data->dataSize, 128 * 1024); + fprintf(stderr, "testing btrfs use cases... "); + for (int level = -1; level < 16; ++level) { + zstd_parameters params = zstd_get_params(level, size); + size_t const workspaceSize = + MAX(zstd_cstream_workspace_bound(¶ms.cParams), + zstd_dstream_workspace_bound(size)); + void *workspace = malloc(workspaceSize); + + char const *ip = data->data; + char const *iend = ip + size; + char *op = data->comp; + char *oend = op + data->compSize; + + CONTROL(params.cParams.windowLog <= 17); + CONTROL(workspace != NULL); + { + zstd_cstream *cctx = zstd_init_cstream(¶ms, size, workspace, workspaceSize); + zstd_out_buffer out = {NULL, 0, 0}; + zstd_in_buffer in = {NULL, 0, 0}; + CONTROL(cctx != NULL); + for (;;) { + if (in.pos == in.size) { + in.src = ip; + in.size = MIN(4096, iend - ip); + in.pos = 0; + ip += in.size; + } + + if (out.pos == out.size) { + out.dst = op; + out.size = MIN(4096, oend - op); + out.pos = 0; + op += out.size; + } + + if (ip != iend || in.pos < in.size) { + CONTROL(!zstd_is_error(zstd_compress_stream(cctx, &out, &in))); + } else { + size_t const ret = zstd_end_stream(cctx, &out); + CONTROL(!zstd_is_error(ret)); + if (ret == 0) { + break; + } + } + } + op += out.pos; + } + + ip = data->comp; + iend = op; + op = data->data2; + oend = op + size; + { + zstd_dstream *dctx = zstd_init_dstream(1ULL << params.cParams.windowLog, workspace, workspaceSize); + zstd_out_buffer out = {NULL, 0, 0}; + zstd_in_buffer in = {NULL, 0, 0}; + CONTROL(dctx != NULL); + for (;;) { + if (in.pos == in.size) { + in.src = ip; + in.size = MIN(4096, iend - ip); + in.pos = 0; + ip += in.size; + } + + if (out.pos == out.size) { + out.dst = op; + out.size = MIN(4096, oend - op); + out.pos = 0; + op += out.size; + } + { + size_t const ret = zstd_decompress_stream(dctx, &out, &in); + CONTROL(!zstd_is_error(ret)); + if (ret == 0) { + break; + } + } + } + } + CONTROL((size_t)(op - data->data2) == data->dataSize); + CONTROL(!memcmp(data->data, data->data2, data->dataSize)); + free(workspace); + } + fprintf(stderr, "Ok\n"); +} + +static void test_decompress_unzstd(test_data_t const *data) { + size_t cSize; + fprintf(stderr, "Testing decompress unzstd... "); + { + zstd_parameters params = zstd_get_params(19, 0); + size_t const wkspSize = zstd_cctx_workspace_bound(¶ms.cParams); + void* wksp = malloc(wkspSize); + zstd_cctx* cctx = zstd_init_cctx(wksp, wkspSize); + CONTROL(wksp != NULL); + CONTROL(cctx != NULL); + cSize = zstd_compress_cctx(cctx, data->comp, data->compSize, data->data, data->dataSize, ¶ms); + CONTROL(!zstd_is_error(cSize)); + free(wksp); + } + { + size_t const wkspSize = zstd_dctx_workspace_bound(); + void* wksp = malloc(wkspSize); + zstd_dctx* dctx = zstd_init_dctx(wksp, wkspSize); + CONTROL(wksp != NULL); + CONTROL(dctx != NULL); + { + size_t const dSize = zstd_decompress_dctx(dctx, data->data2, data->dataSize, data->comp, cSize); + CONTROL(!zstd_is_error(dSize)); + CONTROL(dSize == data->dataSize); + } + CONTROL(!memcmp(data->data, data->data2, data->dataSize)); + free(wksp); + } + fprintf(stderr, "Ok\n"); +} + +static void test_f2fs(void) { + fprintf(stderr, "testing f2fs uses... "); + CONTROL(zstd_min_clevel() < 0); + CONTROL(zstd_max_clevel() == 22); + fprintf(stderr, "Ok\n"); +} + +static char *g_stack = NULL; + +static void __attribute__((noinline)) use(void *x) { + asm volatile("" : "+r"(x)); +} + +static void __attribute__((noinline)) fill_stack(void) { + memset(g_stack, 0x33, 8192); +} + +static void __attribute__((noinline)) set_stack(void) { + + char stack[8192]; + g_stack = stack; + use(g_stack); +} + +static void __attribute__((noinline)) check_stack(void) { + size_t cleanStack = 0; + while (cleanStack < 8192 && g_stack[cleanStack] == 0x33) { + ++cleanStack; + } + { + size_t const stackSize = 8192 - cleanStack; + fprintf(stderr, "Maximum stack size: %zu\n", stackSize); + CONTROL(stackSize <= 2048 + 512); + } +} + +static void test_stack_usage(test_data_t const *data) { + set_stack(); + fill_stack(); + test_f2fs(); + test_btrfs(data); + test_decompress_unzstd(data); + check_stack(); +} + +int main(void) { + test_data_t data = create_test_data(); + test_f2fs(); + test_btrfs(&data); + test_decompress_unzstd(&data); + test_stack_usage(&data); + free_test_data(&data); + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_common_module.c b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_common_module.c new file mode 100644 index 000000000..466828e35 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_common_module.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include + +#include "common/huf.h" +#include "common/fse.h" +#include "common/zstd_internal.h" + +// Export symbols shared by compress and decompress into a common module + +#undef ZSTD_isError /* defined within zstd_internal.h */ +EXPORT_SYMBOL_GPL(FSE_readNCount); +EXPORT_SYMBOL_GPL(HUF_readStats); +EXPORT_SYMBOL_GPL(HUF_readStats_wksp); +EXPORT_SYMBOL_GPL(ZSTD_isError); +EXPORT_SYMBOL_GPL(ZSTD_getErrorName); +EXPORT_SYMBOL_GPL(ZSTD_getErrorCode); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("Zstd Common"); diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_compress_module.c b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_compress_module.c new file mode 100644 index 000000000..804efe6d5 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_compress_module.c @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include +#include +#include +#include + +#include "common/zstd_deps.h" +#include "common/zstd_internal.h" +#include "compress/zstd_compress_internal.h" + +#define ZSTD_FORWARD_IF_ERR(ret) \ + do { \ + size_t const __ret = (ret); \ + if (ZSTD_isError(__ret)) \ + return __ret; \ + } while (0) + +static size_t zstd_cctx_init(zstd_cctx *cctx, const zstd_parameters *parameters, + unsigned long long pledged_src_size) +{ + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_reset( + cctx, ZSTD_reset_session_and_parameters)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setPledgedSrcSize( + cctx, pledged_src_size)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_windowLog, parameters->cParams.windowLog)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_hashLog, parameters->cParams.hashLog)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_chainLog, parameters->cParams.chainLog)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_searchLog, parameters->cParams.searchLog)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_minMatch, parameters->cParams.minMatch)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_targetLength, parameters->cParams.targetLength)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_strategy, parameters->cParams.strategy)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_contentSizeFlag, parameters->fParams.contentSizeFlag)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_checksumFlag, parameters->fParams.checksumFlag)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_dictIDFlag, !parameters->fParams.noDictIDFlag)); + return 0; +} + +int zstd_min_clevel(void) +{ + return ZSTD_minCLevel(); +} +EXPORT_SYMBOL(zstd_min_clevel); + +int zstd_max_clevel(void) +{ + return ZSTD_maxCLevel(); +} +EXPORT_SYMBOL(zstd_max_clevel); + +size_t zstd_compress_bound(size_t src_size) +{ + return ZSTD_compressBound(src_size); +} +EXPORT_SYMBOL(zstd_compress_bound); + +zstd_parameters zstd_get_params(int level, + unsigned long long estimated_src_size) +{ + return ZSTD_getParams(level, estimated_src_size, 0); +} +EXPORT_SYMBOL(zstd_get_params); + +size_t zstd_cctx_set_param(zstd_cctx *cctx, ZSTD_cParameter param, int value) +{ + return ZSTD_CCtx_setParameter(cctx, param, value); +} +EXPORT_SYMBOL(zstd_cctx_set_param); + +size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *cparams) +{ + return ZSTD_estimateCCtxSize_usingCParams(*cparams); +} +EXPORT_SYMBOL(zstd_cctx_workspace_bound); + +// Used by zstd_cctx_workspace_bound_with_ext_seq_prod() +static size_t dummy_external_sequence_producer( + void *sequenceProducerState, + ZSTD_Sequence *outSeqs, size_t outSeqsCapacity, + const void *src, size_t srcSize, + const void *dict, size_t dictSize, + int compressionLevel, + size_t windowSize) +{ + (void)sequenceProducerState; + (void)outSeqs; (void)outSeqsCapacity; + (void)src; (void)srcSize; + (void)dict; (void)dictSize; + (void)compressionLevel; + (void)windowSize; + return ZSTD_SEQUENCE_PRODUCER_ERROR; +} + +static void init_cctx_params_from_compress_params( + ZSTD_CCtx_params *cctx_params, + const zstd_compression_parameters *compress_params) +{ + ZSTD_parameters zstd_params; + memset(&zstd_params, 0, sizeof(zstd_params)); + zstd_params.cParams = *compress_params; + ZSTD_CCtxParams_init_advanced(cctx_params, zstd_params); +} + +size_t zstd_cctx_workspace_bound_with_ext_seq_prod(const zstd_compression_parameters *compress_params) +{ + ZSTD_CCtx_params cctx_params; + init_cctx_params_from_compress_params(&cctx_params, compress_params); + ZSTD_CCtxParams_registerSequenceProducer(&cctx_params, NULL, dummy_external_sequence_producer); + return ZSTD_estimateCCtxSize_usingCCtxParams(&cctx_params); +} +EXPORT_SYMBOL(zstd_cctx_workspace_bound_with_ext_seq_prod); + +size_t zstd_cstream_workspace_bound_with_ext_seq_prod(const zstd_compression_parameters *compress_params) +{ + ZSTD_CCtx_params cctx_params; + init_cctx_params_from_compress_params(&cctx_params, compress_params); + ZSTD_CCtxParams_registerSequenceProducer(&cctx_params, NULL, dummy_external_sequence_producer); + return ZSTD_estimateCStreamSize_usingCCtxParams(&cctx_params); +} +EXPORT_SYMBOL(zstd_cstream_workspace_bound_with_ext_seq_prod); + +zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size) +{ + if (workspace == NULL) + return NULL; + return ZSTD_initStaticCCtx(workspace, workspace_size); +} +EXPORT_SYMBOL(zstd_init_cctx); + +size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity, + const void *src, size_t src_size, const zstd_parameters *parameters) +{ + ZSTD_FORWARD_IF_ERR(zstd_cctx_init(cctx, parameters, src_size)); + return ZSTD_compress2(cctx, dst, dst_capacity, src, src_size); +} +EXPORT_SYMBOL(zstd_compress_cctx); + +size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams) +{ + return ZSTD_estimateCStreamSize_usingCParams(*cparams); +} +EXPORT_SYMBOL(zstd_cstream_workspace_bound); + +zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters, + unsigned long long pledged_src_size, void *workspace, size_t workspace_size) +{ + zstd_cstream *cstream; + + if (workspace == NULL) + return NULL; + + cstream = ZSTD_initStaticCStream(workspace, workspace_size); + if (cstream == NULL) + return NULL; + + /* 0 means unknown in linux zstd API but means 0 in new zstd API */ + if (pledged_src_size == 0) + pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN; + + if (ZSTD_isError(zstd_cctx_init(cstream, parameters, pledged_src_size))) + return NULL; + + return cstream; +} +EXPORT_SYMBOL(zstd_init_cstream); + +size_t zstd_reset_cstream(zstd_cstream *cstream, + unsigned long long pledged_src_size) +{ + if (pledged_src_size == 0) + pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN; + ZSTD_FORWARD_IF_ERR( ZSTD_CCtx_reset(cstream, ZSTD_reset_session_only) ); + ZSTD_FORWARD_IF_ERR( ZSTD_CCtx_setPledgedSrcSize(cstream, pledged_src_size) ); + return 0; +} +EXPORT_SYMBOL(zstd_reset_cstream); + +size_t zstd_compress_stream(zstd_cstream *cstream, zstd_out_buffer *output, + zstd_in_buffer *input) +{ + return ZSTD_compressStream(cstream, output, input); +} +EXPORT_SYMBOL(zstd_compress_stream); + +size_t zstd_flush_stream(zstd_cstream *cstream, zstd_out_buffer *output) +{ + return ZSTD_flushStream(cstream, output); +} +EXPORT_SYMBOL(zstd_flush_stream); + +size_t zstd_end_stream(zstd_cstream *cstream, zstd_out_buffer *output) +{ + return ZSTD_endStream(cstream, output); +} +EXPORT_SYMBOL(zstd_end_stream); + +void zstd_register_sequence_producer( + zstd_cctx *cctx, + void* sequence_producer_state, + zstd_sequence_producer_f sequence_producer +) { + ZSTD_registerSequenceProducer(cctx, sequence_producer_state, sequence_producer); +} +EXPORT_SYMBOL(zstd_register_sequence_producer); + +size_t zstd_compress_sequences_and_literals(zstd_cctx *cctx, void* dst, size_t dst_capacity, + const zstd_sequence *in_seqs, size_t in_seqs_size, + const void* literals, size_t lit_size, size_t lit_capacity, + size_t decompressed_size) +{ + return ZSTD_compressSequencesAndLiterals(cctx, dst, dst_capacity, in_seqs, + in_seqs_size, literals, lit_size, + lit_capacity, decompressed_size); +} +EXPORT_SYMBOL(zstd_compress_sequences_and_literals); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("Zstd Compressor"); diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_decompress_module.c b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_decompress_module.c new file mode 100644 index 000000000..7d31518e9 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_decompress_module.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include +#include +#include +#include + +#include "common/zstd_deps.h" + +/* Common symbols. zstd_compress must depend on zstd_decompress. */ + +unsigned int zstd_is_error(size_t code) +{ + return ZSTD_isError(code); +} +EXPORT_SYMBOL(zstd_is_error); + +zstd_error_code zstd_get_error_code(size_t code) +{ + return ZSTD_getErrorCode(code); +} +EXPORT_SYMBOL(zstd_get_error_code); + +const char *zstd_get_error_name(size_t code) +{ + return ZSTD_getErrorName(code); +} +EXPORT_SYMBOL(zstd_get_error_name); + +/* Decompression symbols. */ + +size_t zstd_dctx_workspace_bound(void) +{ + return ZSTD_estimateDCtxSize(); +} +EXPORT_SYMBOL(zstd_dctx_workspace_bound); + +zstd_dctx *zstd_init_dctx(void *workspace, size_t workspace_size) +{ + if (workspace == NULL) + return NULL; + return ZSTD_initStaticDCtx(workspace, workspace_size); +} +EXPORT_SYMBOL(zstd_init_dctx); + +size_t zstd_decompress_dctx(zstd_dctx *dctx, void *dst, size_t dst_capacity, + const void *src, size_t src_size) +{ + return ZSTD_decompressDCtx(dctx, dst, dst_capacity, src, src_size); +} +EXPORT_SYMBOL(zstd_decompress_dctx); + +size_t zstd_dstream_workspace_bound(size_t max_window_size) +{ + return ZSTD_estimateDStreamSize(max_window_size); +} +EXPORT_SYMBOL(zstd_dstream_workspace_bound); + +zstd_dstream *zstd_init_dstream(size_t max_window_size, void *workspace, + size_t workspace_size) +{ + if (workspace == NULL) + return NULL; + (void)max_window_size; + return ZSTD_initStaticDStream(workspace, workspace_size); +} +EXPORT_SYMBOL(zstd_init_dstream); + +size_t zstd_reset_dstream(zstd_dstream *dstream) +{ + return ZSTD_DCtx_reset(dstream, ZSTD_reset_session_only); +} +EXPORT_SYMBOL(zstd_reset_dstream); + +size_t zstd_decompress_stream(zstd_dstream *dstream, zstd_out_buffer *output, + zstd_in_buffer *input) +{ + return ZSTD_decompressStream(dstream, output, input); +} +EXPORT_SYMBOL(zstd_decompress_stream); + +size_t zstd_find_frame_compressed_size(const void *src, size_t src_size) +{ + return ZSTD_findFrameCompressedSize(src, src_size); +} +EXPORT_SYMBOL(zstd_find_frame_compressed_size); + +size_t zstd_get_frame_header(zstd_frame_header *header, const void *src, + size_t src_size) +{ + return ZSTD_getFrameHeader(header, src, src_size); +} +EXPORT_SYMBOL(zstd_get_frame_header); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("Zstd Decompressor"); diff --git a/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_deps.h b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_deps.h new file mode 100644 index 000000000..f931f7d0e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/linux-kernel/zstd_deps.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* + * This file provides common libc dependencies that zstd requires. + * The purpose is to allow replacing this file with a custom implementation + * to compile zstd without libc support. + */ + +/* Need: + * NULL + * INT_MAX + * UINT_MAX + * ZSTD_memcpy() + * ZSTD_memset() + * ZSTD_memmove() + */ +#ifndef ZSTD_DEPS_COMMON +#define ZSTD_DEPS_COMMON + +#include +#include + +#define ZSTD_memcpy(d,s,n) __builtin_memcpy((d),(s),(n)) +#define ZSTD_memmove(d,s,n) __builtin_memmove((d),(s),(n)) +#define ZSTD_memset(d,s,n) __builtin_memset((d),(s),(n)) + +#endif /* ZSTD_DEPS_COMMON */ + +/* + * Define malloc as always failing. That means the user must + * either use ZSTD_customMem or statically allocate memory. + * Need: + * ZSTD_malloc() + * ZSTD_free() + * ZSTD_calloc() + */ +#ifdef ZSTD_DEPS_NEED_MALLOC +#ifndef ZSTD_DEPS_MALLOC +#define ZSTD_DEPS_MALLOC + +#define ZSTD_malloc(s) ({ (void)(s); NULL; }) +#define ZSTD_free(p) ((void)(p)) +#define ZSTD_calloc(n,s) ({ (void)(n); (void)(s); NULL; }) + +#endif /* ZSTD_DEPS_MALLOC */ +#endif /* ZSTD_DEPS_NEED_MALLOC */ + +/* + * Provides 64-bit math support. + * Need: + * U64 ZSTD_div64(U64 dividend, U32 divisor) + */ +#ifdef ZSTD_DEPS_NEED_MATH64 +#ifndef ZSTD_DEPS_MATH64 +#define ZSTD_DEPS_MATH64 + +#include + +static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) { + return div_u64(dividend, divisor); +} + +#endif /* ZSTD_DEPS_MATH64 */ +#endif /* ZSTD_DEPS_NEED_MATH64 */ + +/* + * This is only requested when DEBUGLEVEL >= 1, meaning + * it is disabled in production. + * Need: + * assert() + */ +#ifdef ZSTD_DEPS_NEED_ASSERT +#ifndef ZSTD_DEPS_ASSERT +#define ZSTD_DEPS_ASSERT + +#include + +#define assert(x) WARN_ON(!(x)) + +#endif /* ZSTD_DEPS_ASSERT */ +#endif /* ZSTD_DEPS_NEED_ASSERT */ + +/* + * This is only requested when DEBUGLEVEL >= 2, meaning + * it is disabled in production. + * Need: + * ZSTD_DEBUG_PRINT() + */ +#ifdef ZSTD_DEPS_NEED_IO +#ifndef ZSTD_DEPS_IO +#define ZSTD_DEPS_IO + +#include + +#define ZSTD_DEBUG_PRINT(...) pr_debug(__VA_ARGS__) + +#endif /* ZSTD_DEPS_IO */ +#endif /* ZSTD_DEPS_NEED_IO */ + +/* + * Only requested when MSAN is enabled. + * Need: + * intptr_t + */ +#ifdef ZSTD_DEPS_NEED_STDINT +#ifndef ZSTD_DEPS_STDINT +#define ZSTD_DEPS_STDINT + +/* intptr_t already provided by ZSTD_DEPS_COMMON */ + +#endif /* ZSTD_DEPS_STDINT */ +#endif /* ZSTD_DEPS_NEED_STDINT */ diff --git a/cpp/third_party/zstd-1.5.7/contrib/match_finders/README.md b/cpp/third_party/zstd-1.5.7/contrib/match_finders/README.md new file mode 100644 index 000000000..54055c370 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/match_finders/README.md @@ -0,0 +1,42 @@ +## Edit Distance Match Finder + +``` +/* This match finder leverages techniques used in file comparison algorithms + * to find matches between a dictionary and a source file. + * + * The original motivation for studying this approach was to try and optimize + * Zstandard for the use case of patching: the most common scenario being + * updating an existing software package with the next version. When patching, + * the difference between the old version of the package and the new version + * is generally tiny (most of the new file will be identical to + * the old one). In more technical terms, the edit distance (the minimal number + * of changes required to take one sequence of bytes to another) between the + * files would be small relative to the size of the file. + * + * Various 'diffing' algorithms utilize this notion of edit distance and + * the corresponding concept of a minimal edit script between two + * sequences to identify the regions within two files where they differ. + * The core algorithm used in this match finder is described in: + * + * "An O(ND) Difference Algorithm and its Variations", Eugene W. Myers, + * Algorithmica Vol. 1, 1986, pp. 251-266, + * . + * + * Additional algorithmic heuristics for speed improvement have also been included. + * These we inspired from implementations of various regular and binary diffing + * algorithms such as GNU diff, bsdiff, and Xdelta. + * + * Note: after some experimentation, this approach proved to not provide enough + * utility to justify the additional CPU used in finding matches. The one area + * where this approach consistently outperforms Zstandard even on level 19 is + * when compressing small files (<10 KB) using an equally small dictionary that + * is very similar to the source file. For the use case that this was intended, + * (large similar files) this approach by itself took 5-10X longer than zstd-19 and + * generally resulted in 2-3X larger files. The core advantage that zstd-19 has + * over this approach for match finding is the overlapping matches. This approach + * cannot find any. + * + * I'm leaving this in the contrib section in case this ever becomes interesting + * to explore again. + * */ +``` diff --git a/cpp/third_party/zstd-1.5.7/contrib/match_finders/zstd_edist.c b/cpp/third_party/zstd-1.5.7/contrib/match_finders/zstd_edist.c new file mode 100644 index 000000000..d685cdd9e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/match_finders/zstd_edist.c @@ -0,0 +1,558 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/*-************************************* +* Dependencies +***************************************/ + +/* Currently relies on qsort when combining contiguous matches. This can probably + * be avoided but would require changes to the algorithm. The qsort is far from + * the bottleneck in this algorithm even for medium sized files so it's probably + * not worth trying to address */ +#include +#include + +#include "zstd_edist.h" +#include "mem.h" + +/*-************************************* +* Constants +***************************************/ + +/* Just a sential for the entries of the diagonal matrix */ +#define ZSTD_EDIST_DIAG_MAX (S32)(1 << 30) + +/* How large should a snake be to be considered a 'big' snake. + * For an explanation of what a 'snake' is with respect to the + * edit distance matrix, see the linked paper in zstd_edist.h */ +#define ZSTD_EDIST_SNAKE_THRESH 20 + +/* After how many iterations should we start to use the heuristic + * based on 'big' snakes */ +#define ZSTD_EDIST_SNAKE_ITER_THRESH 200 + +/* After how many iterations should be just give up and take + * the best available edit script for this round */ +#define ZSTD_EDIST_EXPENSIVE_THRESH 1024 + +/*-************************************* +* Structures +***************************************/ + +typedef struct { + U32 dictIdx; + U32 srcIdx; + U32 matchLength; +} ZSTD_eDist_match; + +typedef struct { + const BYTE* dict; + const BYTE* src; + size_t dictSize; + size_t srcSize; + S32* forwardDiag; /* Entries of the forward diagonal stored here */ + S32* backwardDiag; /* Entries of the backward diagonal stored here. + * Note: this buffer and the 'forwardDiag' buffer + * are contiguous. See the ZSTD_eDist_genSequences */ + ZSTD_eDist_match* matches; /* Accumulate matches of length 1 in this buffer. + * In a subsequence post-processing step, we combine + * contiguous matches. */ + U32 nbMatches; +} ZSTD_eDist_state; + +typedef struct { + S32 dictMid; /* The mid diagonal for the dictionary */ + S32 srcMid; /* The mid diagonal for the source */ + int lowUseHeuristics; /* Should we use heuristics for the low part */ + int highUseHeuristics; /* Should we use heuristics for the high part */ +} ZSTD_eDist_partition; + +/*-************************************* +* Internal +***************************************/ + +static void ZSTD_eDist_diag(ZSTD_eDist_state* state, + ZSTD_eDist_partition* partition, + S32 dictLow, S32 dictHigh, S32 srcLow, + S32 srcHigh, int useHeuristics) +{ + S32* const forwardDiag = state->forwardDiag; + S32* const backwardDiag = state->backwardDiag; + const BYTE* const dict = state->dict; + const BYTE* const src = state->src; + + S32 const diagMin = dictLow - srcHigh; + S32 const diagMax = dictHigh - srcLow; + S32 const forwardMid = dictLow - srcLow; + S32 const backwardMid = dictHigh - srcHigh; + + S32 forwardMin = forwardMid; + S32 forwardMax = forwardMid; + S32 backwardMin = backwardMid; + S32 backwardMax = backwardMid; + int odd = (forwardMid - backwardMid) & 1; + U32 iterations; + + forwardDiag[forwardMid] = dictLow; + backwardDiag[backwardMid] = dictHigh; + + /* Main loop for updating diag entries. Unless useHeuristics is + * set to false, this loop will run until it finds the minimal + * edit script */ + for (iterations = 1;;iterations++) { + S32 diag; + int bigSnake = 0; + + if (forwardMin > diagMin) { + forwardMin--; + forwardDiag[forwardMin - 1] = -1; + } else { + forwardMin++; + } + + if (forwardMax < diagMax) { + forwardMax++; + forwardDiag[forwardMax + 1] = -1; + } else { + forwardMax--; + } + + for (diag = forwardMax; diag >= forwardMin; diag -= 2) { + S32 dictIdx; + S32 srcIdx; + S32 low = forwardDiag[diag - 1]; + S32 high = forwardDiag[diag + 1]; + S32 dictIdx0 = low < high ? high : low + 1; + + for (dictIdx = dictIdx0, srcIdx = dictIdx0 - diag; + dictIdx < dictHigh && srcIdx < srcHigh && dict[dictIdx] == src[srcIdx]; + dictIdx++, srcIdx++) continue; + + if (dictIdx - dictIdx0 > ZSTD_EDIST_SNAKE_THRESH) + bigSnake = 1; + + forwardDiag[diag] = dictIdx; + + if (odd && backwardMin <= diag && diag <= backwardMax && backwardDiag[diag] <= dictIdx) { + partition->dictMid = dictIdx; + partition->srcMid = srcIdx; + partition->lowUseHeuristics = 0; + partition->highUseHeuristics = 0; + return; + } + } + + if (backwardMin > diagMin) { + backwardMin--; + backwardDiag[backwardMin - 1] = ZSTD_EDIST_DIAG_MAX; + } else { + backwardMin++; + } + + if (backwardMax < diagMax) { + backwardMax++; + backwardDiag[backwardMax + 1] = ZSTD_EDIST_DIAG_MAX; + } else { + backwardMax--; + } + + + for (diag = backwardMax; diag >= backwardMin; diag -= 2) { + S32 dictIdx; + S32 srcIdx; + S32 low = backwardDiag[diag - 1]; + S32 high = backwardDiag[diag + 1]; + S32 dictIdx0 = low < high ? low : high - 1; + + for (dictIdx = dictIdx0, srcIdx = dictIdx0 - diag; + dictLow < dictIdx && srcLow < srcIdx && dict[dictIdx - 1] == src[srcIdx - 1]; + dictIdx--, srcIdx--) continue; + + if (dictIdx0 - dictIdx > ZSTD_EDIST_SNAKE_THRESH) + bigSnake = 1; + + backwardDiag[diag] = dictIdx; + + if (!odd && forwardMin <= diag && diag <= forwardMax && dictIdx <= forwardDiag[diag]) { + partition->dictMid = dictIdx; + partition->srcMid = srcIdx; + partition->lowUseHeuristics = 0; + partition->highUseHeuristics = 0; + return; + } + } + + if (!useHeuristics) + continue; + + /* Everything under this point is a heuristic. Using these will + * substantially speed up the match finding. In some cases, taking + * the total match finding time from several minutes to seconds. + * Of course, the caveat is that the edit script found may no longer + * be optimal */ + + /* Big snake heuristic */ + if (iterations > ZSTD_EDIST_SNAKE_ITER_THRESH && bigSnake) { + { + S32 best = 0; + + for (diag = forwardMax; diag >= forwardMin; diag -= 2) { + S32 diagDiag = diag - forwardMid; + S32 dictIdx = forwardDiag[diag]; + S32 srcIdx = dictIdx - diag; + S32 v = (dictIdx - dictLow) * 2 - diagDiag; + + if (v > 12 * (iterations + (diagDiag < 0 ? -diagDiag : diagDiag))) { + if (v > best + && dictLow + ZSTD_EDIST_SNAKE_THRESH <= dictIdx && dictIdx <= dictHigh + && srcLow + ZSTD_EDIST_SNAKE_THRESH <= srcIdx && srcIdx <= srcHigh) { + S32 k; + for (k = 1; dict[dictIdx - k] == src[srcIdx - k]; k++) { + if (k == ZSTD_EDIST_SNAKE_THRESH) { + best = v; + partition->dictMid = dictIdx; + partition->srcMid = srcIdx; + break; + } + } + } + } + } + + if (best > 0) { + partition->lowUseHeuristics = 0; + partition->highUseHeuristics = 1; + return; + } + } + + { + S32 best = 0; + + for (diag = backwardMax; diag >= backwardMin; diag -= 2) { + S32 diagDiag = diag - backwardMid; + S32 dictIdx = backwardDiag[diag]; + S32 srcIdx = dictIdx - diag; + S32 v = (dictHigh - dictIdx) * 2 + diagDiag; + + if (v > 12 * (iterations + (diagDiag < 0 ? -diagDiag : diagDiag))) { + if (v > best + && dictLow < dictIdx && dictIdx <= dictHigh - ZSTD_EDIST_SNAKE_THRESH + && srcLow < srcIdx && srcIdx <= srcHigh - ZSTD_EDIST_SNAKE_THRESH) { + int k; + for (k = 0; dict[dictIdx + k] == src[srcIdx + k]; k++) { + if (k == ZSTD_EDIST_SNAKE_THRESH - 1) { + best = v; + partition->dictMid = dictIdx; + partition->srcMid = srcIdx; + break; + } + } + } + } + } + + if (best > 0) { + partition->lowUseHeuristics = 1; + partition->highUseHeuristics = 0; + return; + } + } + } + + /* More general 'too expensive' heuristic */ + if (iterations >= ZSTD_EDIST_EXPENSIVE_THRESH) { + S32 forwardDictSrcBest; + S32 forwardDictBest = 0; + S32 backwardDictSrcBest; + S32 backwardDictBest = 0; + + forwardDictSrcBest = -1; + for (diag = forwardMax; diag >= forwardMin; diag -= 2) { + S32 dictIdx = MIN(forwardDiag[diag], dictHigh); + S32 srcIdx = dictIdx - diag; + + if (srcHigh < srcIdx) { + dictIdx = srcHigh + diag; + srcIdx = srcHigh; + } + + if (forwardDictSrcBest < dictIdx + srcIdx) { + forwardDictSrcBest = dictIdx + srcIdx; + forwardDictBest = dictIdx; + } + } + + backwardDictSrcBest = ZSTD_EDIST_DIAG_MAX; + for (diag = backwardMax; diag >= backwardMin; diag -= 2) { + S32 dictIdx = MAX(dictLow, backwardDiag[diag]); + S32 srcIdx = dictIdx - diag; + + if (srcIdx < srcLow) { + dictIdx = srcLow + diag; + srcIdx = srcLow; + } + + if (dictIdx + srcIdx < backwardDictSrcBest) { + backwardDictSrcBest = dictIdx + srcIdx; + backwardDictBest = dictIdx; + } + } + + if ((dictHigh + srcHigh) - backwardDictSrcBest < forwardDictSrcBest - (dictLow + srcLow)) { + partition->dictMid = forwardDictBest; + partition->srcMid = forwardDictSrcBest - forwardDictBest; + partition->lowUseHeuristics = 0; + partition->highUseHeuristics = 1; + } else { + partition->dictMid = backwardDictBest; + partition->srcMid = backwardDictSrcBest - backwardDictBest; + partition->lowUseHeuristics = 1; + partition->highUseHeuristics = 0; + } + return; + } + } +} + +static void ZSTD_eDist_insertMatch(ZSTD_eDist_state* state, + S32 const dictIdx, S32 const srcIdx) +{ + state->matches[state->nbMatches].dictIdx = dictIdx; + state->matches[state->nbMatches].srcIdx = srcIdx; + state->matches[state->nbMatches].matchLength = 1; + state->nbMatches++; +} + +static int ZSTD_eDist_compare(ZSTD_eDist_state* state, + S32 dictLow, S32 dictHigh, S32 srcLow, + S32 srcHigh, int useHeuristics) +{ + const BYTE* const dict = state->dict; + const BYTE* const src = state->src; + + /* Found matches while traversing from the low end */ + while (dictLow < dictHigh && srcLow < srcHigh && dict[dictLow] == src[srcLow]) { + ZSTD_eDist_insertMatch(state, dictLow, srcLow); + dictLow++; + srcLow++; + } + + /* Found matches while traversing from the high end */ + while (dictLow < dictHigh && srcLow < srcHigh && dict[dictHigh - 1] == src[srcHigh - 1]) { + ZSTD_eDist_insertMatch(state, dictHigh - 1, srcHigh - 1); + dictHigh--; + srcHigh--; + } + + /* If the low and high end end up touching. If we wanted to make + * note of the differences like most diffing algorithms do, we would + * do so here. In our case, we're only concerned with matches + * Note: if you wanted to find the edit distance of the algorithm, + * you could just accumulate the cost for an insertion/deletion + * below. */ + if (dictLow == dictHigh) { + while (srcLow < srcHigh) { + /* Reaching this point means inserting src[srcLow] into + * the current position of dict */ + srcLow++; + } + } else if (srcLow == srcHigh) { + while (dictLow < dictHigh) { + /* Reaching this point means deleting dict[dictLow] from + * the current position of dict */ + dictLow++; + } + } else { + ZSTD_eDist_partition partition; + partition.dictMid = 0; + partition.srcMid = 0; + ZSTD_eDist_diag(state, &partition, dictLow, dictHigh, + srcLow, srcHigh, useHeuristics); + if (ZSTD_eDist_compare(state, dictLow, partition.dictMid, + srcLow, partition.srcMid, partition.lowUseHeuristics)) + return 1; + if (ZSTD_eDist_compare(state, partition.dictMid, dictHigh, + partition.srcMid, srcHigh, partition.highUseHeuristics)) + return 1; + } + + return 0; +} + +static int ZSTD_eDist_matchComp(const void* p, const void* q) +{ + S32 const l = ((ZSTD_eDist_match*)p)->srcIdx; + S32 const r = ((ZSTD_eDist_match*)q)->srcIdx; + return (l - r); +} + +/* The matches from the approach above will all be of the form + * (dictIdx, srcIdx, 1). This method combines contiguous matches + * of length MINMATCH or greater. Matches less than MINMATCH + * are discarded */ +static void ZSTD_eDist_combineMatches(ZSTD_eDist_state* state) +{ + /* Create a new buffer to put the combined matches into + * and memcpy to state->matches after */ + ZSTD_eDist_match* combinedMatches = + ZSTD_malloc(state->nbMatches * sizeof(ZSTD_eDist_match), + ZSTD_defaultCMem); + + U32 nbCombinedMatches = 1; + size_t i; + + /* Make sure that the srcIdx and dictIdx are in sorted order. + * The combination step won't work otherwise */ + qsort(state->matches, state->nbMatches, sizeof(ZSTD_eDist_match), ZSTD_eDist_matchComp); + + memcpy(combinedMatches, state->matches, sizeof(ZSTD_eDist_match)); + for (i = 1; i < state->nbMatches; i++) { + ZSTD_eDist_match const match = state->matches[i]; + ZSTD_eDist_match const combinedMatch = + combinedMatches[nbCombinedMatches - 1]; + if (combinedMatch.srcIdx + combinedMatch.matchLength == match.srcIdx && + combinedMatch.dictIdx + combinedMatch.matchLength == match.dictIdx) { + combinedMatches[nbCombinedMatches - 1].matchLength++; + } else { + /* Discard matches that are less than MINMATCH */ + if (combinedMatches[nbCombinedMatches - 1].matchLength < MINMATCH) { + nbCombinedMatches--; + } + + memcpy(combinedMatches + nbCombinedMatches, + state->matches + i, sizeof(ZSTD_eDist_match)); + nbCombinedMatches++; + } + } + memcpy(state->matches, combinedMatches, nbCombinedMatches * sizeof(ZSTD_eDist_match)); + state->nbMatches = nbCombinedMatches; + ZSTD_free(combinedMatches, ZSTD_defaultCMem); +} + +static size_t ZSTD_eDist_convertMatchesToSequences(ZSTD_Sequence* sequences, + ZSTD_eDist_state* state) +{ + const ZSTD_eDist_match* matches = state->matches; + size_t const nbMatches = state->nbMatches; + size_t const dictSize = state->dictSize; + size_t nbSequences = 0; + size_t i; + for (i = 0; i < nbMatches; i++) { + ZSTD_eDist_match const match = matches[i]; + U32 const litLength = !i ? match.srcIdx : + match.srcIdx - (matches[i - 1].srcIdx + matches[i - 1].matchLength); + U32 const offset = (match.srcIdx + dictSize) - match.dictIdx; + U32 const matchLength = match.matchLength; + sequences[nbSequences].offset = offset; + sequences[nbSequences].litLength = litLength; + sequences[nbSequences].matchLength = matchLength; + nbSequences++; + } + return nbSequences; +} + +/*-************************************* +* Internal utils +***************************************/ + +static size_t ZSTD_eDist_hamingDist(const BYTE* const a, + const BYTE* const b, size_t n) +{ + size_t i; + size_t dist = 0; + for (i = 0; i < n; i++) + dist += a[i] != b[i]; + return dist; +} + +/* This is a pretty naive recursive implementation that should only + * be used for quick tests obviously. Don't try and run this on a + * GB file or something. There are faster implementations. Use those + * if you need to run it for large files. */ +static size_t ZSTD_eDist_levenshteinDist(const BYTE* const s, + size_t const sn, const BYTE* const t, + size_t const tn) +{ + size_t a, b, c; + + if (!sn) + return tn; + if (!tn) + return sn; + + if (s[sn - 1] == t[tn - 1]) + return ZSTD_eDist_levenshteinDist( + s, sn - 1, t, tn - 1); + + a = ZSTD_eDist_levenshteinDist(s, sn - 1, t, tn - 1); + b = ZSTD_eDist_levenshteinDist(s, sn, t, tn - 1); + c = ZSTD_eDist_levenshteinDist(s, sn - 1, t, tn); + + if (a > b) + a = b; + if (a > c) + a = c; + + return a + 1; +} + +static void ZSTD_eDist_validateMatches(ZSTD_eDist_match* matches, + size_t const nbMatches, const BYTE* const dict, + size_t const dictSize, const BYTE* const src, + size_t const srcSize) +{ + size_t i; + for (i = 0; i < nbMatches; i++) { + ZSTD_eDist_match match = matches[i]; + U32 const dictIdx = match.dictIdx; + U32 const srcIdx = match.srcIdx; + U32 const matchLength = match.matchLength; + + assert(dictIdx + matchLength < dictSize); + assert(srcIdx + matchLength < srcSize); + assert(!memcmp(dict + dictIdx, src + srcIdx, matchLength)); + } +} + +/*-************************************* +* API +***************************************/ + +size_t ZSTD_eDist_genSequences(ZSTD_Sequence* sequences, + const void* dict, size_t dictSize, + const void* src, size_t srcSize, + int useHeuristics) +{ + size_t const nbDiags = dictSize + srcSize + 3; + S32* buffer = ZSTD_malloc(nbDiags * 2 * sizeof(S32), ZSTD_defaultCMem); + ZSTD_eDist_state state; + size_t nbSequences = 0; + + state.dict = (const BYTE*)dict; + state.src = (const BYTE*)src; + state.dictSize = dictSize; + state.srcSize = srcSize; + state.forwardDiag = buffer; + state.backwardDiag = buffer + nbDiags; + state.forwardDiag += srcSize + 1; + state.backwardDiag += srcSize + 1; + state.matches = ZSTD_malloc(srcSize * sizeof(ZSTD_eDist_match), ZSTD_defaultCMem); + state.nbMatches = 0; + + ZSTD_eDist_compare(&state, 0, dictSize, 0, srcSize, 1); + ZSTD_eDist_combineMatches(&state); + nbSequences = ZSTD_eDist_convertMatchesToSequences(sequences, &state); + + ZSTD_free(buffer, ZSTD_defaultCMem); + ZSTD_free(state.matches, ZSTD_defaultCMem); + + return nbSequences; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/match_finders/zstd_edist.h b/cpp/third_party/zstd-1.5.7/contrib/match_finders/zstd_edist.h new file mode 100644 index 000000000..c739e2abc --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/match_finders/zstd_edist.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This match finder leverages techniques used in file comparison algorithms + * to find matches between a dictionary and a source file. + * + * The original motivation for studying this approach was to try and optimize + * Zstandard for the use case of patching: the most common scenario being + * updating an existing software package with the next version. When patching, + * the difference between the old version of the package and the new version + * is generally tiny (most of the new file will be identical to + * the old one). In more technical terms, the edit distance (the minimal number + * of changes required to take one sequence of bytes to another) between the + * files would be small relative to the size of the file. + * + * Various 'diffing' algorithms utilize this notion of edit distance and + * the corresponding concept of a minimal edit script between two + * sequences to identify the regions within two files where they differ. + * The core algorithm used in this match finder is described in: + * + * "An O(ND) Difference Algorithm and its Variations", Eugene W. Myers, + * Algorithmica Vol. 1, 1986, pp. 251-266, + * . + * + * Additional algorithmic heuristics for speed improvement have also been included. + * These we inspired from implementations of various regular and binary diffing + * algorithms such as GNU diff, bsdiff, and Xdelta. + * + * Note: after some experimentation, this approach proved to not provide enough + * utility to justify the additional CPU used in finding matches. The one area + * where this approach consistently outperforms Zstandard even on level 19 is + * when compressing small files (<10 KB) using an equally small dictionary that + * is very similar to the source file. For the use case that this was intended, + * (large similar files) this approach by itself took 5-10X longer than zstd-19 and + * generally resulted in 2-3X larger files. The core advantage that zstd-19 has + * over this approach for match finding is the overlapping matches. This approach + * cannot find any. + * + * I'm leaving this in the contrib section in case this ever becomes interesting + * to explore again. + * */ + +#ifndef ZSTD_EDIST_H +#define ZSTD_EDIST_H + +/*-************************************* +* Dependencies +***************************************/ + +#include +#include "zstd_internal.h" /* ZSTD_Sequence */ + +/*! ZSTD_eDist_genSequences() : + * Will populate the provided ZSTD_Sequence buffer with sequences + * based on the optimal or near-optimal (depending on 'useHeuristics') + * edit script between 'dict' and 'src.' + * @return : the number of sequences found */ +size_t ZSTD_eDist_genSequences(ZSTD_Sequence* sequences, + const void* dict, size_t dictSize, + const void* src, size_t srcSize, + int useHeuristics); + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/premake/premake4.lua b/cpp/third_party/zstd-1.5.7/contrib/premake/premake4.lua new file mode 100644 index 000000000..6675e2e48 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/premake/premake4.lua @@ -0,0 +1,6 @@ +-- Include zstd.lua in your GENie or premake4 file, which exposes a project_zstd function +dofile('zstd.lua') + +solution 'example' + configurations { 'Debug', 'Release' } + project_zstd('../../lib/') diff --git a/cpp/third_party/zstd-1.5.7/contrib/premake/zstd.lua b/cpp/third_party/zstd-1.5.7/contrib/premake/zstd.lua new file mode 100644 index 000000000..df1ace3ee --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/premake/zstd.lua @@ -0,0 +1,80 @@ +-- This GENie/premake file copies the behavior of the Makefile in the lib folder. +-- Basic usage: project_zstd(ZSTD_DIR) + +function project_zstd(dir, compression, decompression, deprecated, dictbuilder, legacy) + if compression == nil then compression = true end + if decompression == nil then decompression = true end + if deprecated == nil then deprecated = false end + if dictbuilder == nil then dictbuilder = false end + + if legacy == nil then legacy = 0 end + + if not compression then + dictbuilder = false + deprecated = false + end + + if not decompression then + legacy = 0 + deprecated = false + end + + project 'zstd' + kind 'StaticLib' + language 'C' + + files { + dir .. 'zstd.h', + dir .. 'common/**.c', + dir .. 'common/**.h' + } + + if compression then + files { + dir .. 'compress/**.c', + dir .. 'compress/**.h' + } + end + + if decompression then + files { + dir .. 'decompress/**.c', + dir .. 'decompress/**.h' + } + end + + if dictbuilder then + files { + dir .. 'dictBuilder/**.c', + dir .. 'dictBuilder/**.h' + } + end + + if deprecated then + files { + dir .. 'deprecated/**.c', + dir .. 'deprecated/**.h' + } + end + + if legacy ~= 0 then + if legacy >= 8 then + files { + dir .. 'legacy/zstd_v0' .. (legacy - 7) .. '.*' + } + end + includedirs { + dir .. 'legacy' + } + end + + includedirs { + dir, + dir .. 'common' + } + + defines { + 'XXH_NAMESPACE=ZSTD_', + 'ZSTD_LEGACY_SUPPORT=' .. legacy + } +end diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/.gitignore b/cpp/third_party/zstd-1.5.7/contrib/pzstd/.gitignore new file mode 100644 index 000000000..84e68fb07 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/.gitignore @@ -0,0 +1,2 @@ +# compilation result +pzstd diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/BUCK b/cpp/third_party/zstd-1.5.7/contrib/pzstd/BUCK new file mode 100644 index 000000000..d04eeedd8 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/BUCK @@ -0,0 +1,72 @@ +cxx_library( + name='libpzstd', + visibility=['PUBLIC'], + header_namespace='', + exported_headers=[ + 'ErrorHolder.h', + 'Logging.h', + 'Pzstd.h', + ], + headers=[ + 'SkippableFrame.h', + ], + srcs=[ + 'Pzstd.cpp', + 'SkippableFrame.cpp', + ], + deps=[ + ':options', + '//contrib/pzstd/utils:utils', + '//lib:mem', + '//lib:zstd', + ], +) + +cxx_library( + name='options', + visibility=['PUBLIC'], + header_namespace='', + exported_headers=['Options.h'], + srcs=['Options.cpp'], + deps=[ + '//contrib/pzstd/utils:scope_guard', + '//lib:zstd', + '//programs:util', + ], +) + +cxx_binary( + name='pzstd', + visibility=['PUBLIC'], + srcs=['main.cpp'], + deps=[ + ':libpzstd', + ':options', + ], +) + +# Must run "make googletest" first +cxx_library( + name='gtest', + srcs=glob([ + 'googletest/googletest/src/gtest-all.cc', + 'googletest/googlemock/src/gmock-all.cc', + 'googletest/googlemock/src/gmock_main.cc', + ]), + header_namespace='', + exported_headers=subdir_glob([ + ('googletest/googletest/include', '**/*.h'), + ('googletest/googlemock/include', '**/*.h'), + ]), + headers=subdir_glob([ + ('googletest/googletest', 'src/*.cc'), + ('googletest/googletest', 'src/*.h'), + ('googletest/googlemock', 'src/*.cc'), + ('googletest/googlemock', 'src/*.h'), + ]), + platform_linker_flags=[ + ('android', []), + ('', ['-lpthread']), + ], + visibility=['PUBLIC'], +) diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/ErrorHolder.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/ErrorHolder.h new file mode 100644 index 000000000..2c2797ede --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/ErrorHolder.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include +#include +#include +#include + +namespace pzstd { + +// Coordinates graceful shutdown of the pzstd pipeline +class ErrorHolder { + std::atomic error_; + std::string message_; + + public: + ErrorHolder() : error_(false) {} + + bool hasError() noexcept { + return error_.load(); + } + + void setError(std::string message) noexcept { + // Given multiple possibly concurrent calls, exactly one will ever succeed. + bool expected = false; + if (error_.compare_exchange_strong(expected, true)) { + message_ = std::move(message); + } + } + + bool check(bool predicate, std::string message) noexcept { + if (!predicate) { + setError(std::move(message)); + } + return !hasError(); + } + + std::string getError() noexcept { + error_.store(false); + return std::move(message_); + } + + ~ErrorHolder() { + assert(!hasError()); + } +}; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/Logging.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Logging.h new file mode 100644 index 000000000..84a08d200 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Logging.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include +#include + +namespace pzstd { + +constexpr int kLogError = 1; +constexpr int kLogInfo = 2; +constexpr int kLogDebug = 3; +constexpr int kLogVerbose = 4; + +class Logger { + std::mutex mutex_; + FILE* out_; + const int level_; + + using Clock = std::chrono::system_clock; + Clock::time_point lastUpdate_; + std::chrono::milliseconds refreshRate_; + + public: + explicit Logger(int level, FILE* out = stderr) + : out_(out), level_(level), lastUpdate_(Clock::now()), + refreshRate_(150) {} + + + bool logsAt(int level) { + return level <= level_; + } + + template + void operator()(int level, const char *fmt, Args... args) { + if (level > level_) { + return; + } + std::lock_guard lock(mutex_); + std::fprintf(out_, fmt, args...); + } + + template + void update(int level, const char *fmt, Args... args) { + if (level > level_) { + return; + } + std::lock_guard lock(mutex_); + auto now = Clock::now(); + if (now - lastUpdate_ > refreshRate_) { + lastUpdate_ = now; + std::fprintf(out_, "\r"); + std::fprintf(out_, fmt, args...); + } + } + + void clear(int level) { + if (level > level_) { + return; + } + std::lock_guard lock(mutex_); + std::fprintf(out_, "\r%79s\r", ""); + } +}; + +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/Makefile b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Makefile new file mode 100644 index 000000000..e4b3e8a21 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Makefile @@ -0,0 +1,265 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +# Standard variables for installation +DESTDIR ?= +PREFIX ?= /usr/local +BINDIR := $(PREFIX)/bin + +ZSTDDIR = ../../lib +PROGDIR = ../../programs + +# External program to use to run tests, e.g. qemu or valgrind +TESTPROG ?= +# Flags to pass to the tests +TESTFLAGS ?= + +# We use gcc/clang to generate the header dependencies of files +DEPFLAGS = -MMD -MP -MF $*.Td +POSTCOMPILE = mv -f $*.Td $*.d + +# CFLAGS, CXXFLAGS, CPPFLAGS, and LDFLAGS are for the users to override +CFLAGS ?= -O3 -Wall -Wextra +CXXFLAGS ?= -O3 -Wall -Wextra -pedantic +CPPFLAGS ?= +LDFLAGS ?= + +# PZstd uses legacy APIs +CFLAGS += -Wno-deprecated-declarations + +# Include flags +PZSTD_INC = -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I. +GTEST_INC = -isystem googletest/googletest/include + +# Set the minimum required by gtest +PZSTD_CXX_STD := -std=c++14 + +PZSTD_CPPFLAGS = $(PZSTD_INC) +PZSTD_CCXXFLAGS = +PZSTD_CFLAGS = $(PZSTD_CCXXFLAGS) +PZSTD_CXXFLAGS = $(PZSTD_CCXXFLAGS) $(PZSTD_CXX_STD) +PZSTD_LDFLAGS = +EXTRA_FLAGS = +ALL_CFLAGS = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CFLAGS) $(PZSTD_CFLAGS) +ALL_CXXFLAGS = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CXXFLAGS) $(PZSTD_CXXFLAGS) +ALL_LDFLAGS = $(EXTRA_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(PZSTD_LDFLAGS) + + +# gtest libraries need to go before "-lpthread" because they depend on it. +GTEST_LIB = -L googletest/build/googlemock/gtest +LIBS = + +# Compilation commands +LD_COMMAND = $(CXX) $^ $(ALL_LDFLAGS) $(LIBS) -pthread -o $@ +CC_COMMAND = $(CC) $(DEPFLAGS) $(ALL_CFLAGS) -c $< -o $@ +CXX_COMMAND = $(CXX) $(DEPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@ + +# List all the pzstd source files so we can determine their dependencies +PZSTD_SRCS := $(wildcard *.cpp) +PZSTD_TESTS := $(wildcard test/*.cpp) +UTILS_TESTS := $(wildcard utils/test/*.cpp) +ALL_SRCS := $(PZSTD_SRCS) $(PZSTD_TESTS) $(UTILS_TESTS) + + +# Define *.exe as extension for Windows systems +ifneq (,$(filter Windows%,$(OS))) +EXT =.exe +else +EXT = +endif + +# Standard targets +.PHONY: default +default: all + +.PHONY: test-pzstd +test-pzstd: TESTFLAGS=--gtest_filter=-*ExtremelyLarge* +test-pzstd: clean googletest pzstd tests check + +.PHONY: test-pzstd32 +test-pzstd32: clean googletest32 all32 check + +.PHONY: test-pzstd-tsan +test-pzstd-tsan: LDFLAGS=-fuse-ld=gold +test-pzstd-tsan: TESTFLAGS=--gtest_filter=-*ExtremelyLarge* +test-pzstd-tsan: clean googletest tsan check + +.PHONY: test-pzstd-asan +test-pzstd-asan: LDFLAGS=-fuse-ld=gold +test-pzstd-asan: TESTFLAGS=--gtest_filter=-*ExtremelyLarge* +test-pzstd-asan: clean asan check + +.PHONY: check +check: + $(TESTPROG) ./utils/test/BufferTest$(EXT) $(TESTFLAGS) + $(TESTPROG) ./utils/test/RangeTest$(EXT) $(TESTFLAGS) + $(TESTPROG) ./utils/test/ResourcePoolTest$(EXT) $(TESTFLAGS) + $(TESTPROG) ./utils/test/ScopeGuardTest$(EXT) $(TESTFLAGS) + $(TESTPROG) ./utils/test/ThreadPoolTest$(EXT) $(TESTFLAGS) + $(TESTPROG) ./utils/test/WorkQueueTest$(EXT) $(TESTFLAGS) + $(TESTPROG) ./test/OptionsTest$(EXT) $(TESTFLAGS) + $(TESTPROG) ./test/PzstdTest$(EXT) $(TESTFLAGS) + +.PHONY: install +install: PZSTD_CPPFLAGS += -DNDEBUG +install: pzstd$(EXT) + install -d -m 755 $(DESTDIR)$(BINDIR)/ + install -m 755 pzstd$(EXT) $(DESTDIR)$(BINDIR)/pzstd$(EXT) + +.PHONY: uninstall +uninstall: + $(RM) $(DESTDIR)$(BINDIR)/pzstd$(EXT) + +# Targets for many different builds +.PHONY: all +all: PZSTD_CPPFLAGS += -DNDEBUG +all: pzstd$(EXT) + +.PHONY: debug +debug: EXTRA_FLAGS += -g +debug: pzstd$(EXT) tests roundtrip + +.PHONY: tsan +tsan: PZSTD_CCXXFLAGS += -fsanitize=thread -fPIC +tsan: PZSTD_LDFLAGS += -fsanitize=thread +tsan: debug + +.PHONY: asan +asan: EXTRA_FLAGS += -fsanitize=address +asan: debug + +.PHONY: ubsan +ubsan: EXTRA_FLAGS += -fsanitize=undefined +ubsan: debug + +.PHONY: all32 +all32: EXTRA_FLAGS += -m32 +all32: all tests roundtrip + +.PHONY: debug32 +debug32: EXTRA_FLAGS += -m32 +debug32: debug + +.PHONY: asan32 +asan32: EXTRA_FLAGS += -m32 +asan32: asan + +.PHONY: tsan32 +tsan32: EXTRA_FLAGS += -m32 +tsan32: tsan + +.PHONY: ubsan32 +ubsan32: EXTRA_FLAGS += -m32 +ubsan32: ubsan + +# Run long round trip tests +.PHONY: roundtripcheck +roundtripcheck: roundtrip check + $(TESTPROG) ./test/RoundTripTest$(EXT) $(TESTFLAGS) + +# Build the main binary +pzstd$(EXT): main.o $(PROGDIR)/util.o Options.o Pzstd.o SkippableFrame.o $(ZSTDDIR)/libzstd.a + $(LD_COMMAND) + +# Target that depends on all the tests +.PHONY: tests +tests: EXTRA_FLAGS += -Wno-deprecated-declarations +tests: $(patsubst %,%$(EXT),$(basename $(PZSTD_TESTS) $(UTILS_TESTS))) + +# Build the round trip tests +.PHONY: roundtrip +roundtrip: EXTRA_FLAGS += -Wno-deprecated-declarations +roundtrip: test/RoundTripTest$(EXT) + +# Use the static library that zstd builds for simplicity and +# so we get the compiler options correct +.PHONY: $(ZSTDDIR)/libzstd.a +$(ZSTDDIR)/libzstd.a: + CFLAGS="$(ALL_CFLAGS)" LDFLAGS="$(ALL_LDFLAGS)" $(MAKE) -C $(ZSTDDIR) libzstd.a + +# Rules to build the tests +test/RoundTripTest$(EXT): test/RoundTripTest.o $(PROGDIR)/datagen.o \ + $(PROGDIR)/util.o Options.o \ + Pzstd.o SkippableFrame.o $(ZSTDDIR)/libzstd.a + $(LD_COMMAND) + +test/%Test$(EXT): PZSTD_LDFLAGS += $(GTEST_LIB) +test/%Test$(EXT): LIBS += -lgtest -lgtest_main +test/%Test$(EXT): test/%Test.o $(PROGDIR)/datagen.o \ + $(PROGDIR)/util.o Options.o Pzstd.o \ + SkippableFrame.o $(ZSTDDIR)/libzstd.a + $(LD_COMMAND) + +utils/test/%Test$(EXT): PZSTD_LDFLAGS += $(GTEST_LIB) +utils/test/%Test$(EXT): LIBS += -lgtest -lgtest_main +utils/test/%Test$(EXT): utils/test/%Test.o + $(LD_COMMAND) + + +GTEST_CMAKEFLAGS = + +# Install googletest +.PHONY: googletest +googletest: PZSTD_CCXXFLAGS += -fPIC +googletest: + @$(RM) -rf googletest + @git clone https://github.com/google/googletest + @mkdir -p googletest/build + @cd googletest/build && cmake $(GTEST_CMAKEFLAGS) -DCMAKE_CXX_FLAGS="$(ALL_CXXFLAGS)" .. && $(MAKE) + +.PHONY: googletest32 +googletest32: PZSTD_CCXXFLAGS += -m32 +googletest32: googletest + +.PHONY: googletest-mingw64 +googletest-mingw64: GTEST_CMAKEFLAGS += -G "MSYS Makefiles" +googletest-mingw64: googletest + +.PHONY: clean +clean: + $(RM) -f *.o pzstd$(EXT) *.Td *.d + $(RM) -f test/*.o test/*Test$(EXT) test/*.Td test/*.d + $(RM) -f utils/test/*.o utils/test/*Test$(EXT) utils/test/*.Td utils/test/*.d + $(RM) -f $(PROGDIR)/*.o $(PROGDIR)/*.Td $(PROGDIR)/*.d + $(MAKE) -C $(ZSTDDIR) clean + @echo Cleaning completed + + +# Cancel implicit rules +%.o: %.c +%.o: %.cpp + +# Object file rules +%.o: %.c + $(CC_COMMAND) + $(POSTCOMPILE) + +$(PROGDIR)/%.o: $(PROGDIR)/%.c + $(CC_COMMAND) + $(POSTCOMPILE) + +%.o: %.cpp + $(CXX_COMMAND) + $(POSTCOMPILE) + +test/%.o: PZSTD_CPPFLAGS += $(GTEST_INC) +test/%.o: test/%.cpp + $(CXX_COMMAND) + $(POSTCOMPILE) + +utils/test/%.o: PZSTD_CPPFLAGS += $(GTEST_INC) +utils/test/%.o: utils/test/%.cpp + $(CXX_COMMAND) + $(POSTCOMPILE) + +# Dependency file stuff +.PRECIOUS: %.d test/%.d utils/test/%.d + +# Include rules that specify header file dependencies +-include $(patsubst %,%.d,$(basename $(ALL_SRCS))) diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/Options.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Options.cpp new file mode 100644 index 000000000..90841b9bb --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Options.cpp @@ -0,0 +1,424 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "Options.h" +#include "util.h" +#include "utils/ScopeGuard.h" + +#include +#include +#include +#include +#include +#include +#include + + +namespace pzstd { + +namespace { +unsigned defaultNumThreads() { +#ifdef PZSTD_NUM_THREADS + return PZSTD_NUM_THREADS; +#else + return std::thread::hardware_concurrency(); +#endif +} + +unsigned parseUnsigned(const char **arg) { + unsigned result = 0; + while (**arg >= '0' && **arg <= '9') { + result *= 10; + result += **arg - '0'; + ++(*arg); + } + return result; +} + +const char *getArgument(const char *options, const char **argv, int &i, + int argc) { + if (options[1] != 0) { + return options + 1; + } + ++i; + if (i == argc) { + std::fprintf(stderr, "Option -%c requires an argument, but none provided\n", + *options); + return nullptr; + } + return argv[i]; +} + +const std::string kZstdExtension = ".zst"; +constexpr char kStdIn[] = "-"; +constexpr char kStdOut[] = "-"; +constexpr unsigned kDefaultCompressionLevel = 3; +constexpr unsigned kMaxNonUltraCompressionLevel = 19; + +#ifdef _WIN32 +const char nullOutput[] = "nul"; +#else +const char nullOutput[] = "/dev/null"; +#endif + +void notSupported(const char *option) { + std::fprintf(stderr, "Operation not supported: %s\n", option); +} + +void usage() { + std::fprintf(stderr, "Usage:\n"); + std::fprintf(stderr, " pzstd [args] [FILE(s)]\n"); + std::fprintf(stderr, "Parallel ZSTD options:\n"); + std::fprintf(stderr, " -p, --processes # : number of threads to use for (de)compression (default:)\n"); + + std::fprintf(stderr, "ZSTD options:\n"); + std::fprintf(stderr, " -# : # compression level (1-%d, default:%d)\n", kMaxNonUltraCompressionLevel, kDefaultCompressionLevel); + std::fprintf(stderr, " -d, --decompress : decompression\n"); + std::fprintf(stderr, " -o file : result stored into `file` (only if 1 input file)\n"); + std::fprintf(stderr, " -f, --force : overwrite output without prompting, (de)compress links\n"); + std::fprintf(stderr, " --rm : remove source file(s) after successful (de)compression\n"); + std::fprintf(stderr, " -k, --keep : preserve source file(s) (default)\n"); + std::fprintf(stderr, " -h, --help : display help and exit\n"); + std::fprintf(stderr, " -V, --version : display version number and exit\n"); + std::fprintf(stderr, " -v, --verbose : verbose mode; specify multiple times to increase log level (default:2)\n"); + std::fprintf(stderr, " -q, --quiet : suppress warnings; specify twice to suppress errors too\n"); + std::fprintf(stderr, " -c, --stdout : write to standard output (even if it is the console)\n"); +#ifdef UTIL_HAS_CREATEFILELIST + std::fprintf(stderr, " -r : operate recursively on directories\n"); +#endif + std::fprintf(stderr, " --ultra : enable levels beyond %i, up to %i (requires more memory)\n", kMaxNonUltraCompressionLevel, ZSTD_maxCLevel()); + std::fprintf(stderr, " -C, --check : integrity check (default)\n"); + std::fprintf(stderr, " --no-check : no integrity check\n"); + std::fprintf(stderr, " -t, --test : test compressed file integrity\n"); + std::fprintf(stderr, " -- : all arguments after \"--\" are treated as files\n"); +} +} // anonymous namespace + +Options::Options() + : numThreads(defaultNumThreads()), maxWindowLog(23), + compressionLevel(kDefaultCompressionLevel), decompress(false), + overwrite(false), keepSource(true), writeMode(WriteMode::Auto), + checksum(true), verbosity(2) {} + +Options::Status Options::parse(int argc, const char **argv) { + bool test = false; + bool recursive = false; + bool ultra = false; + bool forceStdout = false; + bool followLinks = false; + // Local copy of input files, which are pointers into argv. + std::vector localInputFiles; + for (int i = 1; i < argc; ++i) { + const char *arg = argv[i]; + // Protect against empty arguments + if (arg[0] == 0) { + continue; + } + // Everything after "--" is an input file + if (!std::strcmp(arg, "--")) { + ++i; + std::copy(argv + i, argv + argc, std::back_inserter(localInputFiles)); + break; + } + // Long arguments that don't have a short option + { + bool isLongOption = true; + if (!std::strcmp(arg, "--rm")) { + keepSource = false; + } else if (!std::strcmp(arg, "--ultra")) { + ultra = true; + maxWindowLog = 0; + } else if (!std::strcmp(arg, "--no-check")) { + checksum = false; + } else if (!std::strcmp(arg, "--sparse")) { + writeMode = WriteMode::Sparse; + notSupported("Sparse mode"); + return Status::Failure; + } else if (!std::strcmp(arg, "--no-sparse")) { + writeMode = WriteMode::Regular; + notSupported("Sparse mode"); + return Status::Failure; + } else if (!std::strcmp(arg, "--dictID")) { + notSupported(arg); + return Status::Failure; + } else if (!std::strcmp(arg, "--no-dictID")) { + notSupported(arg); + return Status::Failure; + } else { + isLongOption = false; + } + if (isLongOption) { + continue; + } + } + // Arguments with a short option simply set their short option. + const char *options = nullptr; + if (!std::strcmp(arg, "--processes")) { + options = "p"; + } else if (!std::strcmp(arg, "--version")) { + options = "V"; + } else if (!std::strcmp(arg, "--help")) { + options = "h"; + } else if (!std::strcmp(arg, "--decompress")) { + options = "d"; + } else if (!std::strcmp(arg, "--force")) { + options = "f"; + } else if (!std::strcmp(arg, "--stdout")) { + options = "c"; + } else if (!std::strcmp(arg, "--keep")) { + options = "k"; + } else if (!std::strcmp(arg, "--verbose")) { + options = "v"; + } else if (!std::strcmp(arg, "--quiet")) { + options = "q"; + } else if (!std::strcmp(arg, "--check")) { + options = "C"; + } else if (!std::strcmp(arg, "--test")) { + options = "t"; + } else if (arg[0] == '-' && arg[1] != 0) { + options = arg + 1; + } else { + localInputFiles.emplace_back(arg); + continue; + } + assert(options != nullptr); + + bool finished = false; + while (!finished && *options != 0) { + // Parse the compression level + if (*options >= '0' && *options <= '9') { + compressionLevel = parseUnsigned(&options); + continue; + } + + switch (*options) { + case 'h': + case 'H': + usage(); + return Status::Message; + case 'V': + std::fprintf(stderr, "PZSTD version: %s.\n", ZSTD_VERSION_STRING); + return Status::Message; + case 'p': { + finished = true; + const char *optionArgument = getArgument(options, argv, i, argc); + if (optionArgument == nullptr) { + return Status::Failure; + } + if (*optionArgument < '0' || *optionArgument > '9') { + std::fprintf(stderr, "Option -p expects a number, but %s provided\n", + optionArgument); + return Status::Failure; + } + numThreads = parseUnsigned(&optionArgument); + if (*optionArgument != 0) { + std::fprintf(stderr, + "Option -p expects a number, but %u%s provided\n", + numThreads, optionArgument); + return Status::Failure; + } + break; + } + case 'o': { + finished = true; + const char *optionArgument = getArgument(options, argv, i, argc); + if (optionArgument == nullptr) { + return Status::Failure; + } + outputFile = optionArgument; + break; + } + case 'C': + checksum = true; + break; + case 'k': + keepSource = true; + break; + case 'd': + decompress = true; + break; + case 'f': + overwrite = true; + forceStdout = true; + followLinks = true; + break; + case 't': + test = true; + decompress = true; + break; +#ifdef UTIL_HAS_CREATEFILELIST + case 'r': + recursive = true; + break; +#endif + case 'c': + outputFile = kStdOut; + forceStdout = true; + break; + case 'v': + ++verbosity; + break; + case 'q': + --verbosity; + // Ignore them for now + break; + // Unsupported options from Zstd + case 'D': + case 's': + notSupported("Zstd dictionaries."); + return Status::Failure; + case 'b': + case 'e': + case 'i': + case 'B': + notSupported("Zstd benchmarking options."); + return Status::Failure; + default: + std::fprintf(stderr, "Invalid argument: %s\n", arg); + return Status::Failure; + } + if (!finished) { + ++options; + } + } // while (*options != 0); + } // for (int i = 1; i < argc; ++i); + + // Set options for test mode + if (test) { + outputFile = nullOutput; + keepSource = true; + } + + // Input file defaults to standard input if not provided. + if (localInputFiles.empty()) { + localInputFiles.emplace_back(kStdIn); + } + + // Check validity of input files + if (localInputFiles.size() > 1) { + const auto it = std::find(localInputFiles.begin(), localInputFiles.end(), + std::string{kStdIn}); + if (it != localInputFiles.end()) { + std::fprintf( + stderr, + "Cannot specify standard input when handling multiple files\n"); + return Status::Failure; + } + } + if (localInputFiles.size() > 1 || recursive) { + if (!outputFile.empty() && outputFile != nullOutput) { + std::fprintf( + stderr, + "Cannot specify an output file when handling multiple inputs\n"); + return Status::Failure; + } + } + + g_utilDisplayLevel = verbosity; + // Remove local input files that are symbolic links + if (!followLinks) { + localInputFiles.erase(std::remove_if(localInputFiles.begin(), localInputFiles.end(), + [&](const char *path) { + bool isLink = UTIL_isLink(path); + if (isLink && verbosity >= 2) { + std::fprintf( + stderr, + "Warning : %s is symbolic link, ignoring\n", + path); + } + return isLink; + }), localInputFiles.end()); + } + + // Translate input files/directories into files to (de)compress + if (recursive) { + FileNamesTable* const files = UTIL_createExpandedFNT(localInputFiles.data(), localInputFiles.size(), followLinks); + if (files == nullptr) { + std::fprintf(stderr, "Error traversing directories\n"); + return Status::Failure; + } + auto guard = + makeScopeGuard([&] { UTIL_freeFileNamesTable(files); }); + if (files->tableSize == 0) { + std::fprintf(stderr, "No files found\n"); + return Status::Failure; + } + inputFiles.resize(files->tableSize); + std::copy(files->fileNames, files->fileNames + files->tableSize, inputFiles.begin()); + } else { + inputFiles.resize(localInputFiles.size()); + std::copy(localInputFiles.begin(), localInputFiles.end(), + inputFiles.begin()); + } + localInputFiles.clear(); + assert(!inputFiles.empty()); + + // If reading from standard input, default to standard output + if (inputFiles[0] == kStdIn && outputFile.empty()) { + assert(inputFiles.size() == 1); + outputFile = "-"; + } + + if (inputFiles[0] == kStdIn && IS_CONSOLE(stdin)) { + assert(inputFiles.size() == 1); + std::fprintf(stderr, "Cannot read input from interactive console\n"); + return Status::Failure; + } + if (outputFile == "-" && IS_CONSOLE(stdout) && !(forceStdout && decompress)) { + std::fprintf(stderr, "Will not write to console stdout unless -c or -f is " + "specified and decompressing\n"); + return Status::Failure; + } + + // Check compression level + { + unsigned maxCLevel = + ultra ? ZSTD_maxCLevel() : kMaxNonUltraCompressionLevel; + if (compressionLevel > maxCLevel || compressionLevel == 0) { + std::fprintf(stderr, "Invalid compression level %u.\n", compressionLevel); + return Status::Failure; + } + } + + // Check that numThreads is set + if (numThreads == 0) { + std::fprintf(stderr, "Invalid arguments: # of threads not specified " + "and unable to determine hardware concurrency.\n"); + return Status::Failure; + } + + // Modify verbosity + // If we are piping input and output, turn off interaction + if (inputFiles[0] == kStdIn && outputFile == kStdOut && verbosity == 2) { + verbosity = 1; + } + // If we are in multi-file mode, turn off interaction + if (inputFiles.size() > 1 && verbosity == 2) { + verbosity = 1; + } + + return Status::Success; +} + +std::string Options::getOutputFile(const std::string &inputFile) const { + if (!outputFile.empty()) { + return outputFile; + } + // Attempt to add/remove zstd extension from the input file + if (decompress) { + int stemSize = inputFile.size() - kZstdExtension.size(); + if (stemSize > 0 && inputFile.substr(stemSize) == kZstdExtension) { + return inputFile.substr(0, stemSize); + } else { + return ""; + } + } else { + return inputFile + kZstdExtension; + } +} +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/Options.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Options.h new file mode 100644 index 000000000..92c18a350 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Options.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#define ZSTD_STATIC_LINKING_ONLY +#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* No deprecation warnings, pzstd itself is deprecated + * and uses deprecated functions + */ +#include "zstd.h" +#undef ZSTD_STATIC_LINKING_ONLY + +#include +#include +#include + +namespace pzstd { + +struct Options { + enum class WriteMode { Regular, Auto, Sparse }; + + unsigned numThreads; + unsigned maxWindowLog; + unsigned compressionLevel; + bool decompress; + std::vector inputFiles; + std::string outputFile; + bool overwrite; + bool keepSource; + WriteMode writeMode; + bool checksum; + int verbosity; + + enum class Status { + Success, // Successfully parsed options + Failure, // Failure to parse options + Message // Options specified to print a message (e.g. "-h") + }; + + Options(); + Options(unsigned numThreads, unsigned maxWindowLog, unsigned compressionLevel, + bool decompress, std::vector inputFiles, + std::string outputFile, bool overwrite, bool keepSource, + WriteMode writeMode, bool checksum, int verbosity) + : numThreads(numThreads), maxWindowLog(maxWindowLog), + compressionLevel(compressionLevel), decompress(decompress), + inputFiles(std::move(inputFiles)), outputFile(std::move(outputFile)), + overwrite(overwrite), keepSource(keepSource), writeMode(writeMode), + checksum(checksum), verbosity(verbosity) {} + + Status parse(int argc, const char **argv); + + ZSTD_parameters determineParameters() const { + ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, 0); + params.fParams.contentSizeFlag = 0; + params.fParams.checksumFlag = checksum; + if (maxWindowLog != 0 && params.cParams.windowLog > maxWindowLog) { + params.cParams.windowLog = maxWindowLog; + params.cParams = ZSTD_adjustCParams(params.cParams, 0, 0); + } + return params; + } + + std::string getOutputFile(const std::string &inputFile) const; +}; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/Pzstd.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Pzstd.cpp new file mode 100644 index 000000000..048a006b3 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Pzstd.cpp @@ -0,0 +1,626 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "platform.h" /* Large Files support, SET_BINARY_MODE */ +#include "Pzstd.h" +#include "SkippableFrame.h" +#include "utils/FileSystem.h" +#include "utils/Portability.h" +#include "utils/Range.h" +#include "utils/ScopeGuard.h" +#include "utils/ThreadPool.h" +#include "utils/WorkQueue.h" + +#include +#include +#include +#include +#include +#include +#include + + +namespace pzstd { + +namespace { +#ifdef _WIN32 +const std::string nullOutput = "nul"; +#else +const std::string nullOutput = "/dev/null"; +#endif +} + +using std::size_t; + +static std::uintmax_t fileSizeOrZero(const std::string &file) { + if (file == "-") { + return 0; + } + std::error_code ec; + auto size = file_size(file, ec); + if (ec) { + size = 0; + } + return size; +} + +static std::uint64_t handleOneInput(const Options &options, + const std::string &inputFile, + FILE* inputFd, + const std::string &outputFile, + FILE* outputFd, + SharedState& state) { + auto inputSize = fileSizeOrZero(inputFile); + // WorkQueue outlives ThreadPool so in the case of error we are certain + // we don't accidentally try to call push() on it after it is destroyed + WorkQueue> outs{options.numThreads + 1}; + std::uint64_t bytesRead; + std::uint64_t bytesWritten; + { + // Initialize the (de)compression thread pool with numThreads + ThreadPool executor(options.numThreads); + // Run the reader thread on an extra thread + ThreadPool readExecutor(1); + if (!options.decompress) { + // Add a job that reads the input and starts all the compression jobs + readExecutor.add( + [&state, &outs, &executor, inputFd, inputSize, &options, &bytesRead] { + bytesRead = asyncCompressChunks( + state, + outs, + executor, + inputFd, + inputSize, + options.numThreads, + options.determineParameters()); + }); + // Start writing + bytesWritten = writeFile(state, outs, outputFd, options.decompress); + } else { + // Add a job that reads the input and starts all the decompression jobs + readExecutor.add([&state, &outs, &executor, inputFd, &bytesRead] { + bytesRead = asyncDecompressFrames(state, outs, executor, inputFd); + }); + // Start writing + bytesWritten = writeFile(state, outs, outputFd, options.decompress); + } + } + if (!state.errorHolder.hasError()) { + std::string inputFileName = inputFile == "-" ? "stdin" : inputFile; + std::string outputFileName = outputFile == "-" ? "stdout" : outputFile; + if (!options.decompress) { + double ratio = static_cast(bytesWritten) / + static_cast(bytesRead + !bytesRead); + state.log(kLogInfo, "%-20s :%6.2f%% (%6" PRIu64 " => %6" PRIu64 + " bytes, %s)\n", + inputFileName.c_str(), ratio * 100, bytesRead, bytesWritten, + outputFileName.c_str()); + } else { + state.log(kLogInfo, "%-20s: %" PRIu64 " bytes \n", + inputFileName.c_str(),bytesWritten); + } + } + return bytesWritten; +} + +static FILE *openInputFile(const std::string &inputFile, + ErrorHolder &errorHolder) { + if (inputFile == "-") { + SET_BINARY_MODE(stdin); + return stdin; + } + // Check if input file is a directory + { + std::error_code ec; + if (is_directory(inputFile, ec)) { + errorHolder.setError("Output file is a directory -- ignored"); + return nullptr; + } + } + auto inputFd = std::fopen(inputFile.c_str(), "rb"); + if (!errorHolder.check(inputFd != nullptr, "Failed to open input file")) { + return nullptr; + } + return inputFd; +} + +static FILE *openOutputFile(const Options &options, + const std::string &outputFile, + SharedState& state) { + if (outputFile == "-") { + SET_BINARY_MODE(stdout); + return stdout; + } + // Check if the output file exists and then open it + if (!options.overwrite && outputFile != nullOutput) { + auto outputFd = std::fopen(outputFile.c_str(), "rb"); + if (outputFd != nullptr) { + std::fclose(outputFd); + if (!state.log.logsAt(kLogInfo)) { + state.errorHolder.setError("Output file exists"); + return nullptr; + } + state.log( + kLogInfo, + "pzstd: %s already exists; do you wish to overwrite (y/n) ? ", + outputFile.c_str()); + int c = getchar(); + if (c != 'y' && c != 'Y') { + state.errorHolder.setError("Not overwritten"); + return nullptr; + } + } + } + auto outputFd = std::fopen(outputFile.c_str(), "wb"); + if (!state.errorHolder.check( + outputFd != nullptr, "Failed to open output file")) { + return nullptr; + } + return outputFd; +} + +int pzstdMain(const Options &options) { + int returnCode = 0; + SharedState state(options); + for (const auto& input : options.inputFiles) { + // Setup the shared state + auto printErrorGuard = makeScopeGuard([&] { + if (state.errorHolder.hasError()) { + returnCode = 1; + state.log(kLogError, "pzstd: %s: %s.\n", input.c_str(), + state.errorHolder.getError().c_str()); + } + }); + // Open the input file + auto inputFd = openInputFile(input, state.errorHolder); + if (inputFd == nullptr) { + continue; + } + auto closeInputGuard = makeScopeGuard([&] { std::fclose(inputFd); }); + // Open the output file + auto outputFile = options.getOutputFile(input); + if (!state.errorHolder.check(outputFile != "", + "Input file does not have extension .zst")) { + continue; + } + auto outputFd = openOutputFile(options, outputFile, state); + if (outputFd == nullptr) { + continue; + } + auto closeOutputGuard = makeScopeGuard([&] { std::fclose(outputFd); }); + // (de)compress the file + handleOneInput(options, input, inputFd, outputFile, outputFd, state); + if (state.errorHolder.hasError()) { + continue; + } + // Delete the input file if necessary + if (!options.keepSource) { + // Be sure that we are done and have written everything before we delete + if (!state.errorHolder.check(std::fclose(inputFd) == 0, + "Failed to close input file")) { + continue; + } + closeInputGuard.dismiss(); + if (!state.errorHolder.check(std::fclose(outputFd) == 0, + "Failed to close output file")) { + continue; + } + closeOutputGuard.dismiss(); + if (std::remove(input.c_str()) != 0) { + state.errorHolder.setError("Failed to remove input file"); + continue; + } + } + } + // Returns 1 if any of the files failed to (de)compress. + return returnCode; +} + +/// Construct a `ZSTD_inBuffer` that points to the data in `buffer`. +static ZSTD_inBuffer makeZstdInBuffer(const Buffer& buffer) { + return ZSTD_inBuffer{buffer.data(), buffer.size(), 0}; +} + +/** + * Advance `buffer` and `inBuffer` by the amount of data read, as indicated by + * `inBuffer.pos`. + */ +void advance(Buffer& buffer, ZSTD_inBuffer& inBuffer) { + auto pos = inBuffer.pos; + inBuffer.src = static_cast(inBuffer.src) + pos; + inBuffer.size -= pos; + inBuffer.pos = 0; + return buffer.advance(pos); +} + +/// Construct a `ZSTD_outBuffer` that points to the data in `buffer`. +static ZSTD_outBuffer makeZstdOutBuffer(Buffer& buffer) { + return ZSTD_outBuffer{buffer.data(), buffer.size(), 0}; +} + +/** + * Split `buffer` and advance `outBuffer` by the amount of data written, as + * indicated by `outBuffer.pos`. + */ +Buffer split(Buffer& buffer, ZSTD_outBuffer& outBuffer) { + auto pos = outBuffer.pos; + outBuffer.dst = static_cast(outBuffer.dst) + pos; + outBuffer.size -= pos; + outBuffer.pos = 0; + return buffer.splitAt(pos); +} + +/** + * Stream chunks of input from `in`, compress it, and stream it out to `out`. + * + * @param state The shared state + * @param in Queue that we `pop()` input buffers from + * @param out Queue that we `push()` compressed output buffers to + * @param maxInputSize An upper bound on the size of the input + */ +static void compress( + SharedState& state, + std::shared_ptr in, + std::shared_ptr out, + size_t maxInputSize) { + auto& errorHolder = state.errorHolder; + auto guard = makeScopeGuard([&] { + in->finish(); + out->finish(); + }); + // Initialize the CCtx + auto ctx = state.cStreamPool->get(); + if (!errorHolder.check(ctx != nullptr, "Failed to allocate ZSTD_CStream")) { + return; + } + { + auto err = ZSTD_CCtx_reset(ctx.get(), ZSTD_reset_session_only); + if (!errorHolder.check(!ZSTD_isError(err), ZSTD_getErrorName(err))) { + return; + } + } + + // Allocate space for the result + auto outBuffer = Buffer(ZSTD_compressBound(maxInputSize)); + auto zstdOutBuffer = makeZstdOutBuffer(outBuffer); + { + Buffer inBuffer; + // Read a buffer in from the input queue + while (in->pop(inBuffer) && !errorHolder.hasError()) { + auto zstdInBuffer = makeZstdInBuffer(inBuffer); + // Compress the whole buffer and send it to the output queue + while (!inBuffer.empty() && !errorHolder.hasError()) { + if (!errorHolder.check( + !outBuffer.empty(), "ZSTD_compressBound() was too small")) { + return; + } + // Compress + auto err = + ZSTD_compressStream(ctx.get(), &zstdOutBuffer, &zstdInBuffer); + if (!errorHolder.check(!ZSTD_isError(err), ZSTD_getErrorName(err))) { + return; + } + // Split the compressed data off outBuffer and pass to the output queue + out->push(split(outBuffer, zstdOutBuffer)); + // Forget about the data we already compressed + advance(inBuffer, zstdInBuffer); + } + } + } + // Write the epilog + size_t bytesLeft; + do { + if (!errorHolder.check( + !outBuffer.empty(), "ZSTD_compressBound() was too small")) { + return; + } + bytesLeft = ZSTD_endStream(ctx.get(), &zstdOutBuffer); + if (!errorHolder.check( + !ZSTD_isError(bytesLeft), ZSTD_getErrorName(bytesLeft))) { + return; + } + out->push(split(outBuffer, zstdOutBuffer)); + } while (bytesLeft != 0 && !errorHolder.hasError()); +} + +/** + * Calculates how large each independently compressed frame should be. + * + * @param size The size of the source if known, 0 otherwise + * @param numThreads The number of threads available to run compression jobs on + * @param params The zstd parameters to be used for compression + */ +static size_t calculateStep( + std::uintmax_t size, + size_t numThreads, + const ZSTD_parameters ¶ms) { + (void)size; + (void)numThreads; + // Not validated to work correctly for window logs > 23. + // It will definitely fail if windowLog + 2 is >= 4GB because + // the skippable frame can only store sizes up to 4GB. + assert(params.cParams.windowLog <= 23); + return size_t{1} << (params.cParams.windowLog + 2); +} + +namespace { +enum class FileStatus { Continue, Done, Error }; +/// Determines the status of the file descriptor `fd`. +FileStatus fileStatus(FILE* fd) { + if (std::feof(fd)) { + return FileStatus::Done; + } else if (std::ferror(fd)) { + return FileStatus::Error; + } + return FileStatus::Continue; +} +} // anonymous namespace + +/** + * Reads `size` data in chunks of `chunkSize` and puts it into `queue`. + * Will read less if an error or EOF occurs. + * Returns the status of the file after all of the reads have occurred. + */ +static FileStatus +readData(BufferWorkQueue& queue, size_t chunkSize, size_t size, FILE* fd, + std::uint64_t *totalBytesRead) { + Buffer buffer(size); + while (!buffer.empty()) { + auto bytesRead = + std::fread(buffer.data(), 1, std::min(chunkSize, buffer.size()), fd); + *totalBytesRead += bytesRead; + queue.push(buffer.splitAt(bytesRead)); + auto status = fileStatus(fd); + if (status != FileStatus::Continue) { + return status; + } + } + return FileStatus::Continue; +} + +std::uint64_t asyncCompressChunks( + SharedState& state, + WorkQueue>& chunks, + ThreadPool& executor, + FILE* fd, + std::uintmax_t size, + size_t numThreads, + ZSTD_parameters params) { + auto chunksGuard = makeScopeGuard([&] { chunks.finish(); }); + std::uint64_t bytesRead = 0; + + // Break the input up into chunks of size `step` and compress each chunk + // independently. + size_t step = calculateStep(size, numThreads, params); + state.log(kLogDebug, "Chosen frame size: %zu\n", step); + auto status = FileStatus::Continue; + while (status == FileStatus::Continue && !state.errorHolder.hasError()) { + // Make a new input queue that we will put the chunk's input data into. + auto in = std::make_shared(); + auto inGuard = makeScopeGuard([&] { in->finish(); }); + // Make a new output queue that compress will put the compressed data into. + auto out = std::make_shared(); + // Start compression in the thread pool + executor.add([&state, in, out, step] { + return compress( + state, std::move(in), std::move(out), step); + }); + // Pass the output queue to the writer thread. + chunks.push(std::move(out)); + state.log(kLogVerbose, "%s\n", "Starting a new frame"); + // Fill the input queue for the compression job we just started + status = readData(*in, ZSTD_CStreamInSize(), step, fd, &bytesRead); + } + state.errorHolder.check(status != FileStatus::Error, "Error reading input"); + return bytesRead; +} + +/** + * Decompress a frame, whose data is streamed into `in`, and stream the output + * to `out`. + * + * @param state The shared state + * @param in Queue that we `pop()` input buffers from. It contains + * exactly one compressed frame. + * @param out Queue that we `push()` decompressed output buffers to + */ +static void decompress( + SharedState& state, + std::shared_ptr in, + std::shared_ptr out) { + auto& errorHolder = state.errorHolder; + auto guard = makeScopeGuard([&] { + in->finish(); + out->finish(); + }); + // Initialize the DCtx + auto ctx = state.dStreamPool->get(); + if (!errorHolder.check(ctx != nullptr, "Failed to allocate ZSTD_DStream")) { + return; + } + { + auto err = ZSTD_DCtx_reset(ctx.get(), ZSTD_reset_session_only); + if (!errorHolder.check(!ZSTD_isError(err), ZSTD_getErrorName(err))) { + return; + } + } + + const size_t outSize = ZSTD_DStreamOutSize(); + Buffer inBuffer; + size_t returnCode = 0; + // Read a buffer in from the input queue + while (in->pop(inBuffer) && !errorHolder.hasError()) { + auto zstdInBuffer = makeZstdInBuffer(inBuffer); + // Decompress the whole buffer and send it to the output queue + while (!inBuffer.empty() && !errorHolder.hasError()) { + // Allocate a buffer with at least outSize bytes. + Buffer outBuffer(outSize); + auto zstdOutBuffer = makeZstdOutBuffer(outBuffer); + // Decompress + returnCode = + ZSTD_decompressStream(ctx.get(), &zstdOutBuffer, &zstdInBuffer); + if (!errorHolder.check( + !ZSTD_isError(returnCode), ZSTD_getErrorName(returnCode))) { + return; + } + // Pass the buffer with the decompressed data to the output queue + out->push(split(outBuffer, zstdOutBuffer)); + // Advance past the input we already read + advance(inBuffer, zstdInBuffer); + if (returnCode == 0) { + // The frame is over, prepare to (maybe) start a new frame + ZSTD_initDStream(ctx.get()); + } + } + } + if (!errorHolder.check(returnCode <= 1, "Incomplete block")) { + return; + } + // We've given ZSTD_decompressStream all of our data, but there may still + // be data to read. + while (returnCode == 1) { + // Allocate a buffer with at least outSize bytes. + Buffer outBuffer(outSize); + auto zstdOutBuffer = makeZstdOutBuffer(outBuffer); + // Pass in no input. + ZSTD_inBuffer zstdInBuffer{nullptr, 0, 0}; + // Decompress + returnCode = + ZSTD_decompressStream(ctx.get(), &zstdOutBuffer, &zstdInBuffer); + if (!errorHolder.check( + !ZSTD_isError(returnCode), ZSTD_getErrorName(returnCode))) { + return; + } + // Pass the buffer with the decompressed data to the output queue + out->push(split(outBuffer, zstdOutBuffer)); + } +} + +std::uint64_t asyncDecompressFrames( + SharedState& state, + WorkQueue>& frames, + ThreadPool& executor, + FILE* fd) { + auto framesGuard = makeScopeGuard([&] { frames.finish(); }); + std::uint64_t totalBytesRead = 0; + + // Split the source up into its component frames. + // If we find our recognized skippable frame we know the next frames size + // which means that we can decompress each standard frame in independently. + // Otherwise, we will decompress using only one decompression task. + const size_t chunkSize = ZSTD_DStreamInSize(); + auto status = FileStatus::Continue; + while (status == FileStatus::Continue && !state.errorHolder.hasError()) { + // Make a new input queue that we will put the frames's bytes into. + auto in = std::make_shared(); + auto inGuard = makeScopeGuard([&] { in->finish(); }); + // Make a output queue that decompress will put the decompressed data into + auto out = std::make_shared(); + + size_t frameSize; + { + // Calculate the size of the next frame. + // frameSize is 0 if the frame info can't be decoded. + Buffer buffer(SkippableFrame::kSize); + auto bytesRead = std::fread(buffer.data(), 1, buffer.size(), fd); + totalBytesRead += bytesRead; + status = fileStatus(fd); + if (bytesRead == 0 && status != FileStatus::Continue) { + break; + } + buffer.subtract(buffer.size() - bytesRead); + frameSize = SkippableFrame::tryRead(buffer.range()); + in->push(std::move(buffer)); + } + if (frameSize == 0) { + // We hit a non SkippableFrame, so this will be the last job. + // Make sure that we don't use too much memory + in->setMaxSize(64); + out->setMaxSize(64); + } + // Start decompression in the thread pool + executor.add([&state, in, out] { + return decompress(state, std::move(in), std::move(out)); + }); + // Pass the output queue to the writer thread + frames.push(std::move(out)); + if (frameSize == 0) { + // We hit a non SkippableFrame ==> not compressed by pzstd or corrupted + // Pass the rest of the source to this decompression task + state.log(kLogVerbose, "%s\n", + "Input not in pzstd format, falling back to serial decompression"); + while (status == FileStatus::Continue && !state.errorHolder.hasError()) { + status = readData(*in, chunkSize, chunkSize, fd, &totalBytesRead); + } + break; + } + state.log(kLogVerbose, "Decompressing a frame of size %zu", frameSize); + // Fill the input queue for the decompression job we just started + status = readData(*in, chunkSize, frameSize, fd, &totalBytesRead); + } + state.errorHolder.check(status != FileStatus::Error, "Error reading input"); + return totalBytesRead; +} + +/// Write `data` to `fd`, returns true iff success. +static bool writeData(ByteRange data, FILE* fd) { + while (!data.empty()) { + data.advance(std::fwrite(data.begin(), 1, data.size(), fd)); + if (std::ferror(fd)) { + return false; + } + } + return true; +} + +std::uint64_t writeFile( + SharedState& state, + WorkQueue>& outs, + FILE* outputFd, + bool decompress) { + auto& errorHolder = state.errorHolder; + auto outsFinishGuard = makeScopeGuard([&outs] { outs.finish(); }); + auto lineClearGuard = makeScopeGuard([&state] { + state.log.clear(kLogInfo); + }); + std::uint64_t bytesWritten = 0; + std::shared_ptr out; + // Grab the output queue for each decompression job (in order). + while (outs.pop(out)) { + auto outFinishGuard = makeScopeGuard([&out] { out->finish(); }); + if (errorHolder.hasError()) { + continue; + } + if (!decompress) { + // If we are compressing and want to write skippable frames we can't + // start writing before compression is done because we need to know the + // compressed size. + // Wait for the compressed size to be available and write skippable frame + assert(uint64_t(out->size()) < uint64_t(1) << 32); + SkippableFrame frame(uint32_t(out->size())); + if (!writeData(frame.data(), outputFd)) { + errorHolder.setError("Failed to write output"); + return bytesWritten; + } + bytesWritten += frame.kSize; + } + // For each chunk of the frame: Pop it from the queue and write it + Buffer buffer; + while (out->pop(buffer) && !errorHolder.hasError()) { + if (!writeData(buffer.range(), outputFd)) { + errorHolder.setError("Failed to write output"); + return bytesWritten; + } + bytesWritten += buffer.size(); + state.log.update(kLogInfo, "Written: %u MB ", + static_cast(bytesWritten >> 20)); + } + } + return bytesWritten; +} +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/Pzstd.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Pzstd.h new file mode 100644 index 000000000..3645e5942 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/Pzstd.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include "ErrorHolder.h" +#include "Logging.h" +#include "Options.h" +#include "utils/Buffer.h" +#include "utils/Range.h" +#include "utils/ResourcePool.h" +#include "utils/ThreadPool.h" +#include "utils/WorkQueue.h" +#define ZSTD_STATIC_LINKING_ONLY +#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* No deprecation warnings, pzstd itself is deprecated + * and uses deprecated functions + */ +#include "zstd.h" +#undef ZSTD_STATIC_LINKING_ONLY + +#include +#include +#include + +namespace pzstd { +/** + * Runs pzstd with `options` and returns the number of bytes written. + * An error occurred if `errorHandler.hasError()`. + * + * @param options The pzstd options to use for (de)compression + * @returns 0 upon success and non-zero on failure. + */ +int pzstdMain(const Options& options); + +class SharedState { + public: + SharedState(const Options& options) : log(options.verbosity) { + if (!options.decompress) { + auto parameters = options.determineParameters(); + cStreamPool.reset(new ResourcePool{ + [this, parameters]() -> ZSTD_CStream* { + this->log(kLogVerbose, "%s\n", "Creating new ZSTD_CStream"); + auto zcs = ZSTD_createCStream(); + if (zcs) { + auto err = ZSTD_initCStream_advanced( + zcs, nullptr, 0, parameters, 0); + if (ZSTD_isError(err)) { + ZSTD_freeCStream(zcs); + return nullptr; + } + } + return zcs; + }, + [](ZSTD_CStream *zcs) { + ZSTD_freeCStream(zcs); + }}); + } else { + dStreamPool.reset(new ResourcePool{ + [this]() -> ZSTD_DStream* { + this->log(kLogVerbose, "%s\n", "Creating new ZSTD_DStream"); + auto zds = ZSTD_createDStream(); + if (zds) { + auto err = ZSTD_initDStream(zds); + if (ZSTD_isError(err)) { + ZSTD_freeDStream(zds); + return nullptr; + } + } + return zds; + }, + [](ZSTD_DStream *zds) { + ZSTD_freeDStream(zds); + }}); + } + } + + ~SharedState() { + // The resource pools have references to this, so destroy them first. + cStreamPool.reset(); + dStreamPool.reset(); + } + + Logger log; + ErrorHolder errorHolder; + std::unique_ptr> cStreamPool; + std::unique_ptr> dStreamPool; +}; + +/** + * Streams input from `fd`, breaks input up into chunks, and compresses each + * chunk independently. Output of each chunk gets streamed to a queue, and + * the output queues get put into `chunks` in order. + * + * @param state The shared state + * @param chunks Each compression jobs output queue gets `pushed()` here + * as soon as it is available + * @param executor The thread pool to run compression jobs in + * @param fd The input file descriptor + * @param size The size of the input file if known, 0 otherwise + * @param numThreads The number of threads in the thread pool + * @param parameters The zstd parameters to use for compression + * @returns The number of bytes read from the file + */ +std::uint64_t asyncCompressChunks( + SharedState& state, + WorkQueue>& chunks, + ThreadPool& executor, + FILE* fd, + std::uintmax_t size, + std::size_t numThreads, + ZSTD_parameters parameters); + +/** + * Streams input from `fd`. If pzstd headers are available it breaks the input + * up into independent frames. It sends each frame to an independent + * decompression job. Output of each frame gets streamed to a queue, and + * the output queues get put into `frames` in order. + * + * @param state The shared state + * @param frames Each decompression jobs output queue gets `pushed()` here + * as soon as it is available + * @param executor The thread pool to run compression jobs in + * @param fd The input file descriptor + * @returns The number of bytes read from the file + */ +std::uint64_t asyncDecompressFrames( + SharedState& state, + WorkQueue>& frames, + ThreadPool& executor, + FILE* fd); + +/** + * Streams input in from each queue in `outs` in order, and writes the data to + * `outputFd`. + * + * @param state The shared state + * @param outs A queue of output queues, one for each + * (de)compression job. + * @param outputFd The file descriptor to write to + * @param decompress Are we decompressing? + * @returns The number of bytes written + */ +std::uint64_t writeFile( + SharedState& state, + WorkQueue>& outs, + FILE* outputFd, + bool decompress); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/README.md b/cpp/third_party/zstd-1.5.7/contrib/pzstd/README.md new file mode 100644 index 000000000..bc8f831f8 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/README.md @@ -0,0 +1,56 @@ +# Parallel Zstandard (PZstandard) + +Parallel Zstandard is a Pigz-like tool for Zstandard. +It provides Zstandard format compatible compression and decompression that is able to utilize multiple cores. +It breaks the input up into equal sized chunks and compresses each chunk independently into a Zstandard frame. +It then concatenates the frames together to produce the final compressed output. +Pzstandard will write a 12 byte header for each frame that is a skippable frame in the Zstandard format, which tells PZstandard the size of the next compressed frame. +PZstandard supports parallel decompression of files compressed with PZstandard. +When decompressing files compressed with Zstandard, PZstandard does IO in one thread, and decompression in another. + +## Usage + +PZstandard supports the same command line interface as Zstandard, but also provides the `-p` option to specify the number of threads. +Dictionary mode is not currently supported. + +Basic usage + + pzstd input-file -o output-file -p num-threads -# # Compression + pzstd -d input-file -o output-file -p num-threads # Decompression + +PZstandard also supports piping and fifo pipes + + cat input-file | pzstd -p num-threads -# -c > /dev/null + +For more options + + pzstd --help + +PZstandard tries to pick a smart default number of threads if not specified (displayed in `pzstd --help`). +If this number is not suitable, during compilation you can define `PZSTD_NUM_THREADS` to the number of threads you prefer. + +## Benchmarks + +As a reference, PZstandard and Pigz were compared on an Intel Core i7 @ 3.1 GHz, each using 4 threads, with the [Silesia compression corpus](https://sun.aei.polsl.pl//~sdeor/index.php?page=silesia). + +Compression Speed vs Ratio with 4 Threads | Decompression Speed with 4 Threads +------------------------------------------|----------------------------------- +![Compression Speed vs Ratio](images/Cspeed.png "Compression Speed vs Ratio") | ![Decompression Speed](images/Dspeed.png "Decompression Speed") + +The test procedure was to run each of the following commands 2 times for each compression level, and take the minimum time. + + time pzstd -# -p 4 -c silesia.tar > silesia.tar.zst + time pzstd -d -p 4 -c silesia.tar.zst > /dev/null + + time pigz -# -p 4 -k -c silesia.tar > silesia.tar.gz + time pigz -d -p 4 -k -c silesia.tar.gz > /dev/null + +PZstandard was tested using compression levels 1-19, and Pigz was tested using compression levels 1-9. +Pigz cannot do parallel decompression, it simply does each of reading, decompression, and writing on separate threads. + +## Tests + +Tests require that you have [gtest](https://github.com/google/googletest) installed. +Set `GTEST_INC` and `GTEST_LIB` in `Makefile` to specify the location of the gtest headers and libraries. +Alternatively, run `make googletest`, which will clone googletest and build it. +Run `make tests && make check` to run tests. diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/SkippableFrame.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/SkippableFrame.cpp new file mode 100644 index 000000000..3bea4eb65 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/SkippableFrame.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "SkippableFrame.h" +#include "mem.h" +#include "utils/Range.h" + +#include + +using namespace pzstd; + +SkippableFrame::SkippableFrame(std::uint32_t size) : frameSize_(size) { + MEM_writeLE32(data_.data(), kSkippableFrameMagicNumber); + MEM_writeLE32(data_.data() + 4, kFrameContentsSize); + MEM_writeLE32(data_.data() + 8, frameSize_); +} + +/* static */ std::size_t SkippableFrame::tryRead(ByteRange bytes) { + if (bytes.size() < SkippableFrame::kSize || + MEM_readLE32(bytes.begin()) != kSkippableFrameMagicNumber || + MEM_readLE32(bytes.begin() + 4) != kFrameContentsSize) { + return 0; + } + return MEM_readLE32(bytes.begin() + 8); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/SkippableFrame.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/SkippableFrame.h new file mode 100644 index 000000000..817415e92 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/SkippableFrame.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include "utils/Range.h" + +#include +#include +#include +#include + +namespace pzstd { +/** + * We put a skippable frame before each frame. + * It contains a skippable frame magic number, the size of the skippable frame, + * and the size of the next frame. + * Each skippable frame is exactly 12 bytes in little endian format. + * The first 8 bytes are for compatibility with the ZSTD format. + * If we have N threads, the output will look like + * + * [0x184D2A50|4|size1] [frame1 of size size1] + * [0x184D2A50|4|size2] [frame2 of size size2] + * ... + * [0x184D2A50|4|sizeN] [frameN of size sizeN] + * + * Each sizeX is 4 bytes. + * + * These skippable frames should allow us to skip through the compressed file + * and only load at most N pages. + */ +class SkippableFrame { + public: + static constexpr std::size_t kSize = 12; + + private: + std::uint32_t frameSize_; + std::array data_; + static constexpr std::uint32_t kSkippableFrameMagicNumber = 0x184D2A50; + // Could be improved if the size fits in less bytes + static constexpr std::uint32_t kFrameContentsSize = kSize - 8; + + public: + // Write the skippable frame to data_ in LE format. + explicit SkippableFrame(std::uint32_t size); + + // Read the skippable frame from bytes in LE format. + static std::size_t tryRead(ByteRange bytes); + + ByteRange data() const { + return {data_.data(), data_.size()}; + } + + // Size of the next frame. + std::size_t frameSize() const { + return frameSize_; + } +}; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/images/Cspeed.png b/cpp/third_party/zstd-1.5.7/contrib/pzstd/images/Cspeed.png new file mode 100644 index 0000000000000000000000000000000000000000..aca4f663ea2e98b6df7c1344b51af99757549d8a GIT binary patch literal 69804 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

<^Cy&%i!i4)Eca=wTuqIGA0*ebIMyM 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 cvzWZHB0(f` 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/main.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/main.cpp new file mode 100644 index 000000000..422b4a56a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/main.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "ErrorHolder.h" +#include "Options.h" +#include "Pzstd.h" + +using namespace pzstd; + +int main(int argc, const char** argv) { + Options options; + switch (options.parse(argc, argv)) { + case Options::Status::Failure: + return 1; + case Options::Status::Message: + return 0; + default: + break; + } + + return pzstdMain(options); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/BUCK b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/BUCK new file mode 100644 index 000000000..6d3fdd3c2 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/BUCK @@ -0,0 +1,37 @@ +cxx_test( + name='options_test', + srcs=['OptionsTest.cpp'], + deps=['//contrib/pzstd:options'], +) + +cxx_test( + name='pzstd_test', + srcs=['PzstdTest.cpp'], + deps=[ + ':round_trip', + '//contrib/pzstd:libpzstd', + '//contrib/pzstd/utils:scope_guard', + '//programs:datagen', + ], +) + +cxx_binary( + name='round_trip_test', + srcs=['RoundTripTest.cpp'], + deps=[ + ':round_trip', + '//contrib/pzstd/utils:scope_guard', + '//programs:datagen', + ] +) + +cxx_library( + name='round_trip', + header_namespace='test', + exported_headers=['RoundTrip.h'], + deps=[ + '//contrib/pzstd:libpzstd', + '//contrib/pzstd:options', + '//contrib/pzstd/utils:scope_guard', + ] +) diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/OptionsTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/OptionsTest.cpp new file mode 100644 index 000000000..91e39750d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/OptionsTest.cpp @@ -0,0 +1,536 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "Options.h" + +#include +#include + +using namespace pzstd; + +namespace pzstd { +bool operator==(const Options &lhs, const Options &rhs) { + return lhs.numThreads == rhs.numThreads && + lhs.maxWindowLog == rhs.maxWindowLog && + lhs.compressionLevel == rhs.compressionLevel && + lhs.decompress == rhs.decompress && lhs.inputFiles == rhs.inputFiles && + lhs.outputFile == rhs.outputFile && lhs.overwrite == rhs.overwrite && + lhs.keepSource == rhs.keepSource && lhs.writeMode == rhs.writeMode && + lhs.checksum == rhs.checksum && lhs.verbosity == rhs.verbosity; +} + +std::ostream &operator<<(std::ostream &out, const Options &opt) { + out << "{"; + { + out << "\n\t" + << "numThreads: " << opt.numThreads; + out << ",\n\t" + << "maxWindowLog: " << opt.maxWindowLog; + out << ",\n\t" + << "compressionLevel: " << opt.compressionLevel; + out << ",\n\t" + << "decompress: " << opt.decompress; + out << ",\n\t" + << "inputFiles: {"; + { + bool first = true; + for (const auto &file : opt.inputFiles) { + if (!first) { + out << ","; + } + first = false; + out << "\n\t\t" << file; + } + } + out << "\n\t}"; + out << ",\n\t" + << "outputFile: " << opt.outputFile; + out << ",\n\t" + << "overwrite: " << opt.overwrite; + out << ",\n\t" + << "keepSource: " << opt.keepSource; + out << ",\n\t" + << "writeMode: " << static_cast(opt.writeMode); + out << ",\n\t" + << "checksum: " << opt.checksum; + out << ",\n\t" + << "verbosity: " << opt.verbosity; + } + out << "\n}"; + return out; +} +} + +namespace { +#ifdef _WIN32 +const char nullOutput[] = "nul"; +#else +const char nullOutput[] = "/dev/null"; +#endif + +constexpr auto autoMode = Options::WriteMode::Auto; +} // anonymous namespace + +#define EXPECT_SUCCESS(...) EXPECT_EQ(Options::Status::Success, __VA_ARGS__) +#define EXPECT_FAILURE(...) EXPECT_EQ(Options::Status::Failure, __VA_ARGS__) +#define EXPECT_MESSAGE(...) EXPECT_EQ(Options::Status::Message, __VA_ARGS__) + +template +std::array makeArray(Args... args) { + return {{nullptr, args...}}; +} + +TEST(Options, ValidInputs) { + { + Options options; + auto args = makeArray("--processes", "5", "-o", "x", "y", "-f"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {5, 23, 3, false, {"y"}, "x", + true, true, autoMode, true, 2}; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("-p", "1", "input", "-19"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 23, 19, false, {"input"}, "", + false, true, autoMode, true, 2}; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = + makeArray("--ultra", "-22", "-p", "1", "-o", "x", "-d", "x.zst", "-f"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 0, 22, true, {"x.zst"}, "x", + true, true, autoMode, true, 2}; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("--processes", "100", "hello.zst", "--decompress", + "--force"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {100, 23, 3, true, {"hello.zst"}, "", true, + true, autoMode, true, 2}; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("x", "-dp", "1", "-c"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 23, 3, true, {"x"}, "-", + false, true, autoMode, true, 2}; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("x", "-dp", "1", "--stdout"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 23, 3, true, {"x"}, "-", + false, true, autoMode, true, 2}; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("-p", "1", "x", "-5", "-fo", "-", "--ultra", "-d"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 0, 5, true, {"x"}, "-", + true, true, autoMode, true, 2}; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("silesia.tar", "-o", "silesia.tar.pzstd", "-p", "2"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {2, + 23, + 3, + false, + {"silesia.tar"}, + "silesia.tar.pzstd", + false, + true, + autoMode, + true, + 2}; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("x", "-p", "1"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-p", "1"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + } +} + +TEST(Options, GetOutputFile) { + { + Options options; + auto args = makeArray("x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("x.zst", options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("x", "y", "-o", nullOutput); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(nullOutput, options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("x.zst", "-do", nullOutput); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(nullOutput, options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("x.zst", "-d"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("x", options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("xzst", "-d"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("", options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("xzst", "-doxx"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("xx", options.getOutputFile(options.inputFiles[0])); + } +} + +TEST(Options, MultipleFiles) { + { + Options options; + auto args = makeArray("x", "y", "z"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected; + expected.inputFiles = {"x", "y", "z"}; + expected.verbosity = 1; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("x", "y", "z", "-o", nullOutput); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected; + expected.inputFiles = {"x", "y", "z"}; + expected.outputFile = nullOutput; + expected.verbosity = 1; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("x", "y", "-o-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "y", "-o", "file"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-qqvd12qp4", "-f", "x", "--", "--rm", "-c"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {4, 23, 12, true, {"x", "--rm", "-c"}, + "", true, true, autoMode, true, + 0}; + EXPECT_EQ(expected, options); + } +} + +TEST(Options, NumThreads) { + { + Options options; + auto args = makeArray("x", "-dfo", "-"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-p", "0", "-fo", "-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-f", "-p", "-o", "-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } +} + +TEST(Options, BadCompressionLevel) { + { + Options options; + auto args = makeArray("x", "-20"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "--ultra", "-23"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "--1"); // negative 1? + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } +} + +TEST(Options, InvalidOption) { + { + Options options; + auto args = makeArray("x", "-x"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } +} + +TEST(Options, BadOutputFile) { + { + Options options; + auto args = makeArray("notzst", "-d", "-p", "1"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("", options.getOutputFile(options.inputFiles.front())); + } +} + +TEST(Options, BadOptionsWithArguments) { + { + Options options; + auto args = makeArray("x", "-pf"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-p", "10f"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-p"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-o"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-o"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } +} + +TEST(Options, KeepSource) { + { + Options options; + auto args = makeArray("x", "--rm", "-k"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + } + { + Options options; + auto args = makeArray("x", "--rm", "--keep"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + } + { + Options options; + auto args = makeArray("x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + } + { + Options options; + auto args = makeArray("x", "--rm"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(false, options.keepSource); + } +} + +TEST(Options, Verbosity) { + { + Options options; + auto args = makeArray("x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(2, options.verbosity); + } + { + Options options; + auto args = makeArray("--quiet", "-qq", "x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(-1, options.verbosity); + } + { + Options options; + auto args = makeArray("x", "y"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(1, options.verbosity); + } + { + Options options; + auto args = makeArray("--", "x", "y"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(1, options.verbosity); + } + { + Options options; + auto args = makeArray("-qv", "x", "y"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(1, options.verbosity); + } + { + Options options; + auto args = makeArray("-v", "x", "y"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(3, options.verbosity); + } + { + Options options; + auto args = makeArray("-v", "x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(3, options.verbosity); + } +} + +TEST(Options, TestMode) { + { + Options options; + auto args = makeArray("x", "-t"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + EXPECT_EQ(true, options.decompress); + EXPECT_EQ(nullOutput, options.outputFile); + } + { + Options options; + auto args = makeArray("x", "--test", "--rm", "-ohello"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + EXPECT_EQ(true, options.decompress); + EXPECT_EQ(nullOutput, options.outputFile); + } +} + +TEST(Options, Checksum) { + { + Options options; + auto args = makeArray("x.zst", "--no-check", "-Cd"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.checksum); + } + { + Options options; + auto args = makeArray("x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.checksum); + } + { + Options options; + auto args = makeArray("x", "--no-check", "--check"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.checksum); + } + { + Options options; + auto args = makeArray("x", "--no-check"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(false, options.checksum); + } +} + +TEST(Options, InputFiles) { + { + Options options; + auto args = makeArray("-cd"); + options.parse(args.size(), args.data()); + EXPECT_EQ(1, options.inputFiles.size()); + EXPECT_EQ("-", options.inputFiles[0]); + EXPECT_EQ("-", options.outputFile); + } + { + Options options; + auto args = makeArray(); + options.parse(args.size(), args.data()); + EXPECT_EQ(1, options.inputFiles.size()); + EXPECT_EQ("-", options.inputFiles[0]); + EXPECT_EQ("-", options.outputFile); + } + { + Options options; + auto args = makeArray("-d"); + options.parse(args.size(), args.data()); + EXPECT_EQ(1, options.inputFiles.size()); + EXPECT_EQ("-", options.inputFiles[0]); + EXPECT_EQ("-", options.outputFile); + } + { + Options options; + auto args = makeArray("x", "-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } +} + +TEST(Options, InvalidOptions) { + { + Options options; + auto args = makeArray("-ibasdf"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("- "); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-n15"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-0", "x"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } +} + +TEST(Options, Extras) { + { + Options options; + auto args = makeArray("-h"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-H"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-V"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("--help"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("--version"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); + } +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/PzstdTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/PzstdTest.cpp new file mode 100644 index 000000000..3249f860a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/PzstdTest.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "Pzstd.h" +#include "datagen.h" +#include "test/RoundTrip.h" +#include "utils/ScopeGuard.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace pzstd; + +TEST(Pzstd, SmallSizes) { + unsigned seed = std::random_device{}(); + std::fprintf(stderr, "Pzstd.SmallSizes seed: %u\n", seed); + std::mt19937 gen(seed); + + for (unsigned len = 1; len < 256; ++len) { + if (len % 16 == 0) { + std::fprintf(stderr, "%u / 16\n", len / 16); + } + std::string inputFile = std::tmpnam(nullptr); + auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); + { + static uint8_t buf[256]; + RDG_genBuffer(buf, len, 0.5, 0.0, gen()); + auto fd = std::fopen(inputFile.c_str(), "wb"); + auto written = std::fwrite(buf, 1, len, fd); + std::fclose(fd); + ASSERT_EQ(written, len); + } + for (unsigned numThreads = 1; numThreads <= 2; ++numThreads) { + for (unsigned level = 1; level <= 4; level *= 4) { + auto errorGuard = makeScopeGuard([&] { + std::fprintf(stderr, "# threads: %u\n", numThreads); + std::fprintf(stderr, "compression level: %u\n", level); + }); + Options options; + options.overwrite = true; + options.inputFiles = {inputFile}; + options.numThreads = numThreads; + options.compressionLevel = level; + options.verbosity = 1; + ASSERT_TRUE(roundTrip(options)); + errorGuard.dismiss(); + } + } + } +} + +TEST(Pzstd, LargeSizes) { + unsigned seed = std::random_device{}(); + std::fprintf(stderr, "Pzstd.LargeSizes seed: %u\n", seed); + std::mt19937 gen(seed); + + for (unsigned len = 1 << 20; len <= (1 << 24); len *= 2) { + std::string inputFile = std::tmpnam(nullptr); + auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); + { + std::unique_ptr buf(new uint8_t[len]); + RDG_genBuffer(buf.get(), len, 0.5, 0.0, gen()); + auto fd = std::fopen(inputFile.c_str(), "wb"); + auto written = std::fwrite(buf.get(), 1, len, fd); + std::fclose(fd); + ASSERT_EQ(written, len); + } + for (unsigned numThreads = 1; numThreads <= 16; numThreads *= 4) { + for (unsigned level = 1; level <= 4; level *= 4) { + auto errorGuard = makeScopeGuard([&] { + std::fprintf(stderr, "# threads: %u\n", numThreads); + std::fprintf(stderr, "compression level: %u\n", level); + }); + Options options; + options.overwrite = true; + options.inputFiles = {inputFile}; + options.numThreads = std::min(numThreads, options.numThreads); + options.compressionLevel = level; + options.verbosity = 1; + ASSERT_TRUE(roundTrip(options)); + errorGuard.dismiss(); + } + } + } +} + +TEST(Pzstd, DISABLED_ExtremelyLargeSize) { + unsigned seed = std::random_device{}(); + std::fprintf(stderr, "Pzstd.ExtremelyLargeSize seed: %u\n", seed); + std::mt19937 gen(seed); + + std::string inputFile = std::tmpnam(nullptr); + auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); + + { + // Write 4GB + 64 MB + constexpr size_t kLength = 1 << 26; + std::unique_ptr buf(new uint8_t[kLength]); + auto fd = std::fopen(inputFile.c_str(), "wb"); + auto closeGuard = makeScopeGuard([&] { std::fclose(fd); }); + for (size_t i = 0; i < (1 << 6) + 1; ++i) { + RDG_genBuffer(buf.get(), kLength, 0.5, 0.0, gen()); + auto written = std::fwrite(buf.get(), 1, kLength, fd); + if (written != kLength) { + std::fprintf(stderr, "Failed to write file, skipping test\n"); + return; + } + } + } + + Options options; + options.overwrite = true; + options.inputFiles = {inputFile}; + options.compressionLevel = 1; + if (options.numThreads == 0) { + options.numThreads = 1; + } + ASSERT_TRUE(roundTrip(options)); +} + +TEST(Pzstd, ExtremelyCompressible) { + std::string inputFile = std::tmpnam(nullptr); + auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); + { + std::unique_ptr buf(new uint8_t[10000]); + std::memset(buf.get(), 'a', 10000); + auto fd = std::fopen(inputFile.c_str(), "wb"); + auto written = std::fwrite(buf.get(), 1, 10000, fd); + std::fclose(fd); + ASSERT_EQ(written, 10000); + } + Options options; + options.overwrite = true; + options.inputFiles = {inputFile}; + options.numThreads = 1; + options.compressionLevel = 1; + ASSERT_TRUE(roundTrip(options)); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/RoundTrip.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/RoundTrip.h new file mode 100644 index 000000000..f777622a3 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/RoundTrip.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include "Options.h" +#include "Pzstd.h" +#include "utils/ScopeGuard.h" + +#include +#include +#include +#include + +namespace pzstd { + +inline bool check(std::string source, std::string decompressed) { + std::unique_ptr sBuf(new std::uint8_t[1024]); + std::unique_ptr dBuf(new std::uint8_t[1024]); + + auto sFd = std::fopen(source.c_str(), "rb"); + auto dFd = std::fopen(decompressed.c_str(), "rb"); + auto guard = makeScopeGuard([&] { + std::fclose(sFd); + std::fclose(dFd); + }); + + size_t sRead, dRead; + + do { + sRead = std::fread(sBuf.get(), 1, 1024, sFd); + dRead = std::fread(dBuf.get(), 1, 1024, dFd); + if (std::ferror(sFd) || std::ferror(dFd)) { + return false; + } + if (sRead != dRead) { + return false; + } + + for (size_t i = 0; i < sRead; ++i) { + if (sBuf.get()[i] != dBuf.get()[i]) { + return false; + } + } + } while (sRead == 1024); + if (!std::feof(sFd) || !std::feof(dFd)) { + return false; + } + return true; +} + +inline bool roundTrip(Options& options) { + if (options.inputFiles.size() != 1) { + return false; + } + std::string source = options.inputFiles.front(); + std::string compressedFile = std::tmpnam(nullptr); + std::string decompressedFile = std::tmpnam(nullptr); + auto guard = makeScopeGuard([&] { + std::remove(compressedFile.c_str()); + std::remove(decompressedFile.c_str()); + }); + + { + options.outputFile = compressedFile; + options.decompress = false; + if (pzstdMain(options) != 0) { + return false; + } + } + { + options.decompress = true; + options.inputFiles.front() = compressedFile; + options.outputFile = decompressedFile; + if (pzstdMain(options) != 0) { + return false; + } + } + return check(source, decompressedFile); +} +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/RoundTripTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/RoundTripTest.cpp new file mode 100644 index 000000000..27c5028e8 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/test/RoundTripTest.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "datagen.h" +#include "Options.h" +#include "test/RoundTrip.h" +#include "utils/ScopeGuard.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace pzstd; + +namespace { +string +writeData(size_t size, double matchProba, double litProba, unsigned seed) { + std::unique_ptr buf(new uint8_t[size]); + RDG_genBuffer(buf.get(), size, matchProba, litProba, seed); + string file = tmpnam(nullptr); + auto fd = std::fopen(file.c_str(), "wb"); + auto guard = makeScopeGuard([&] { std::fclose(fd); }); + auto bytesWritten = std::fwrite(buf.get(), 1, size, fd); + if (bytesWritten != size) { + std::abort(); + } + return file; +} + +template +string generateInputFile(Generator& gen) { + // Use inputs ranging from 1 Byte to 2^16 Bytes + std::uniform_int_distribution size{1, 1 << 16}; + std::uniform_real_distribution<> prob{0, 1}; + return writeData(size(gen), prob(gen), prob(gen), gen()); +} + +template +Options generateOptions(Generator& gen, const string& inputFile) { + Options options; + options.inputFiles = {inputFile}; + options.overwrite = true; + + std::uniform_int_distribution numThreads{1, 32}; + std::uniform_int_distribution compressionLevel{1, 10}; + + options.numThreads = numThreads(gen); + options.compressionLevel = compressionLevel(gen); + + return options; +} +} + +int main() { + std::mt19937 gen(std::random_device{}()); + + auto newlineGuard = makeScopeGuard([] { std::fprintf(stderr, "\n"); }); + for (unsigned i = 0; i < 10000; ++i) { + if (i % 100 == 0) { + std::fprintf(stderr, "Progress: %u%%\r", i / 100); + } + auto inputFile = generateInputFile(gen); + auto inputGuard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); + for (unsigned i = 0; i < 10; ++i) { + auto options = generateOptions(gen, inputFile); + if (!roundTrip(options)) { + std::fprintf(stderr, "numThreads: %u\n", options.numThreads); + std::fprintf(stderr, "level: %u\n", options.compressionLevel); + std::fprintf(stderr, "decompress? %u\n", (unsigned)options.decompress); + std::fprintf(stderr, "file: %s\n", inputFile.c_str()); + return 1; + } + } + } + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/BUCK b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/BUCK new file mode 100644 index 000000000..e757f4120 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/BUCK @@ -0,0 +1,75 @@ +cxx_library( + name='buffer', + visibility=['PUBLIC'], + header_namespace='utils', + exported_headers=['Buffer.h'], + deps=[':range'], +) + +cxx_library( + name='file_system', + visibility=['PUBLIC'], + header_namespace='utils', + exported_headers=['FileSystem.h'], + deps=[':range'], +) + +cxx_library( + name='likely', + visibility=['PUBLIC'], + header_namespace='utils', + exported_headers=['Likely.h'], +) + +cxx_library( + name='range', + visibility=['PUBLIC'], + header_namespace='utils', + exported_headers=['Range.h'], + deps=[':likely'], +) + +cxx_library( + name='resource_pool', + visibility=['PUBLIC'], + header_namespace='utils', + exported_headers=['ResourcePool.h'], +) + +cxx_library( + name='scope_guard', + visibility=['PUBLIC'], + header_namespace='utils', + exported_headers=['ScopeGuard.h'], +) + +cxx_library( + name='thread_pool', + visibility=['PUBLIC'], + header_namespace='utils', + exported_headers=['ThreadPool.h'], + deps=[':work_queue'], +) + +cxx_library( + name='work_queue', + visibility=['PUBLIC'], + header_namespace='utils', + exported_headers=['WorkQueue.h'], + deps=[':buffer'], +) + +cxx_library( + name='utils', + visibility=['PUBLIC'], + deps=[ + ':buffer', + ':file_system', + ':likely', + ':range', + ':resource_pool', + ':scope_guard', + ':thread_pool', + ':work_queue', + ], +) diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Buffer.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Buffer.h new file mode 100644 index 000000000..a85f770ba --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Buffer.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include "utils/Range.h" + +#include +#include +#include + +namespace pzstd { + +/** + * A `Buffer` has a pointer to a shared buffer, and a range of the buffer that + * it owns. + * The idea is that you can allocate one buffer, and write chunks into it + * and break off those chunks. + * The underlying buffer is reference counted, and will be destroyed when all + * `Buffer`s that reference it are destroyed. + */ +class Buffer { + std::shared_ptr buffer_; + MutableByteRange range_; + + static void delete_buffer(unsigned char* buffer) { + delete[] buffer; + } + + public: + /// Construct an empty buffer that owns no data. + explicit Buffer() {} + + /// Construct a `Buffer` that owns a new underlying buffer of size `size`. + explicit Buffer(std::size_t size) + : buffer_(new unsigned char[size], delete_buffer), + range_(buffer_.get(), buffer_.get() + size) {} + + explicit Buffer(std::shared_ptr buffer, MutableByteRange data) + : buffer_(buffer), range_(data) {} + + Buffer(Buffer&&) = default; + Buffer& operator=(Buffer&&) = default; + + /** + * Splits the data into two pieces: [begin, begin + n), [begin + n, end). + * Their data both points into the same underlying buffer. + * Modifies the original `Buffer` to point to only [begin + n, end). + * + * @param n The offset to split at. + * @returns A buffer that owns the data [begin, begin + n). + */ + Buffer splitAt(std::size_t n) { + auto firstPiece = range_.subpiece(0, n); + range_.advance(n); + return Buffer(buffer_, firstPiece); + } + + /// Modifies the buffer to point to the range [begin + n, end). + void advance(std::size_t n) { + range_.advance(n); + } + + /// Modifies the buffer to point to the range [begin, end - n). + void subtract(std::size_t n) { + range_.subtract(n); + } + + /// Returns a read only `Range` pointing to the `Buffer`s data. + ByteRange range() const { + return range_; + } + /// Returns a mutable `Range` pointing to the `Buffer`s data. + MutableByteRange range() { + return range_; + } + + const unsigned char* data() const { + return range_.data(); + } + + unsigned char* data() { + return range_.data(); + } + + std::size_t size() const { + return range_.size(); + } + + bool empty() const { + return range_.empty(); + } +}; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/FileSystem.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/FileSystem.h new file mode 100644 index 000000000..8d57d05f0 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/FileSystem.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include "utils/Portability.h" +#include "utils/Range.h" + +#include +#include +#include +#include +#include + +// A small subset of `std::filesystem`. +// `std::filesystem` should be a drop in replacement. +// See https://en.cppreference.com/w/cpp/filesystem for documentation. + +namespace pzstd { + +// using file_status = ... causes gcc to emit a false positive warning +#if defined(_MSC_VER) +typedef struct ::_stat64 file_status; +#else +typedef struct ::stat file_status; +#endif + +/// https://en.cppreference.com/w/cpp/filesystem/status +inline file_status status(StringPiece path, std::error_code& ec) noexcept { + file_status status; +#if defined(_MSC_VER) + const auto error = ::_stat64(path.data(), &status); +#else + const auto error = ::stat(path.data(), &status); +#endif + if (error) { + ec.assign(errno, std::generic_category()); + } else { + ec.clear(); + } + return status; +} + +/// https://en.cppreference.com/w/cpp/filesystem/is_regular_file +inline bool is_regular_file(file_status status) noexcept { +#if defined(S_ISREG) + return S_ISREG(status.st_mode); +#elif !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) + return (status.st_mode & S_IFMT) == S_IFREG; +#else + static_assert(false, "No POSIX stat() support."); +#endif +} + +/// https://en.cppreference.com/w/cpp/filesystem/is_regular_file +inline bool is_regular_file(StringPiece path, std::error_code& ec) noexcept { + return is_regular_file(status(path, ec)); +} + +/// https://en.cppreference.com/w/cpp/filesystem/is_directory +inline bool is_directory(file_status status) noexcept { +#if defined(S_ISDIR) + return S_ISDIR(status.st_mode); +#elif !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) + return (status.st_mode & S_IFMT) == S_IFDIR; +#else + static_assert(false, "NO POSIX stat() support."); +#endif +} + +/// https://en.cppreference.com/w/cpp/filesystem/is_directory +inline bool is_directory(StringPiece path, std::error_code& ec) noexcept { + return is_directory(status(path, ec)); +} + +/// https://en.cppreference.com/w/cpp/filesystem/file_size +inline std::uintmax_t file_size( + StringPiece path, + std::error_code& ec) noexcept { + auto stat = status(path, ec); + if (ec) { + return std::numeric_limits::max(); + } + if (!is_regular_file(stat)) { + ec.assign(ENOTSUP, std::generic_category()); + return std::numeric_limits::max(); + } + ec.clear(); + return stat.st_size; +} +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Likely.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Likely.h new file mode 100644 index 000000000..52243a64e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Likely.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + +/** + * Compiler hints to indicate the fast path of an "if" branch: whether + * the if condition is likely to be true or false. + * + * @author Tudor Bosman (tudorb@fb.com) + */ + +#pragma once + +#undef LIKELY +#undef UNLIKELY + +#if defined(__GNUC__) && __GNUC__ >= 4 +#define LIKELY(x) (__builtin_expect((x), 1)) +#define UNLIKELY(x) (__builtin_expect((x), 0)) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Portability.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Portability.h new file mode 100644 index 000000000..ef1f86e51 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Portability.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + +#pragma once + +#include + +// Required for windows, which defines min/max, but we want the std:: version. +#undef min +#undef max diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Range.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Range.h new file mode 100644 index 000000000..0fd8f9f86 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/Range.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + +/** + * A subset of `folly/Range.h`. + * All code copied verbatim modulo formatting + */ +#pragma once + +#include "utils/Likely.h" +#include "utils/Portability.h" + +#include +#include +#include +#include +#include +#include + +namespace pzstd { + +namespace detail { +/* + *Use IsCharPointer::type to enable const char* or char*. + *Use IsCharPointer::const_type to enable only const char*. +*/ +template +struct IsCharPointer {}; + +template <> +struct IsCharPointer { + typedef int type; +}; + +template <> +struct IsCharPointer { + typedef int const_type; + typedef int type; +}; + +} // namespace detail + +template +class Range { + Iter b_; + Iter e_; + + public: + using size_type = std::size_t; + using iterator = Iter; + using const_iterator = Iter; + using value_type = typename std::remove_reference< + typename std::iterator_traits::reference>::type; + using reference = typename std::iterator_traits::reference; + + constexpr Range() : b_(), e_() {} + constexpr Range(Iter begin, Iter end) : b_(begin), e_(end) {} + + constexpr Range(Iter begin, size_type size) : b_(begin), e_(begin + size) {} + + template ::type = 0> + /* implicit */ Range(Iter str) : b_(str), e_(str + std::strlen(str)) {} + + template ::const_type = 0> + /* implicit */ Range(const std::string& str) + : b_(str.data()), e_(b_ + str.size()) {} + + // Allow implicit conversion from Range to Range if From is + // implicitly convertible to To. + template < + class OtherIter, + typename std::enable_if< + (!std::is_same::value && + std::is_convertible::value), + int>::type = 0> + constexpr /* implicit */ Range(const Range& other) + : b_(other.begin()), e_(other.end()) {} + + Range(const Range&) = default; + Range(Range&&) = default; + + Range& operator=(const Range&) = default; + Range& operator=(Range&&) = default; + + constexpr size_type size() const { + return e_ - b_; + } + bool empty() const { + return b_ == e_; + } + Iter data() const { + return b_; + } + Iter begin() const { + return b_; + } + Iter end() const { + return e_; + } + + void advance(size_type n) { + if (UNLIKELY(n > size())) { + throw std::out_of_range("index out of range"); + } + b_ += n; + } + + void subtract(size_type n) { + if (UNLIKELY(n > size())) { + throw std::out_of_range("index out of range"); + } + e_ -= n; + } + + Range subpiece(size_type first, size_type length = std::string::npos) const { + if (UNLIKELY(first > size())) { + throw std::out_of_range("index out of range"); + } + + return Range(b_ + first, std::min(length, size() - first)); + } +}; + +using ByteRange = Range; +using MutableByteRange = Range; +using StringPiece = Range; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ResourcePool.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ResourcePool.h new file mode 100644 index 000000000..7c4bb6235 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ResourcePool.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include +#include +#include +#include +#include + +namespace pzstd { + +/** + * An unbounded pool of resources. + * A `ResourcePool` requires a factory function that takes allocates `T*` and + * a free function that frees a `T*`. + * Calling `ResourcePool::get()` will give you a new `ResourcePool::UniquePtr` + * to a `T`, and when it goes out of scope the resource will be returned to the + * pool. + * The `ResourcePool` *must* survive longer than any resources it hands out. + * Remember that `ResourcePool` hands out mutable `T`s, so make sure to clean + * up the resource before or after every use. + */ +template +class ResourcePool { + public: + class Deleter; + using Factory = std::function; + using Free = std::function; + using UniquePtr = std::unique_ptr; + + private: + std::mutex mutex_; + Factory factory_; + Free free_; + std::vector resources_; + unsigned inUse_; + + public: + /** + * Creates a `ResourcePool`. + * + * @param factory The function to use to create new resources. + * @param free The function to use to free resources created by `factory`. + */ + ResourcePool(Factory factory, Free free) + : factory_(std::move(factory)), free_(std::move(free)), inUse_(0) {} + + /** + * @returns A unique pointer to a resource. The resource is null iff + * there are no available resources and `factory()` returns null. + */ + UniquePtr get() { + std::lock_guard lock(mutex_); + if (!resources_.empty()) { + UniquePtr resource{resources_.back(), Deleter{*this}}; + resources_.pop_back(); + ++inUse_; + return resource; + } + UniquePtr resource{factory_(), Deleter{*this}}; + ++inUse_; + return resource; + } + + ~ResourcePool() noexcept { + assert(inUse_ == 0); + for (const auto resource : resources_) { + free_(resource); + } + } + + class Deleter { + ResourcePool *pool_; + public: + explicit Deleter(ResourcePool &pool) : pool_(&pool) {} + + void operator() (T *resource) { + std::lock_guard lock(pool_->mutex_); + // Make sure we don't put null resources into the pool + if (resource) { + pool_->resources_.push_back(resource); + } + assert(pool_->inUse_ > 0); + --pool_->inUse_; + } + }; +}; + +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ScopeGuard.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ScopeGuard.h new file mode 100644 index 000000000..911fd9842 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ScopeGuard.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include + +namespace pzstd { + +/** + * Dismissable scope guard. + * `Function` must be callable and take no parameters. + * Unless `dismiss()` is called, the callable is executed upon destruction of + * `ScopeGuard`. + * + * Example: + * + * auto guard = makeScopeGuard([&] { cleanup(); }); + */ +template +class ScopeGuard { + Function function; + bool dismissed; + + public: + explicit ScopeGuard(Function&& function) + : function(std::move(function)), dismissed(false) {} + + void dismiss() { + dismissed = true; + } + + ~ScopeGuard() noexcept { + if (!dismissed) { + function(); + } + } +}; + +/// Creates a scope guard from `function`. +template +ScopeGuard makeScopeGuard(Function&& function) { + return ScopeGuard(std::forward(function)); +} +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ThreadPool.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ThreadPool.h new file mode 100644 index 000000000..a087d7c1c --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/ThreadPool.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include "utils/WorkQueue.h" + +#include +#include +#include +#include + +namespace pzstd { +/// A simple thread pool that pulls tasks off its queue in FIFO order. +class ThreadPool { + std::vector threads_; + + WorkQueue> tasks_; + + public: + /// Constructs a thread pool with `numThreads` threads. + explicit ThreadPool(std::size_t numThreads) { + threads_.reserve(numThreads); + for (std::size_t i = 0; i < numThreads; ++i) { + threads_.emplace_back([this] { + std::function task; + while (tasks_.pop(task)) { + task(); + } + }); + } + } + + /// Finishes all tasks currently in the queue. + ~ThreadPool() { + tasks_.finish(); + for (auto& thread : threads_) { + thread.join(); + } + } + + /** + * Adds `task` to the queue of tasks to execute. Since `task` is a + * `std::function<>`, it cannot be a move only type. So any lambda passed must + * not capture move only types (like `std::unique_ptr`). + * + * @param task The task to execute. + */ + void add(std::function task) { + tasks_.push(std::move(task)); + } +}; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/WorkQueue.h b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/WorkQueue.h new file mode 100644 index 000000000..07842e598 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/WorkQueue.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#pragma once + +#include "utils/Buffer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace pzstd { + +/// Unbounded thread-safe work queue. +template +class WorkQueue { + // Protects all member variable access + std::mutex mutex_; + std::condition_variable readerCv_; + std::condition_variable writerCv_; + std::condition_variable finishCv_; + + std::queue queue_; + bool done_; + std::size_t maxSize_; + + // Must have lock to call this function + bool full() const { + if (maxSize_ == 0) { + return false; + } + return queue_.size() >= maxSize_; + } + + public: + /** + * Constructs an empty work queue with an optional max size. + * If `maxSize == 0` the queue size is unbounded. + * + * @param maxSize The maximum allowed size of the work queue. + */ + WorkQueue(std::size_t maxSize = 0) : done_(false), maxSize_(maxSize) {} + + /** + * Push an item onto the work queue. Notify a single thread that work is + * available. If `finish()` has been called, do nothing and return false. + * If `push()` returns false, then `item` has not been moved from. + * + * @param item Item to push onto the queue. + * @returns True upon success, false if `finish()` has been called. An + * item was pushed iff `push()` returns true. + */ + bool push(T&& item) { + { + std::unique_lock lock(mutex_); + while (full() && !done_) { + writerCv_.wait(lock); + } + if (done_) { + return false; + } + queue_.push(std::move(item)); + } + readerCv_.notify_one(); + return true; + } + + /** + * Attempts to pop an item off the work queue. It will block until data is + * available or `finish()` has been called. + * + * @param[out] item If `pop` returns `true`, it contains the popped item. + * If `pop` returns `false`, it is unmodified. + * @returns True upon success. False if the queue is empty and + * `finish()` has been called. + */ + bool pop(T& item) { + { + std::unique_lock lock(mutex_); + while (queue_.empty() && !done_) { + readerCv_.wait(lock); + } + if (queue_.empty()) { + assert(done_); + return false; + } + item = std::move(queue_.front()); + queue_.pop(); + } + writerCv_.notify_one(); + return true; + } + + /** + * Sets the maximum queue size. If `maxSize == 0` then it is unbounded. + * + * @param maxSize The new maximum queue size. + */ + void setMaxSize(std::size_t maxSize) { + { + std::lock_guard lock(mutex_); + maxSize_ = maxSize; + } + writerCv_.notify_all(); + } + + /** + * Promise that either the reader side or the writer side is done. + * If the writer is done, `push()` won't be called again, so once the queue + * is empty there will never be any more work. If the reader is done, `pop()` + * won't be called again, so further items pushed will just be ignored. + */ + void finish() { + { + std::lock_guard lock(mutex_); + done_ = true; + } + readerCv_.notify_all(); + writerCv_.notify_all(); + finishCv_.notify_all(); + } + + /// Blocks until `finish()` has been called (but the queue may not be empty). + void waitUntilFinished() { + std::unique_lock lock(mutex_); + while (!done_) { + finishCv_.wait(lock); + } + } +}; + +/// Work queue for `Buffer`s that knows the total number of bytes in the queue. +class BufferWorkQueue { + WorkQueue queue_; + std::atomic size_; + + public: + BufferWorkQueue(std::size_t maxSize = 0) : queue_(maxSize), size_(0) {} + + void push(Buffer buffer) { + size_.fetch_add(buffer.size()); + queue_.push(std::move(buffer)); + } + + bool pop(Buffer& buffer) { + bool result = queue_.pop(buffer); + if (result) { + size_.fetch_sub(buffer.size()); + } + return result; + } + + void setMaxSize(std::size_t maxSize) { + queue_.setMaxSize(maxSize); + } + + void finish() { + queue_.finish(); + } + + /** + * Blocks until `finish()` has been called. + * + * @returns The total number of bytes of all the `Buffer`s currently in the + * queue. + */ + std::size_t size() { + queue_.waitUntilFinished(); + return size_.load(); + } +}; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/BUCK b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/BUCK new file mode 100644 index 000000000..a5113cab6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/BUCK @@ -0,0 +1,35 @@ +cxx_test( + name='buffer_test', + srcs=['BufferTest.cpp'], + deps=['//contrib/pzstd/utils:buffer'], +) + +cxx_test( + name='range_test', + srcs=['RangeTest.cpp'], + deps=['//contrib/pzstd/utils:range'], +) + +cxx_test( + name='resource_pool_test', + srcs=['ResourcePoolTest.cpp'], + deps=['//contrib/pzstd/utils:resource_pool'], +) + +cxx_test( + name='scope_guard_test', + srcs=['ScopeGuardTest.cpp'], + deps=['//contrib/pzstd/utils:scope_guard'], +) + +cxx_test( + name='thread_pool_test', + srcs=['ThreadPoolTest.cpp'], + deps=['//contrib/pzstd/utils:thread_pool'], +) + +cxx_test( + name='work_queue_test', + srcs=['RangeTest.cpp'], + deps=['//contrib/pzstd/utils:work_queue'], +) diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/BufferTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/BufferTest.cpp new file mode 100644 index 000000000..58bf08dcd --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/BufferTest.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "utils/Buffer.h" +#include "utils/Range.h" + +#include +#include + +using namespace pzstd; + +namespace { +void deleter(const unsigned char* buf) { + delete[] buf; +} +} + +TEST(Buffer, Constructors) { + Buffer empty; + EXPECT_TRUE(empty.empty()); + EXPECT_EQ(0, empty.size()); + + Buffer sized(5); + EXPECT_FALSE(sized.empty()); + EXPECT_EQ(5, sized.size()); + + Buffer moved(std::move(sized)); + EXPECT_FALSE(sized.empty()); + EXPECT_EQ(5, sized.size()); + + Buffer assigned; + assigned = std::move(moved); + EXPECT_FALSE(sized.empty()); + EXPECT_EQ(5, sized.size()); +} + +TEST(Buffer, BufferManagement) { + std::shared_ptr buf(new unsigned char[10], deleter); + { + Buffer acquired(buf, MutableByteRange(buf.get(), buf.get() + 10)); + EXPECT_EQ(2, buf.use_count()); + Buffer moved(std::move(acquired)); + EXPECT_EQ(2, buf.use_count()); + Buffer assigned; + assigned = std::move(moved); + EXPECT_EQ(2, buf.use_count()); + + Buffer split = assigned.splitAt(5); + EXPECT_EQ(3, buf.use_count()); + + split.advance(1); + assigned.subtract(1); + EXPECT_EQ(3, buf.use_count()); + } + EXPECT_EQ(1, buf.use_count()); +} + +TEST(Buffer, Modifiers) { + Buffer buf(10); + { + unsigned char i = 0; + for (auto& byte : buf.range()) { + byte = i++; + } + } + + auto prefix = buf.splitAt(2); + + ASSERT_EQ(2, prefix.size()); + EXPECT_EQ(0, *prefix.data()); + + ASSERT_EQ(8, buf.size()); + EXPECT_EQ(2, *buf.data()); + + buf.advance(2); + EXPECT_EQ(4, *buf.data()); + + EXPECT_EQ(9, *(buf.range().end() - 1)); + + buf.subtract(2); + EXPECT_EQ(7, *(buf.range().end() - 1)); + + EXPECT_EQ(4, buf.size()); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/RangeTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/RangeTest.cpp new file mode 100644 index 000000000..8b7dee271 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/RangeTest.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "utils/Range.h" + +#include +#include + +using namespace pzstd; + +// Range is directly copied from folly. +// Just some sanity tests to make sure everything seems to work. + +TEST(Range, Constructors) { + StringPiece empty; + EXPECT_TRUE(empty.empty()); + EXPECT_EQ(0, empty.size()); + + std::string str = "hello"; + { + Range piece(str.begin(), str.end()); + EXPECT_EQ(5, piece.size()); + EXPECT_EQ('h', *piece.data()); + EXPECT_EQ('o', *(piece.end() - 1)); + } + + { + StringPiece piece(str.data(), str.size()); + EXPECT_EQ(5, piece.size()); + EXPECT_EQ('h', *piece.data()); + EXPECT_EQ('o', *(piece.end() - 1)); + } + + { + StringPiece piece(str); + EXPECT_EQ(5, piece.size()); + EXPECT_EQ('h', *piece.data()); + EXPECT_EQ('o', *(piece.end() - 1)); + } + + { + StringPiece piece(str.c_str()); + EXPECT_EQ(5, piece.size()); + EXPECT_EQ('h', *piece.data()); + EXPECT_EQ('o', *(piece.end() - 1)); + } +} + +TEST(Range, Modifiers) { + StringPiece range("hello world"); + ASSERT_EQ(11, range.size()); + + { + auto hello = range.subpiece(0, 5); + EXPECT_EQ(5, hello.size()); + EXPECT_EQ('h', *hello.data()); + EXPECT_EQ('o', *(hello.end() - 1)); + } + { + auto hello = range; + hello.subtract(6); + EXPECT_EQ(5, hello.size()); + EXPECT_EQ('h', *hello.data()); + EXPECT_EQ('o', *(hello.end() - 1)); + } + { + auto world = range; + world.advance(6); + EXPECT_EQ(5, world.size()); + EXPECT_EQ('w', *world.data()); + EXPECT_EQ('d', *(world.end() - 1)); + } + + std::string expected = "hello world"; + EXPECT_EQ(expected, std::string(range.begin(), range.end())); + EXPECT_EQ(expected, std::string(range.data(), range.size())); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ResourcePoolTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ResourcePoolTest.cpp new file mode 100644 index 000000000..750ee084b --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ResourcePoolTest.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "utils/ResourcePool.h" + +#include +#include +#include + +using namespace pzstd; + +TEST(ResourcePool, FullTest) { + unsigned numCreated = 0; + unsigned numDeleted = 0; + { + ResourcePool pool( + [&numCreated] { ++numCreated; return new int{5}; }, + [&numDeleted](int *x) { ++numDeleted; delete x; }); + + { + auto i = pool.get(); + EXPECT_EQ(5, *i); + *i = 6; + } + { + auto i = pool.get(); + EXPECT_EQ(6, *i); + auto j = pool.get(); + EXPECT_EQ(5, *j); + *j = 7; + } + { + auto i = pool.get(); + EXPECT_EQ(6, *i); + auto j = pool.get(); + EXPECT_EQ(7, *j); + } + } + EXPECT_EQ(2, numCreated); + EXPECT_EQ(numCreated, numDeleted); +} + +TEST(ResourcePool, ThreadSafe) { + std::atomic numCreated{0}; + std::atomic numDeleted{0}; + { + ResourcePool pool( + [&numCreated] { ++numCreated; return new int{0}; }, + [&numDeleted](int *x) { ++numDeleted; delete x; }); + auto push = [&pool] { + for (int i = 0; i < 100; ++i) { + auto x = pool.get(); + ++*x; + } + }; + std::thread t1{push}; + std::thread t2{push}; + t1.join(); + t2.join(); + + auto x = pool.get(); + auto y = pool.get(); + EXPECT_EQ(200, *x + *y); + } + EXPECT_GE(2, numCreated); + EXPECT_EQ(numCreated, numDeleted); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ScopeGuardTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ScopeGuardTest.cpp new file mode 100644 index 000000000..0f77cdf38 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ScopeGuardTest.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "utils/ScopeGuard.h" + +#include + +using namespace pzstd; + +TEST(ScopeGuard, Dismiss) { + { + auto guard = makeScopeGuard([&] { EXPECT_TRUE(false); }); + guard.dismiss(); + } +} + +TEST(ScopeGuard, Executes) { + bool executed = false; + { + auto guard = makeScopeGuard([&] { executed = true; }); + } + EXPECT_TRUE(executed); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ThreadPoolTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ThreadPoolTest.cpp new file mode 100644 index 000000000..a01052e60 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/ThreadPoolTest.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "utils/ThreadPool.h" + +#include +#include +#include +#include +#include + +using namespace pzstd; + +TEST(ThreadPool, Ordering) { + std::vector results; + + { + ThreadPool executor(1); + for (int i = 0; i < 10; ++i) { + executor.add([ &results, i ] { results.push_back(i); }); + } + } + + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(i, results[i]); + } +} + +TEST(ThreadPool, AllJobsFinished) { + std::atomic numFinished{0}; + std::atomic start{false}; + { + std::cerr << "Creating executor" << std::endl; + ThreadPool executor(5); + for (int i = 0; i < 10; ++i) { + executor.add([ &numFinished, &start ] { + while (!start.load()) { + std::this_thread::yield(); + } + ++numFinished; + }); + } + std::cerr << "Starting" << std::endl; + start.store(true); + std::cerr << "Finishing" << std::endl; + } + EXPECT_EQ(10, numFinished.load()); +} + +TEST(ThreadPool, AddJobWhileJoining) { + std::atomic done{false}; + { + ThreadPool executor(1); + executor.add([&executor, &done] { + while (!done.load()) { + std::this_thread::yield(); + } + // Sleep for a second to be sure that we are joining + std::this_thread::sleep_for(std::chrono::seconds(1)); + executor.add([] { + EXPECT_TRUE(false); + }); + }); + done.store(true); + } +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/WorkQueueTest.cpp b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/WorkQueueTest.cpp new file mode 100644 index 000000000..16600bb60 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/pzstd/utils/test/WorkQueueTest.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ +#include "utils/Buffer.h" +#include "utils/WorkQueue.h" + +#include +#include +#include +#include +#include +#include + +using namespace pzstd; + +namespace { +struct Popper { + WorkQueue* queue; + int* results; + std::mutex* mutex; + + void operator()() { + int result; + while (queue->pop(result)) { + std::lock_guard lock(*mutex); + results[result] = result; + } + } +}; +} + +TEST(WorkQueue, SingleThreaded) { + WorkQueue queue; + int result; + + queue.push(5); + EXPECT_TRUE(queue.pop(result)); + EXPECT_EQ(5, result); + + queue.push(1); + queue.push(2); + EXPECT_TRUE(queue.pop(result)); + EXPECT_EQ(1, result); + EXPECT_TRUE(queue.pop(result)); + EXPECT_EQ(2, result); + + queue.push(1); + queue.push(2); + queue.finish(); + EXPECT_TRUE(queue.pop(result)); + EXPECT_EQ(1, result); + EXPECT_TRUE(queue.pop(result)); + EXPECT_EQ(2, result); + EXPECT_FALSE(queue.pop(result)); + + queue.waitUntilFinished(); +} + +TEST(WorkQueue, SPSC) { + WorkQueue queue; + const int max = 100; + + for (int i = 0; i < 10; ++i) { + queue.push(int{i}); + } + + std::thread thread([ &queue, max ] { + int result; + for (int i = 0;; ++i) { + if (!queue.pop(result)) { + EXPECT_EQ(i, max); + break; + } + EXPECT_EQ(i, result); + } + }); + + std::this_thread::yield(); + for (int i = 10; i < max; ++i) { + queue.push(int{i}); + } + queue.finish(); + + thread.join(); +} + +TEST(WorkQueue, SPMC) { + WorkQueue queue; + std::vector results(50, -1); + std::mutex mutex; + std::vector threads; + for (int i = 0; i < 5; ++i) { + threads.emplace_back(Popper{&queue, results.data(), &mutex}); + } + + for (int i = 0; i < 50; ++i) { + queue.push(int{i}); + } + queue.finish(); + + for (auto& thread : threads) { + thread.join(); + } + + for (int i = 0; i < 50; ++i) { + EXPECT_EQ(i, results[i]); + } +} + +TEST(WorkQueue, MPMC) { + WorkQueue queue; + std::vector results(100, -1); + std::mutex mutex; + std::vector popperThreads; + for (int i = 0; i < 4; ++i) { + popperThreads.emplace_back(Popper{&queue, results.data(), &mutex}); + } + + std::vector pusherThreads; + for (int i = 0; i < 2; ++i) { + auto min = i * 50; + auto max = (i + 1) * 50; + pusherThreads.emplace_back( + [ &queue, min, max ] { + for (int i = min; i < max; ++i) { + queue.push(int{i}); + } + }); + } + + for (auto& thread : pusherThreads) { + thread.join(); + } + queue.finish(); + + for (auto& thread : popperThreads) { + thread.join(); + } + + for (int i = 0; i < 100; ++i) { + EXPECT_EQ(i, results[i]); + } +} + +TEST(WorkQueue, BoundedSizeWorks) { + WorkQueue queue(1); + int result; + queue.push(5); + queue.pop(result); + queue.push(5); + queue.pop(result); + queue.push(5); + queue.finish(); + queue.pop(result); + EXPECT_EQ(5, result); +} + +TEST(WorkQueue, BoundedSizePushAfterFinish) { + WorkQueue queue(1); + int result; + queue.push(5); + std::thread pusher([&queue] { + queue.push(6); + }); + // Dirtily try and make sure that pusher has run. + std::this_thread::sleep_for(std::chrono::seconds(1)); + queue.finish(); + EXPECT_TRUE(queue.pop(result)); + EXPECT_EQ(5, result); + EXPECT_FALSE(queue.pop(result)); + + pusher.join(); +} + +TEST(WorkQueue, SetMaxSize) { + WorkQueue queue(2); + int result; + queue.push(5); + queue.push(6); + queue.setMaxSize(1); + std::thread pusher([&queue] { + queue.push(7); + }); + // Dirtily try and make sure that pusher has run. + std::this_thread::sleep_for(std::chrono::seconds(1)); + queue.finish(); + EXPECT_TRUE(queue.pop(result)); + EXPECT_EQ(5, result); + EXPECT_TRUE(queue.pop(result)); + EXPECT_EQ(6, result); + EXPECT_FALSE(queue.pop(result)); + + pusher.join(); +} + +TEST(WorkQueue, BoundedSizeMPMC) { + WorkQueue queue(10); + std::vector results(200, -1); + std::mutex mutex; + std::cerr << "Creating popperThreads" << std::endl; + std::vector popperThreads; + for (int i = 0; i < 4; ++i) { + popperThreads.emplace_back(Popper{&queue, results.data(), &mutex}); + } + + std::cerr << "Creating pusherThreads" << std::endl; + std::vector pusherThreads; + for (int i = 0; i < 2; ++i) { + auto min = i * 100; + auto max = (i + 1) * 100; + pusherThreads.emplace_back( + [ &queue, min, max ] { + for (int i = min; i < max; ++i) { + queue.push(int{i}); + } + }); + } + + std::cerr << "Joining pusherThreads" << std::endl; + for (auto& thread : pusherThreads) { + thread.join(); + } + std::cerr << "Finishing queue" << std::endl; + queue.finish(); + + std::cerr << "Joining popperThreads" << std::endl; + for (auto& thread : popperThreads) { + thread.join(); + } + + std::cerr << "Inspecting results" << std::endl; + for (int i = 0; i < 200; ++i) { + EXPECT_EQ(i, results[i]); + } +} + +TEST(WorkQueue, FailedPush) { + WorkQueue> queue; + std::unique_ptr x(new int{5}); + EXPECT_TRUE(queue.push(std::move(x))); + EXPECT_EQ(nullptr, x); + queue.finish(); + x.reset(new int{6}); + EXPECT_FALSE(queue.push(std::move(x))); + EXPECT_NE(nullptr, x); + EXPECT_EQ(6, *x); +} + +TEST(BufferWorkQueue, SizeCalculatedCorrectly) { + { + BufferWorkQueue queue; + queue.finish(); + EXPECT_EQ(0, queue.size()); + } + { + BufferWorkQueue queue; + queue.push(Buffer(10)); + queue.finish(); + EXPECT_EQ(10, queue.size()); + } + { + BufferWorkQueue queue; + queue.push(Buffer(10)); + queue.push(Buffer(5)); + queue.finish(); + EXPECT_EQ(15, queue.size()); + } + { + BufferWorkQueue queue; + queue.push(Buffer(10)); + queue.push(Buffer(5)); + queue.finish(); + Buffer buffer; + queue.pop(buffer); + EXPECT_EQ(5, queue.size()); + } +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/recovery/Makefile b/cpp/third_party/zstd-1.5.7/contrib/recovery/Makefile new file mode 100644 index 000000000..be6ea4b0e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/recovery/Makefile @@ -0,0 +1,35 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +.PHONY: all +all: recover_directory + +ZSTDLIBDIR ?= ../../lib +PROGRAMDIR ?= ../../programs + +CFLAGS ?= -O3 +CFLAGS += -I$(ZSTDLIBDIR) -I$(PROGRAMDIR) +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum \ + -Wstrict-prototypes -Wundef \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls -Wmissing-prototypes +CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) + +.PHONY: $(ZSTDLIBDIR)/libzstd.a +$(ZSTDLIBDIR)/libzstd.a: + $(MAKE) -C $(ZSTDLIBDIR) libzstd.a + +recover_directory: recover_directory.c $(ZSTDLIBDIR)/libzstd.a $(PROGRAMDIR)/util.c + $(CC) $(FLAGS) $^ -o $@$(EXT) + +.PHONY: clean +clean: + rm -f recover_directory diff --git a/cpp/third_party/zstd-1.5.7/contrib/recovery/recover_directory.c b/cpp/third_party/zstd-1.5.7/contrib/recovery/recover_directory.c new file mode 100644 index 000000000..b9bd7ab49 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/recovery/recover_directory.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include +#include +#include + +#define ZSTD_STATIC_LINKING_ONLY +#include "util.h" +#include "zstd.h" + +#define CHECK(cond, ...) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, "%s:%d CHECK(%s) failed: ", __FILE__, __LINE__, #cond); \ + fprintf(stderr, "" __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + exit(1); \ + } \ + } while (0) + +static void usage(char const *program) { + fprintf(stderr, "USAGE: %s FILE.zst PREFIX\n", program); + fprintf(stderr, "FILE.zst: A zstd compressed file with multiple frames\n"); + fprintf(stderr, "PREFIX: The output prefix. Uncompressed files will be " + "created named ${PREFIX}0 ${PREFIX}1...\n\n"); + fprintf(stderr, "This program takes concatenated zstd frames and " + "decompresses them into individual files.\n"); + fprintf(stderr, "E.g. files created with a command like: zstd -r directory " + "-o file.zst\n"); +} + +typedef struct { + char *data; + size_t size; + size_t frames; + size_t maxFrameSize; +} ZstdFrames; + +static ZstdFrames readFile(char const *fileName) { + U64 const fileSize = UTIL_getFileSize(fileName); + CHECK(fileSize != UTIL_FILESIZE_UNKNOWN, "Unknown file size!"); + + char *const data = (char *)malloc(fileSize); + CHECK(data != NULL, "Allocation failed"); + + FILE *file = fopen(fileName, "rb"); + CHECK(file != NULL, "fopen failed"); + + size_t const readSize = fread(data, 1, fileSize, file); + CHECK(readSize == fileSize, "fread failed"); + + fclose(file); + ZstdFrames frames; + frames.data = (char *)data; + frames.size = fileSize; + frames.frames = 0; + + size_t index; + size_t maxFrameSize = 0; + for (index = 0; index < fileSize;) { + size_t const frameSize = + ZSTD_findFrameCompressedSize(data + index, fileSize - index); + CHECK(!ZSTD_isError(frameSize), "Bad zstd frame: %s", + ZSTD_getErrorName(frameSize)); + if (frameSize > maxFrameSize) + maxFrameSize = frameSize; + frames.frames += 1; + index += frameSize; + } + CHECK(index == fileSize, "Zstd file corrupt!"); + frames.maxFrameSize = maxFrameSize; + + return frames; +} + +static int computePadding(size_t numFrames) { + return snprintf(NULL, 0, "%u", (unsigned)numFrames); +} + +int main(int argc, char **argv) { + if (argc != 3) { + usage(argv[0]); + exit(1); + } + char const *const zstdFile = argv[1]; + char const *const prefix = argv[2]; + + ZstdFrames frames = readFile(zstdFile); + + if (frames.frames <= 1) { + fprintf( + stderr, + "%s only has %u zstd frame. Simply use `zstd -d` to decompress it.\n", + zstdFile, (unsigned)frames.frames); + exit(1); + } + + int const padding = computePadding(frames.frames - 1); + + size_t const outFileNameSize = strlen(prefix) + padding + 1; + char* outFileName = malloc(outFileNameSize); + CHECK(outFileName != NULL, "Allocation failure"); + + size_t const bufferSize = 128 * 1024; + void *buffer = malloc(bufferSize); + CHECK(buffer != NULL, "Allocation failure"); + + ZSTD_DCtx* dctx = ZSTD_createDCtx(); + CHECK(dctx != NULL, "Allocation failure"); + + fprintf(stderr, "Recovering %u files...\n", (unsigned)frames.frames); + + size_t index; + size_t frame = 0; + for (index = 0; index < frames.size; ++frame) { + size_t const frameSize = + ZSTD_findFrameCompressedSize(frames.data + index, frames.size - index); + + int const ret = snprintf(outFileName, outFileNameSize, "%s%0*u", prefix, padding, (unsigned)frame); + CHECK(ret >= 0 && (size_t)ret <= outFileNameSize, "snprintf failed!"); + + FILE* outFile = fopen(outFileName, "wb"); + CHECK(outFile != NULL, "fopen failed"); + + ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only); + ZSTD_inBuffer in = {frames.data + index, frameSize, 0}; + while (in.pos < in.size) { + ZSTD_outBuffer out = {buffer, bufferSize, 0}; + CHECK(!ZSTD_isError(ZSTD_decompressStream(dctx, &out, &in)), "decompression failed"); + size_t const writeSize = fwrite(out.dst, 1, out.pos, outFile); + CHECK(writeSize == out.pos, "fwrite failed"); + } + fclose(outFile); + fprintf(stderr, "Recovered %s\n", outFileName); + index += frameSize; + } + fprintf(stderr, "Complete\n"); + + free(outFileName); + ZSTD_freeDCtx(dctx); + free(buffer); + free(frames.data); + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/README.md b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/README.md new file mode 100644 index 000000000..fedf96bab --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/README.md @@ -0,0 +1,42 @@ +# Zstandard Seekable Format + +The seekable format splits compressed data into a series of independent "frames", +each compressed individually, +so that decompression of a section in the middle of an archive +only requires zstd to decompress at most a frame's worth of extra data, +instead of the entire archive. + +The frames are appended, so that the decompression of the entire payload +still regenerates the original content, using any compliant zstd decoder. + +On top of that, the seekable format generates a jump table, +which makes it possible to jump directly to the position of the relevant frame +when requesting only a segment of the data. +The jump table is simply ignored by zstd decoders unaware of the seekable format. + +The format is delivered with an API to create seekable archives +and to retrieve arbitrary segments inside the archive. + +### Maximum Frame Size parameter + +When creating a seekable archive, the main parameter is the maximum frame size. + +At compression time, user can manually select the boundaries between segments, +but they don't have to: long segments will be automatically split +when larger than selected maximum frame size. + +Small frame sizes reduce decompression cost when requesting small segments, +because the decoder will nonetheless have to decompress an entire frame +to recover just a single byte from it. + +A good rule of thumb is to select a maximum frame size roughly equivalent +to the access pattern when it's known. +For example, if the application tends to request 4KB blocks, +then it's a good idea to set a maximum frame size in the vicinity of 4 KB. + +But small frame sizes also reduce compression ratio, +and increase the cost for the jump table, +so there is a balance to find. + +In general, try to avoid really tiny frame sizes (<1 KB), +which would have a large negative impact on compression ratio. diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/.gitignore b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/.gitignore new file mode 100644 index 000000000..0b83f5e11 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/.gitignore @@ -0,0 +1,5 @@ +seekable_compression +seekable_decompression +seekable_decompression_mem +parallel_processing +parallel_compression diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/Makefile b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/Makefile new file mode 100644 index 000000000..fcc04587c --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/Makefile @@ -0,0 +1,53 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +# This Makefile presumes libzstd is built, using `make` in / or /lib/ + +ZSTDLIB_PATH = ../../../lib +ZSTDLIB_NAME = libzstd.a +ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME) + +CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -I../ -I../../../lib -I../../../lib/common + +CFLAGS ?= -O3 +CFLAGS += -g + +SEEKABLE_OBJS = ../zstdseek_compress.c ../zstdseek_decompress.c $(ZSTDLIB) + +.PHONY: default all clean test + +default: all + +all: seekable_compression seekable_decompression seekable_decompression_mem \ + parallel_processing + +$(ZSTDLIB): + make -C $(ZSTDLIB_PATH) $(ZSTDLIB_NAME) + +seekable_compression : seekable_compression.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +seekable_decompression : seekable_decompression.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +seekable_decompression_mem : seekable_decompression_mem.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +parallel_processing : parallel_processing.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ -pthread + +parallel_compression : parallel_compression.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ -pthread + +clean: + @rm -f core *.o tmp* result* *.zst \ + seekable_compression seekable_decompression \ + seekable_decompression_mem \ + parallel_processing parallel_compression + @echo Cleaning completed diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/parallel_compression.c b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/parallel_compression.c new file mode 100644 index 000000000..4e06fae32 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/parallel_compression.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + +#include // malloc, free, exit, atoi +#include // fprintf, perror, feof, fopen, etc. +#include // strlen, memset, strcat +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed +#include +#if defined(WIN32) || defined(_WIN32) +# include +# define SLEEP(x) Sleep(x) +#else +# include +# define SLEEP(x) usleep(x * 1000) +#endif + +#include "xxhash.h" + +#include "pool.h" // use zstd thread pool for demo + +#include "../zstd_seekable.h" + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc:"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void fseek_orDie(FILE* file, long int offset, int origin) +{ + if (!fseek(file, offset, origin)) { + if (!fflush(file)) return; + } + /* error */ + perror("fseek"); + exit(7); +} + +static long int ftell_orDie(FILE* file) +{ + long int off = ftell(file); + if (off != -1) return off; + /* error */ + perror("ftell"); + exit(8); +} + +struct job { + const void* src; + size_t srcSize; + void* dst; + size_t dstSize; + + unsigned checksum; + + int compressionLevel; + int done; +}; + +static void compressFrame(void* opaque) +{ + struct job* job = opaque; + + job->checksum = XXH64(job->src, job->srcSize, 0); + + size_t ret = ZSTD_compress(job->dst, job->dstSize, job->src, job->srcSize, job->compressionLevel); + if (ZSTD_isError(ret)) { + fprintf(stderr, "ZSTD_compress() error : %s \n", ZSTD_getErrorName(ret)); + exit(20); + } + + job->dstSize = ret; + job->done = 1; +} + +static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned frameSize, int nbThreads) +{ + POOL_ctx* pool = POOL_create(nbThreads, nbThreads); + if (pool == NULL) { fprintf(stderr, "POOL_create() error \n"); exit(9); } + + FILE* const fin = fopen_orDie(fname, "rb"); + FILE* const fout = fopen_orDie(outName, "wb"); + + if (ZSTD_compressBound(frameSize) > 0xFFFFFFFFU) { fprintf(stderr, "Frame size too large \n"); exit(10); } + unsigned dstSize = ZSTD_compressBound(frameSize); + + + fseek_orDie(fin, 0, SEEK_END); + long int length = ftell_orDie(fin); + fseek_orDie(fin, 0, SEEK_SET); + + size_t numFrames = (length + frameSize - 1) / frameSize; + + struct job* jobs = malloc_orDie(sizeof(struct job) * numFrames); + + size_t i; + for(i = 0; i < numFrames; i++) { + void* in = malloc_orDie(frameSize); + void* out = malloc_orDie(dstSize); + + size_t inSize = fread_orDie(in, frameSize, fin); + + jobs[i].src = in; + jobs[i].srcSize = inSize; + jobs[i].dst = out; + jobs[i].dstSize = dstSize; + jobs[i].compressionLevel = cLevel; + jobs[i].done = 0; + POOL_add(pool, compressFrame, &jobs[i]); + } + + ZSTD_frameLog* fl = ZSTD_seekable_createFrameLog(1); + if (fl == NULL) { fprintf(stderr, "ZSTD_seekable_createFrameLog() failed \n"); exit(11); } + for (i = 0; i < numFrames; i++) { + while (!jobs[i].done) SLEEP(5); /* wake up every 5 milliseconds to check */ + fwrite_orDie(jobs[i].dst, jobs[i].dstSize, fout); + free((void*)jobs[i].src); + free(jobs[i].dst); + + size_t ret = ZSTD_seekable_logFrame(fl, jobs[i].dstSize, jobs[i].srcSize, jobs[i].checksum); + if (ZSTD_isError(ret)) { fprintf(stderr, "ZSTD_seekable_logFrame() error : %s \n", ZSTD_getErrorName(ret)); } + } + + { unsigned char seekTableBuff[1024]; + ZSTD_outBuffer out = {seekTableBuff, 1024, 0}; + while (ZSTD_seekable_writeSeekTable(fl, &out) != 0) { + fwrite_orDie(seekTableBuff, out.pos, fout); + out.pos = 0; + } + fwrite_orDie(seekTableBuff, out.pos, fout); + } + + ZSTD_seekable_freeFrameLog(fl); + free(jobs); + fclose_orDie(fout); + fclose_orDie(fin); +} + +static const char* createOutFilename_orDie(const char* filename) +{ + size_t const inL = strlen(filename); + size_t const outL = inL + 5; + void* outSpace = malloc_orDie(outL); + memset(outSpace, 0, outL); + strcat(outSpace, filename); + strcat(outSpace, ".zst"); + return (const char*)outSpace; +} + +int main(int argc, const char** argv) { + const char* const exeName = argv[0]; + if (argc!=4) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s FILE FRAME_SIZE NB_THREADS\n", exeName); + return 1; + } + + { const char* const inFileName = argv[1]; + unsigned const frameSize = (unsigned)atoi(argv[2]); + int const nbThreads = atoi(argv[3]); + + const char* const outFileName = createOutFilename_orDie(inFileName); + compressFile_orDie(inFileName, outFileName, 5, frameSize, nbThreads); + } + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/parallel_processing.c b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/parallel_processing.c new file mode 100644 index 000000000..928371025 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/parallel_processing.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + +/* + * A simple demo that sums up all the bytes in the file in parallel using + * seekable decompression and the zstd thread pool + */ + +#include // malloc, exit +#include // fprintf, perror, feof +#include // strerror +#include // errno +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed +#include +#if defined(_WIN32) +# include +# define SLEEP(x) Sleep(x) +#else +# include +# define SLEEP(x) usleep(x * 1000) +#endif + +#include "pool.h" // use zstd thread pool for demo + +#include "../zstd_seekable.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc"); + exit(1); +} + +static void* realloc_orDie(void* ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr) return ptr; + /* error */ + perror("realloc"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void fseek_orDie(FILE* file, long int offset, int origin) { + if (!fseek(file, offset, origin)) { + if (!fflush(file)) return; + } + /* error */ + perror("fseek"); + exit(7); +} + +struct sum_job { + const char* fname; + unsigned long long sum; + unsigned frameNb; + int done; +}; + +static void sumFrame(void* opaque) +{ + struct sum_job* job = (struct sum_job*)opaque; + job->done = 0; + + FILE* const fin = fopen_orDie(job->fname, "rb"); + + ZSTD_seekable* const seekable = ZSTD_seekable_create(); + if (seekable==NULL) { fprintf(stderr, "ZSTD_seekable_create() error \n"); exit(10); } + + size_t const initResult = ZSTD_seekable_initFile(seekable, fin); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_init() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + size_t const frameSize = ZSTD_seekable_getFrameDecompressedSize(seekable, job->frameNb); + unsigned char* data = malloc_orDie(frameSize); + + size_t result = ZSTD_seekable_decompressFrame(seekable, data, frameSize, job->frameNb); + if (ZSTD_isError(result)) { fprintf(stderr, "ZSTD_seekable_decompressFrame() error : %s \n", ZSTD_getErrorName(result)); exit(12); } + + unsigned long long sum = 0; + size_t i; + for (i = 0; i < frameSize; i++) { + sum += data[i]; + } + job->sum = sum; + job->done = 1; + + fclose(fin); + ZSTD_seekable_free(seekable); + free(data); +} + +static void sumFile_orDie(const char* fname, int nbThreads) +{ + POOL_ctx* pool = POOL_create(nbThreads, nbThreads); + if (pool == NULL) { fprintf(stderr, "POOL_create() error \n"); exit(9); } + + FILE* const fin = fopen_orDie(fname, "rb"); + + ZSTD_seekable* const seekable = ZSTD_seekable_create(); + if (seekable==NULL) { fprintf(stderr, "ZSTD_seekable_create() error \n"); exit(10); } + + size_t const initResult = ZSTD_seekable_initFile(seekable, fin); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_init() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + unsigned const numFrames = ZSTD_seekable_getNumFrames(seekable); + struct sum_job* jobs = (struct sum_job*)malloc(numFrames * sizeof(struct sum_job)); + + unsigned fnb; + for (fnb = 0; fnb < numFrames; fnb++) { + jobs[fnb] = (struct sum_job){ fname, 0, fnb, 0 }; + POOL_add(pool, sumFrame, &jobs[fnb]); + } + + unsigned long long total = 0; + + for (fnb = 0; fnb < numFrames; fnb++) { + while (!jobs[fnb].done) SLEEP(5); /* wake up every 5 milliseconds to check */ + total += jobs[fnb].sum; + } + + printf("Sum: %llu\n", total); + + POOL_free(pool); + ZSTD_seekable_free(seekable); + fclose(fin); + free(jobs); +} + + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc!=3) { + fprintf(stderr, "wrong arguments\n"); + fprintf(stderr, "usage:\n"); + fprintf(stderr, "%s FILE NB_THREADS\n", exeName); + return 1; + } + + { + const char* const inFilename = argv[1]; + int const nbThreads = atoi(argv[2]); + sumFile_orDie(inFilename, nbThreads); + } + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_compression.c b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_compression.c new file mode 100644 index 000000000..c3d227dd0 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_compression.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + +#include // malloc, free, exit, atoi +#include // fprintf, perror, feof, fopen, etc. +#include // strlen, memset, strcat +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed + +#include "../zstd_seekable.h" + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc:"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned frameSize) +{ + FILE* const fin = fopen_orDie(fname, "rb"); + FILE* const fout = fopen_orDie(outName, "wb"); + size_t const buffInSize = ZSTD_CStreamInSize(); /* can always read one full block */ + void* const buffIn = malloc_orDie(buffInSize); + size_t const buffOutSize = ZSTD_CStreamOutSize(); /* can always flush a full block */ + void* const buffOut = malloc_orDie(buffOutSize); + + ZSTD_seekable_CStream* const cstream = ZSTD_seekable_createCStream(); + if (cstream==NULL) { fprintf(stderr, "ZSTD_seekable_createCStream() error \n"); exit(10); } + size_t const initResult = ZSTD_seekable_initCStream(cstream, cLevel, 1, frameSize); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_initCStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + size_t read, toRead = buffInSize; + while( (read = fread_orDie(buffIn, toRead, fin)) ) { + ZSTD_inBuffer input = { buffIn, read, 0 }; + while (input.pos < input.size) { + ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; + toRead = ZSTD_seekable_compressStream(cstream, &output , &input); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */ + if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_seekable_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); } + if (toRead > buffInSize) toRead = buffInSize; /* Safely handle case when `buffInSize` is manually changed to a value < ZSTD_CStreamInSize()*/ + fwrite_orDie(buffOut, output.pos, fout); + } + } + + while (1) { + ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; + size_t const remainingToFlush = ZSTD_seekable_endStream(cstream, &output); /* close stream */ + if (ZSTD_isError(remainingToFlush)) { fprintf(stderr, "ZSTD_seekable_endStream() error : %s \n", ZSTD_getErrorName(remainingToFlush)); exit(13); } + fwrite_orDie(buffOut, output.pos, fout); + if (!remainingToFlush) break; + } + + ZSTD_seekable_freeCStream(cstream); + fclose_orDie(fout); + fclose_orDie(fin); + free(buffIn); + free(buffOut); +} + +static char* createOutFilename_orDie(const char* filename) +{ + size_t const inL = strlen(filename); + size_t const outL = inL + 5; + void* outSpace = malloc_orDie(outL); + memset(outSpace, 0, outL); + strcat(outSpace, filename); + strcat(outSpace, ".zst"); + return (char*)outSpace; +} + +#define CLEVEL_DEFAULT 5 +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + if (argc<3 || argc>4) { + printf("wrong arguments \n"); + printf("usage: \n"); + printf("%s FILE FRAME_SIZE [LEVEL] \n", exeName); + return 1; + } + + { const char* const inFileName = argv[1]; + unsigned const frameSize = (unsigned)atoi(argv[2]); + int const cLevel = (argc==4) ? atoi(argv[3]) : CLEVEL_DEFAULT; + + char* const outFileName = createOutFilename_orDie(inFileName); + compressFile_orDie(inFileName, outFileName, cLevel, frameSize); + free(outFileName); + } + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_decompression.c b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_decompression.c new file mode 100644 index 000000000..7edbca87d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_decompression.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + + +#include // malloc, exit +#include // fprintf, perror, feof +#include // strerror +#include // errno +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed +#include + +#include "../zstd_seekable.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc"); + exit(1); +} + +static void* realloc_orDie(void* ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr) return ptr; + /* error */ + perror("realloc"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void fseek_orDie(FILE* file, long int offset, int origin) { + if (!fseek(file, offset, origin)) { + if (!fflush(file)) return; + } + /* error */ + perror("fseek"); + exit(7); +} + + +static void decompressFile_orDie(const char* fname, off_t startOffset, off_t endOffset) +{ + FILE* const fin = fopen_orDie(fname, "rb"); + FILE* const fout = stdout; + size_t const buffOutSize = ZSTD_DStreamOutSize(); /* Guarantee to successfully flush at least one complete compressed block in all circumstances. */ + void* const buffOut = malloc_orDie(buffOutSize); + + ZSTD_seekable* const seekable = ZSTD_seekable_create(); + if (seekable==NULL) { fprintf(stderr, "ZSTD_seekable_create() error \n"); exit(10); } + + size_t const initResult = ZSTD_seekable_initFile(seekable, fin); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_init() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + while (startOffset < endOffset) { + size_t const result = ZSTD_seekable_decompress(seekable, buffOut, MIN(endOffset - startOffset, buffOutSize), startOffset); + if (!result) { + break; + } + + if (ZSTD_isError(result)) { + fprintf(stderr, "ZSTD_seekable_decompress() error : %s \n", + ZSTD_getErrorName(result)); + exit(12); + } + fwrite_orDie(buffOut, result, fout); + startOffset += result; + } + + ZSTD_seekable_free(seekable); + fclose_orDie(fin); + fclose_orDie(fout); + free(buffOut); +} + + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc!=4) { + fprintf(stderr, "wrong arguments\n"); + fprintf(stderr, "usage:\n"); + fprintf(stderr, "%s FILE START END\n", exeName); + return 1; + } + + { + const char* const inFilename = argv[1]; + off_t const startOffset = atoll(argv[2]); + off_t const endOffset = atoll(argv[3]); + decompressFile_orDie(inFilename, startOffset, endOffset); + } + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_decompression_mem.c b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_decompression_mem.c new file mode 100644 index 000000000..44a06fbbf --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/examples/seekable_decompression_mem.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + + +#include // malloc, exit +#include // fprintf, perror, feof +#include // strerror +#include // errno +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed +#include + +#include "zstd_seekable.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#define MAX_FILE_SIZE (8 * 1024 * 1024) + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc"); + exit(1); +} + +static void* realloc_orDie(void* ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr) return ptr; + /* error */ + perror("realloc"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void fseek_orDie(FILE* file, long int offset, int origin) { + if (!fseek(file, offset, origin)) { + if (!fflush(file)) return; + } + /* error */ + perror("fseek"); + exit(7); +} + + +static void decompressFile_orDie(const char* fname, off_t startOffset, off_t endOffset) +{ + FILE* const fin = fopen_orDie(fname, "rb"); + FILE* const fout = stdout; + // Just for demo purposes, assume file is <= MAX_FILE_SIZE + void* const buffIn = malloc_orDie(MAX_FILE_SIZE); + size_t const inSize = fread_orDie(buffIn, MAX_FILE_SIZE, fin); + size_t const buffOutSize = ZSTD_DStreamOutSize(); /* Guarantee to successfully flush at least one complete compressed block in all circumstances. */ + void* const buffOut = malloc_orDie(buffOutSize); + + ZSTD_seekable* const seekable = ZSTD_seekable_create(); + if (seekable==NULL) { fprintf(stderr, "ZSTD_seekable_create() error \n"); exit(10); } + + size_t const initResult = ZSTD_seekable_initBuff(seekable, buffIn, inSize); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_init() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + while (startOffset < endOffset) { + size_t const result = ZSTD_seekable_decompress(seekable, buffOut, MIN(endOffset - startOffset, buffOutSize), startOffset); + if (!result) { + break; + } + + if (ZSTD_isError(result)) { + fprintf(stderr, "ZSTD_seekable_decompress() error : %s \n", + ZSTD_getErrorName(result)); + exit(12); + } + fwrite_orDie(buffOut, result, fout); + startOffset += result; + } + + ZSTD_seekable_free(seekable); + fclose_orDie(fin); + fclose_orDie(fout); + free(buffIn); + free(buffOut); +} + + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc!=4) { + fprintf(stderr, "wrong arguments\n"); + fprintf(stderr, "usage:\n"); + fprintf(stderr, "%s FILE START END\n", exeName); + return 1; + } + + { + const char* const inFilename = argv[1]; + off_t const startOffset = atoll(argv[2]); + off_t const endOffset = atoll(argv[3]); + decompressFile_orDie(inFilename, startOffset, endOffset); + } + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/.gitignore b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/.gitignore new file mode 100644 index 000000000..f831eaf37 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/.gitignore @@ -0,0 +1 @@ +seekable_tests diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/Makefile b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/Makefile new file mode 100644 index 000000000..a81f2229f --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/Makefile @@ -0,0 +1,38 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +# This Makefile presumes libzstd is built, using `make` in / or /lib/ + +ZSTDLIB_PATH = ../../../lib +ZSTDLIB_NAME = libzstd.a +ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME) + +CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -I../ -I$(ZSTDLIB_PATH) -I$(ZSTDLIB_PATH)/common + +CFLAGS ?= -O3 +CFLAGS += -g -Wall -Wextra -Wcast-qual -Wcast-align -Wconversion \ + -Wformat=2 -Wstrict-aliasing=1 + +SEEKABLE_OBJS = ../zstdseek_compress.c ../zstdseek_decompress.c $(ZSTDLIB) + +.PHONY: default clean test +default: test + +test: seekable_tests + ./seekable_tests + +$(ZSTDLIB): + $(MAKE) -C $(ZSTDLIB_PATH) $(ZSTDLIB_NAME) + +seekable_tests : $(SEEKABLE_OBJS) + +clean: + @$(RM) core *.o tmp* result* *.zst \ + seekable_tests + @echo Cleaning completed diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/seekable_tests.c b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/seekable_tests.c new file mode 100644 index 000000000..f89bdc930 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/tests/seekable_tests.c @@ -0,0 +1,363 @@ +#include +#include +#include // malloc +#include +#include +#include + +#include "../zstd_seekable.h" + + +/* ZSTD_seekable_customFile implementation that reads/seeks a buffer while keeping track of total bytes read */ +typedef struct { + const void *ptr; + size_t size; + size_t pos; + size_t totalRead; +} buffWrapperWithTotal_t; + +static int readBuffWithTotal(void* opaque, void* buffer, size_t n) +{ + buffWrapperWithTotal_t* const buff = (buffWrapperWithTotal_t*)opaque; + assert(buff != NULL); + if (buff->pos + n > buff->size) return -1; + memcpy(buffer, (const char*)buff->ptr + buff->pos, n); + buff->pos += n; + buff->totalRead += n; + return 0; +} + +static int seekBuffWithTotal(void* opaque, long long offset, int origin) +{ + buffWrapperWithTotal_t* const buff = (buffWrapperWithTotal_t*) opaque; + unsigned long long newOffset; + assert(buff != NULL); + switch (origin) { + case SEEK_SET: + assert(offset >= 0); + newOffset = (unsigned long long)offset; + break; + case SEEK_CUR: + newOffset = (unsigned long long)((long long)buff->pos + offset); + break; + case SEEK_END: + newOffset = (unsigned long long)((long long)buff->size + offset); + break; + default: + assert(0); /* not possible */ + } + if (newOffset > buff->size) { + return -1; + } + buff->pos = newOffset; + return 0; +} + +/* Basic unit tests for zstd seekable format */ +int main(int argc, const char** argv) +{ + unsigned testNb = 1; + (void)argc; (void)argv; + printf("Beginning zstd seekable format tests...\n"); + + printf("Test %u - simple round trip: ", testNb++); + { size_t const inSize = 4000; + void* const inBuffer = malloc(inSize); + assert(inBuffer != NULL); + + size_t const seekCapacity = 5000; + void* const seekBuffer = malloc(seekCapacity); + assert(seekBuffer != NULL); + size_t seekSize; + + size_t const outCapacity = inSize; + void* const outBuffer = malloc(outCapacity); + assert(outBuffer != NULL); + + ZSTD_seekable_CStream* const zscs = ZSTD_seekable_createCStream(); + assert(zscs != NULL); + + { size_t const initStatus = ZSTD_seekable_initCStream(zscs, 9, 0 /* checksumFlag */, (unsigned)inSize /* maxFrameSize */); + assert(!ZSTD_isError(initStatus)); + } + + { ZSTD_outBuffer outb = { .dst=seekBuffer, .pos=0, .size=seekCapacity }; + ZSTD_inBuffer inb = { .src=inBuffer, .pos=0, .size=inSize }; + + size_t const cStatus = ZSTD_seekable_compressStream(zscs, &outb, &inb); + assert(!ZSTD_isError(cStatus)); + assert(inb.pos == inb.size); + + size_t const endStatus = ZSTD_seekable_endStream(zscs, &outb); + assert(!ZSTD_isError(endStatus)); + seekSize = outb.pos; + } + + ZSTD_seekable* const stream = ZSTD_seekable_create(); + assert(stream != NULL); + { size_t const initStatus = ZSTD_seekable_initBuff(stream, seekBuffer, seekSize); + assert(!ZSTD_isError(initStatus)); } + + { size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, outCapacity, 0); + assert(decStatus == inSize); } + + /* unit test ZSTD_seekTable functions */ + ZSTD_seekTable* const zst = ZSTD_seekTable_create_fromSeekable(stream); + assert(zst != NULL); + + unsigned const nbFrames = ZSTD_seekTable_getNumFrames(zst); + assert(nbFrames > 0); + + unsigned long long const frame0Offset = ZSTD_seekTable_getFrameCompressedOffset(zst, 0); + assert(frame0Offset == 0); + + unsigned long long const content0Offset = ZSTD_seekTable_getFrameDecompressedOffset(zst, 0); + assert(content0Offset == 0); + + size_t const cSize = ZSTD_seekTable_getFrameCompressedSize(zst, 0); + assert(!ZSTD_isError(cSize)); + assert(cSize <= seekCapacity); + + size_t const origSize = ZSTD_seekTable_getFrameDecompressedSize(zst, 0); + assert(origSize == inSize); + + unsigned const fo1idx = ZSTD_seekTable_offsetToFrameIndex(zst, 1); + assert(fo1idx == 0); + + free(inBuffer); + free(seekBuffer); + free(outBuffer); + ZSTD_seekable_freeCStream(zscs); + ZSTD_seekTable_free(zst); + ZSTD_seekable_free(stream); + } + printf("Success!\n"); + + + printf("Test %u - check that seekable decompress does not hang: ", testNb++); + { /* Github issue #2335 */ + const size_t compressed_size = 17; + const uint8_t compressed_data[17] = { + '^', + '*', + 'M', + '\x18', + '\t', + '\x00', + '\x00', + '\x00', + '\x00', + '\x00', + '\x00', + '\x00', + (uint8_t)('\x03'), + (uint8_t)('\xb1'), + (uint8_t)('\xea'), + (uint8_t)('\x92'), + (uint8_t)('\x8f'), + }; + const size_t uncompressed_size = 32; + uint8_t uncompressed_data[32]; + + ZSTD_seekable* const stream = ZSTD_seekable_create(); + assert(stream != NULL); + { size_t const status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size); + if (ZSTD_isError(status)) { + ZSTD_seekable_free(stream); + goto _test_error; + } } + + /* Should return an error, but not hang */ + { const size_t offset = 2; + size_t const status = ZSTD_seekable_decompress(stream, uncompressed_data, uncompressed_size, offset); + if (!ZSTD_isError(status)) { + ZSTD_seekable_free(stream); + goto _test_error; + } } + + ZSTD_seekable_free(stream); + } + printf("Success!\n"); + + printf("Test %u - check #2 that seekable decompress does not hang: ", testNb++); + { /* Github issue #FIXME */ + const size_t compressed_size = 27; + const uint8_t compressed_data[27] = { + (uint8_t)'\x28', + (uint8_t)'\xb5', + (uint8_t)'\x2f', + (uint8_t)'\xfd', + (uint8_t)'\x00', + (uint8_t)'\x32', + (uint8_t)'\x91', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\x5e', + (uint8_t)'\x2a', + (uint8_t)'\x4d', + (uint8_t)'\x18', + (uint8_t)'\x09', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\x00', + (uint8_t)'\xb1', + (uint8_t)'\xea', + (uint8_t)'\x92', + (uint8_t)'\x8f', + }; + const size_t uncompressed_size = 400; + uint8_t uncompressed_data[400]; + + ZSTD_seekable* stream = ZSTD_seekable_create(); + size_t status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size); + if (ZSTD_isError(status)) { + ZSTD_seekable_free(stream); + goto _test_error; + } + + const size_t offset = 2; + /* Should return an error, but not hang */ + status = ZSTD_seekable_decompress(stream, uncompressed_data, uncompressed_size, offset); + if (!ZSTD_isError(status)) { + ZSTD_seekable_free(stream); + goto _test_error; + } + + ZSTD_seekable_free(stream); + } + printf("Success!\n"); + + + printf("Test %u - check ZSTD magic in compressing empty string: ", testNb++); + { // compressing empty string should return a zstd header + size_t const capacity = 255; + char* inBuffer = malloc(capacity); + assert(inBuffer != NULL); + inBuffer[0] = '\0'; + void* const outBuffer = malloc(capacity); + assert(outBuffer != NULL); + + ZSTD_seekable_CStream *s = ZSTD_seekable_createCStream(); + ZSTD_seekable_initCStream(s, 1, 1, 255); + + ZSTD_inBuffer input = { .src=inBuffer, .pos=0, .size=0 }; + ZSTD_outBuffer output = { .dst=outBuffer, .pos=0, .size=capacity }; + + ZSTD_seekable_compressStream(s, &output, &input); + ZSTD_seekable_endStream(s, &output); + + if((((char*)output.dst)[0] != '\x28') | (((char*)output.dst)[1] != '\xb5') | (((char*)output.dst)[2] != '\x2f') | (((char*)output.dst)[3] != '\xfd')) { + printf("%#02x %#02x %#02x %#02x\n", ((char*)output.dst)[0], ((char*)output.dst)[1] , ((char*)output.dst)[2] , ((char*)output.dst)[3] ); + + free(inBuffer); + free(outBuffer); + ZSTD_seekable_freeCStream(s); + goto _test_error; + } + + free(inBuffer); + free(outBuffer); + ZSTD_seekable_freeCStream(s); + } + printf("Success!\n"); + + + printf("Test %u - multiple decompress calls: ", testNb++); + { char const inBuffer[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt"; + size_t const inSize = sizeof(inBuffer); + + size_t const seekCapacity = 5000; + void* const seekBuffer = malloc(seekCapacity); + assert(seekBuffer != NULL); + size_t seekSize; + + size_t const outCapacity = inSize; + char* const outBuffer = malloc(outCapacity); + assert(outBuffer != NULL); + + ZSTD_seekable_CStream* const zscs = ZSTD_seekable_createCStream(); + assert(zscs != NULL); + + /* compress test data with a small frame size to ensure multiple frames in the output */ + unsigned const maxFrameSize = 40; + { size_t const initStatus = ZSTD_seekable_initCStream(zscs, 9, 0 /* checksumFlag */, maxFrameSize); + assert(!ZSTD_isError(initStatus)); + } + + { ZSTD_outBuffer outb = { .dst=seekBuffer, .pos=0, .size=seekCapacity }; + ZSTD_inBuffer inb = { .src=inBuffer, .pos=0, .size=inSize }; + + while (inb.pos < inb.size) { + size_t const cStatus = ZSTD_seekable_compressStream(zscs, &outb, &inb); + assert(!ZSTD_isError(cStatus)); + } + + size_t const endStatus = ZSTD_seekable_endStream(zscs, &outb); + assert(!ZSTD_isError(endStatus)); + seekSize = outb.pos; + } + + ZSTD_seekable* const stream = ZSTD_seekable_create(); + assert(stream != NULL); + buffWrapperWithTotal_t buffWrapper = {seekBuffer, seekSize, 0, 0}; + { ZSTD_seekable_customFile srcFile = {&buffWrapper, &readBuffWithTotal, &seekBuffWithTotal}; + size_t const initStatus = ZSTD_seekable_initAdvanced(stream, srcFile); + assert(!ZSTD_isError(initStatus)); } + + /* Perform a series of small reads and seeks (repeatedly read 1 byte and skip 1 byte) + and check that we didn't reread input data unnecessarily */ + size_t pos; + for (pos = 0; pos < inSize; pos += 2) { + size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, 1, pos); + if (decStatus != 1 || outBuffer[0] != inBuffer[pos]) { + goto _test_error; + } + } + if (buffWrapper.totalRead > seekSize) { + /* We read more than the compressed size, meaning there were some rereads. + This is unneeded because we only seeked forward. */ + printf("Too much data read: %zu read, with compressed size %zu\n", buffWrapper.totalRead, seekSize); + goto _test_error; + } + + /* Perform some reads and seeks to ensure correctness */ + struct { + size_t offset; + size_t size; + } const tests[] = { /* Assume the frame size is 40 */ + {20, 40}, /* read partial data from two frames */ + {60, 10}, /* continue reading from the same offset */ + {50, 20}, /* seek backward within the same frame */ + {10, 10}, /* seek backward to a different frame */ + {25, 10}, /* seek forward within the same frame */ + {60, 10}, /* seek forward to a different frame */ + }; + size_t idx; + for (idx = 0; idx < sizeof(tests) / sizeof(tests[0]); idx++) { + size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, tests[idx].size, tests[idx].offset); + if (decStatus != tests[idx].size || memcmp(outBuffer, inBuffer + tests[idx].offset, tests[idx].size) != 0) { + goto _test_error; + } + } + + free(seekBuffer); + free(outBuffer); + ZSTD_seekable_freeCStream(zscs); + ZSTD_seekable_free(stream); + } + printf("Success!\n"); + + /* TODO: Add more tests */ + printf("Finished tests\n"); + return 0; + +_test_error: + printf("test failed! Exiting..\n"); + return 1; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstd_seekable.h b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstd_seekable.h new file mode 100644 index 000000000..b1f83d0e0 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstd_seekable.h @@ -0,0 +1,226 @@ +#ifndef SEEKABLE_H +#define SEEKABLE_H + +#include +#include "zstd.h" /* ZSTDLIB_API */ + +#if defined (__cplusplus) +extern "C" { +#endif + + +#define ZSTD_seekTableFooterSize 9 + +#define ZSTD_SEEKABLE_MAGICNUMBER 0x8F92EAB1 + +#define ZSTD_SEEKABLE_MAXFRAMES 0x8000000U + +/* Limit maximum size to avoid potential issues storing the compressed size */ +#define ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE 0x40000000U + +/*-**************************************************************************** +* Seekable Format +* +* The seekable format splits the compressed data into a series of "frames", +* each compressed individually so that decompression of a section in the +* middle of an archive only requires zstd to decompress at most a frame's +* worth of extra data, instead of the entire archive. +******************************************************************************/ + +typedef struct ZSTD_seekable_CStream_s ZSTD_seekable_CStream; +typedef struct ZSTD_seekable_s ZSTD_seekable; +typedef struct ZSTD_seekTable_s ZSTD_seekTable; + +/*-**************************************************************************** +* Seekable compression - HowTo +* A ZSTD_seekable_CStream object is required to tracking streaming operation. +* Use ZSTD_seekable_createCStream() and ZSTD_seekable_freeCStream() to create/ +* release resources. +* +* Streaming objects are reusable to avoid allocation and deallocation, +* to start a new compression operation call ZSTD_seekable_initCStream() on the +* compressor. +* +* Data streamed to the seekable compressor will automatically be split into +* frames of size `maxFrameSize` (provided in ZSTD_seekable_initCStream()), +* or if none is provided, will be cut off whenever ZSTD_seekable_endFrame() is +* called or when the default maximum frame size (2GB) is reached. +* +* Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object +* for a new compression operation. +* - `maxFrameSize` indicates the size at which to automatically start a new +* seekable frame. +* `maxFrameSize == 0` implies the default maximum size. +* Smaller frame sizes allow faster decompression of small segments, +* since retrieving a single byte requires decompression of +* the full frame where the byte belongs. +* In general, size the frames to roughly correspond to +* the access granularity (when it's known). +* But small sizes also reduce compression ratio. +* Avoid really tiny frame sizes (< 1 KB), +* that would hurt compression ratio considerably. +* - `checksumFlag` indicates whether or not the seek table should include frame +* checksums on the uncompressed data for verification. +* @return : a size hint for input to provide for compression, or an error code +* checkable with ZSTD_isError() +* +* Use ZSTD_seekable_compressStream() repetitively to consume input stream. +* The function will automatically update both `pos` fields. +* Note that it may not consume the entire input, in which case `pos < size`, +* and it's up to the caller to present again remaining data. +* @return : a size hint, preferred nb of bytes to use as input for next +* function call or an error code, which can be tested using +* ZSTD_isError(). +* Note 1 : it's just a hint, to help latency a little, any other +* value will work fine. +* +* At any time, call ZSTD_seekable_endFrame() to end the current frame and +* start a new one. +* +* ZSTD_seekable_endStream() will end the current frame, and then write the seek +* table so that decompressors can efficiently find compressed frames. +* ZSTD_seekable_endStream() may return a number > 0 if it was unable to flush +* all the necessary data to `output`. In this case, it should be called again +* until all remaining data is flushed out and 0 is returned. +******************************************************************************/ + +/*===== Seekable compressor management =====*/ +ZSTDLIB_API ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void); +ZSTDLIB_API size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs); + +/*===== Seekable compression functions =====*/ +ZSTDLIB_API size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, unsigned maxFrameSize); +ZSTDLIB_API size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); +ZSTDLIB_API size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); +ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); + +/*= Raw seek table API + * These functions allow for the seek table to be constructed directly. + * This table can then be appended to a file of concatenated frames. + * This allows the frames to be compressed independently, even in parallel, + * and compiled together afterward into a seekable archive. + * + * Use ZSTD_seekable_createFrameLog() to allocate and initialize a tracking + * structure. + * + * Call ZSTD_seekable_logFrame() once for each frame in the archive. + * checksum is optional, and will not be used if checksumFlag was 0 when the + * frame log was created. If present, it should be the least significant 32 + * bits of the XXH64 hash of the uncompressed data. + * + * Call ZSTD_seekable_writeSeekTable to serialize the data into a seek table. + * If the entire table was written, the return value will be 0. Otherwise, + * it will be equal to the number of bytes left to write. */ +typedef struct ZSTD_frameLog_s ZSTD_frameLog; +ZSTDLIB_API ZSTD_frameLog* ZSTD_seekable_createFrameLog(int checksumFlag); +ZSTDLIB_API size_t ZSTD_seekable_freeFrameLog(ZSTD_frameLog* fl); +ZSTDLIB_API size_t ZSTD_seekable_logFrame(ZSTD_frameLog* fl, unsigned compressedSize, unsigned decompressedSize, unsigned checksum); +ZSTDLIB_API size_t ZSTD_seekable_writeSeekTable(ZSTD_frameLog* fl, ZSTD_outBuffer* output); + + +/*-**************************************************************************** +* Seekable decompression - HowTo +* A ZSTD_seekable object is required to tracking the seekTable. +* +* Call ZSTD_seekable_init* to initialize a ZSTD_seekable object with the +* the seek table provided in the input. +* There are three modes for ZSTD_seekable_init: +* - ZSTD_seekable_initBuff() : An in-memory API. The data contained in +* `src` should be the entire seekable file, including the seek table. +* `src` should be kept alive and unmodified until the ZSTD_seekable object +* is freed or reset. +* - ZSTD_seekable_initFile() : A simplified file API using stdio. fread and +* fseek will be used to access the required data for building the seek +* table and doing decompression operations. `src` should not be closed +* or modified until the ZSTD_seekable object is freed or reset. +* - ZSTD_seekable_initAdvanced() : A general API allowing the client to +* provide its own read and seek callbacks. +* + ZSTD_seekable_read() : read exactly `n` bytes into `buffer`. +* Premature EOF should be treated as an error. +* + ZSTD_seekable_seek() : seek the read head to `offset` from `origin`, +* where origin is either SEEK_SET (beginning of +* file), or SEEK_END (end of file). +* Both functions should return a non-negative value in case of success, and a +* negative value in case of failure. If implementing using this API and +* stdio, be careful with files larger than 4GB and fseek. All of these +* functions return an error code checkable with ZSTD_isError(). +* +* Call ZSTD_seekable_decompress to decompress `dstSize` bytes at decompressed +* offset `offset`. ZSTD_seekable_decompress may have to decompress the entire +* prefix of the frame before the desired data if it has not already processed +* this section. If ZSTD_seekable_decompress is called multiple times for a +* consecutive range of data, it will efficiently retain the decompressor object +* and avoid redecompressing frame prefixes. The return value is the number of +* bytes decompressed, or an error code checkable with ZSTD_isError(). +* +* The seek table access functions can be used to obtain the data contained +* in the seek table. If frameIndex is larger than the value returned by +* ZSTD_seekable_getNumFrames(), they will return error codes checkable with +* ZSTD_isError(). Note that since the offset access functions return +* unsigned long long instead of size_t, in this case they will instead return +* the value ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE. +******************************************************************************/ + +/*===== Seekable decompressor management =====*/ +ZSTDLIB_API ZSTD_seekable* ZSTD_seekable_create(void); +ZSTDLIB_API size_t ZSTD_seekable_free(ZSTD_seekable* zs); + +/*===== Seekable decompression functions =====*/ +ZSTDLIB_API size_t ZSTD_seekable_initBuff(ZSTD_seekable* zs, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_seekable_initFile(ZSTD_seekable* zs, FILE* src); +ZSTDLIB_API size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t dstSize, unsigned long long offset); +ZSTDLIB_API size_t ZSTD_seekable_decompressFrame(ZSTD_seekable* zs, void* dst, size_t dstSize, unsigned frameIndex); + +#define ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE (0ULL-2) +/*===== Seekable seek table access functions =====*/ +ZSTDLIB_API unsigned ZSTD_seekable_getNumFrames(const ZSTD_seekable* zs); +ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameCompressedOffset(const ZSTD_seekable* zs, unsigned frameIndex); +ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameDecompressedOffset(const ZSTD_seekable* zs, unsigned frameIndex); +ZSTDLIB_API size_t ZSTD_seekable_getFrameCompressedSize(const ZSTD_seekable* zs, unsigned frameIndex); +ZSTDLIB_API size_t ZSTD_seekable_getFrameDecompressedSize(const ZSTD_seekable* zs, unsigned frameIndex); +ZSTDLIB_API unsigned ZSTD_seekable_offsetToFrameIndex(const ZSTD_seekable* zs, unsigned long long offset); + + +/*-**************************************************************************** +* Direct exploitation of the seekTable +* +* Memory constrained use cases that manage multiple archives +* benefit from retaining multiple archive seek tables +* without retaining a ZSTD_seekable instance for each. +* +* Below API allow the above-mentioned use cases +* to initialize a ZSTD_seekable, extract its (smaller) ZSTD_seekTable, +* then throw the ZSTD_seekable away to save memory. +* +* Standard ZSTD operations can then be used +* to decompress frames based on seek table offsets. +******************************************************************************/ + +/*===== Independent seek table management =====*/ +ZSTDLIB_API ZSTD_seekTable* ZSTD_seekTable_create_fromSeekable(const ZSTD_seekable* zs); +ZSTDLIB_API size_t ZSTD_seekTable_free(ZSTD_seekTable* st); + +/*===== Direct seek table access functions =====*/ +ZSTDLIB_API unsigned ZSTD_seekTable_getNumFrames(const ZSTD_seekTable* st); +ZSTDLIB_API unsigned long long ZSTD_seekTable_getFrameCompressedOffset(const ZSTD_seekTable* st, unsigned frameIndex); +ZSTDLIB_API unsigned long long ZSTD_seekTable_getFrameDecompressedOffset(const ZSTD_seekTable* st, unsigned frameIndex); +ZSTDLIB_API size_t ZSTD_seekTable_getFrameCompressedSize(const ZSTD_seekTable* st, unsigned frameIndex); +ZSTDLIB_API size_t ZSTD_seekTable_getFrameDecompressedSize(const ZSTD_seekTable* st, unsigned frameIndex); +ZSTDLIB_API unsigned ZSTD_seekTable_offsetToFrameIndex(const ZSTD_seekTable* st, unsigned long long offset); + + +/*===== Seekable advanced I/O API =====*/ +typedef int(ZSTD_seekable_read)(void* opaque, void* buffer, size_t n); +typedef int(ZSTD_seekable_seek)(void* opaque, long long offset, int origin); +typedef struct { + void* opaque; + ZSTD_seekable_read* read; + ZSTD_seekable_seek* seek; +} ZSTD_seekable_customFile; +ZSTDLIB_API size_t ZSTD_seekable_initAdvanced(ZSTD_seekable* zs, ZSTD_seekable_customFile src); + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstd_seekable_compression_format.md b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstd_seekable_compression_format.md new file mode 100644 index 000000000..7bd0790e8 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstd_seekable_compression_format.md @@ -0,0 +1,116 @@ +# Zstandard Seekable Format + +### Notices + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is granted to copy and distribute this document +for any purpose and without charge, +including translations into other languages +and incorporation into compilations, +provided that the copyright notice and this notice are preserved, +and that any substantive changes or deletions from the original +are clearly marked. +Distribution of this document is unlimited. + +### Version +0.1.0 (11/04/17) + +## Introduction +This document defines a format for compressed data to be stored so that subranges of the data can be efficiently decompressed without requiring the entire document to be decompressed. +This is done by splitting up the input data into frames, +each of which are compressed independently, +and so can be decompressed independently. +Decompression then takes advantage of a provided 'seek table', which allows the decompressor to immediately jump to the desired data. This is done in a way that is compatible with the original Zstandard format by placing the seek table in a Zstandard skippable frame. + +### Overall conventions +In this document: +- square brackets i.e. `[` and `]` are used to indicate optional fields or parameters. +- the naming convention for identifiers is `Mixed_Case_With_Underscores` +- All numeric fields are little-endian unless specified otherwise + +## Format + +The format consists of a number of frames (Zstandard compressed frames and skippable frames), followed by a final skippable frame at the end containing the seek table. + +### Seek Table Format +The structure of the seek table frame is as follows: + +|`Skippable_Magic_Number`|`Frame_Size`|`[Seek_Table_Entries]`|`Seek_Table_Footer`| +|------------------------|------------|----------------------|-------------------| +| 4 bytes | 4 bytes | 8-12 bytes each | 9 bytes | + +__`Skippable_Magic_Number`__ + +Value : 0x184D2A5E. +This is for compatibility with [Zstandard skippable frames]. +Since it is legal for other Zstandard skippable frames to use the same +magic number, it is not recommended for a decoder to recognize frames +solely on this. + +__`Frame_Size`__ + +The total size of the skippable frame, not including the `Skippable_Magic_Number` or `Frame_Size`. +This is for compatibility with [Zstandard skippable frames]. + +[Zstandard skippable frames]: https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#skippable-frames + +#### `Seek_Table_Footer` +The seek table footer format is as follows: + +|`Number_Of_Frames`|`Seek_Table_Descriptor`|`Seekable_Magic_Number`| +|------------------|-----------------------|-----------------------| +| 4 bytes | 1 byte | 4 bytes | + +__`Seekable_Magic_Number`__ + +Value : 0x8F92EAB1. +This value must be the last bytes present in the compressed file so that decoders +can efficiently find it and determine if there is an actual seek table present. + +__`Number_Of_Frames`__ + +The number of stored frames in the data. + +__`Seek_Table_Descriptor`__ + +A bitfield describing the format of the seek table. + +| Bit number | Field name | +| ---------- | ---------- | +| 7 | `Checksum_Flag` | +| 6-2 | `Reserved_Bits` | +| 1-0 | `Unused_Bits` | + +While only `Checksum_Flag` currently exists, there are 7 other bits in this field that can be used for future changes to the format, +for example the addition of inline dictionaries. + +__`Checksum_Flag`__ + +If the checksum flag is set, each of the seek table entries contains a 4 byte checksum of the uncompressed data contained in its frame. + +`Reserved_Bits` are not currently used but may be used in the future for breaking changes, so a compliant decoder should ensure they are set to 0. `Unused_Bits` may be used in the future for non-breaking changes, so a compliant decoder should not interpret these bits. + +#### __`Seek_Table_Entries`__ + +`Seek_Table_Entries` consists of `Number_Of_Frames` (one for each frame in the data, not including the seek table frame) entries of the following form, in sequence: + +|`Compressed_Size`|`Decompressed_Size`|`[Checksum]`| +|-----------------|-------------------|------------| +| 4 bytes | 4 bytes | 4 bytes | + +__`Compressed_Size`__ + +The compressed size of the frame. +The cumulative sum of the `Compressed_Size` fields of frames `0` to `i` gives the offset in the compressed file of frame `i+1`. + +__`Decompressed_Size`__ + +The size of the decompressed data contained in the frame. For skippable or otherwise empty frames, this value is 0. + +__`Checksum`__ + +Only present if `Checksum_Flag` is set in the `Seek_Table_Descriptor`. Value : the least significant 32 bits of the XXH64 digest of the uncompressed data, stored in little-endian format. + +## Version Changes +- 0.1.0: initial version diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstdseek_compress.c b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstdseek_compress.c new file mode 100644 index 000000000..4997807d2 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstdseek_compress.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + */ + +#include /* malloc, free */ +#include /* UINT_MAX */ +#include + +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "zstd_errors.h" +#include "mem.h" + +#include "zstd_seekable.h" + +#define CHECK_Z(f) { size_t const ret = (f); if (ret != 0) return ret; } + +#undef ERROR +#define ERROR(name) ((size_t)-ZSTD_error_##name) + +#undef MIN +#undef MAX +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +typedef struct { + U32 cSize; + U32 dSize; + U32 checksum; +} framelogEntry_t; + +struct ZSTD_frameLog_s { + framelogEntry_t* entries; + U32 size; + U32 capacity; + + int checksumFlag; + + /* for use when streaming out the seek table */ + U32 seekTablePos; + U32 seekTableIndex; +} framelog_t; + +struct ZSTD_seekable_CStream_s { + ZSTD_CStream* cstream; + ZSTD_frameLog framelog; + + U32 frameCSize; + U32 frameDSize; + + XXH64_state_t xxhState; + + U32 maxFrameSize; + + int writingSeekTable; +}; + +static size_t ZSTD_seekable_frameLog_allocVec(ZSTD_frameLog* fl) +{ + /* allocate some initial space */ + size_t const FRAMELOG_STARTING_CAPACITY = 16; + fl->entries = (framelogEntry_t*)malloc( + sizeof(framelogEntry_t) * FRAMELOG_STARTING_CAPACITY); + if (fl->entries == NULL) return ERROR(memory_allocation); + fl->capacity = (U32)FRAMELOG_STARTING_CAPACITY; + return 0; +} + +static size_t ZSTD_seekable_frameLog_freeVec(ZSTD_frameLog* fl) +{ + if (fl != NULL) free(fl->entries); + return 0; +} + +ZSTD_frameLog* ZSTD_seekable_createFrameLog(int checksumFlag) +{ + ZSTD_frameLog* const fl = (ZSTD_frameLog*)malloc(sizeof(ZSTD_frameLog)); + if (fl == NULL) return NULL; + + if (ZSTD_isError(ZSTD_seekable_frameLog_allocVec(fl))) { + free(fl); + return NULL; + } + + fl->checksumFlag = checksumFlag; + fl->seekTablePos = 0; + fl->seekTableIndex = 0; + fl->size = 0; + + return fl; +} + +size_t ZSTD_seekable_freeFrameLog(ZSTD_frameLog* fl) +{ + ZSTD_seekable_frameLog_freeVec(fl); + free(fl); + return 0; +} + +ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void) +{ + ZSTD_seekable_CStream* const zcs = (ZSTD_seekable_CStream*)malloc(sizeof(ZSTD_seekable_CStream)); + if (zcs == NULL) return NULL; + + memset(zcs, 0, sizeof(*zcs)); + + zcs->cstream = ZSTD_createCStream(); + if (zcs->cstream == NULL) goto failed1; + + if (ZSTD_isError(ZSTD_seekable_frameLog_allocVec(&zcs->framelog))) goto failed2; + + return zcs; + +failed2: + ZSTD_freeCStream(zcs->cstream); +failed1: + free(zcs); + return NULL; +} + +size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs) +{ + if (zcs == NULL) return 0; /* support free on null */ + ZSTD_freeCStream(zcs->cstream); + ZSTD_seekable_frameLog_freeVec(&zcs->framelog); + free(zcs); + return 0; +} + +size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, + int compressionLevel, + int checksumFlag, + unsigned maxFrameSize) +{ + zcs->framelog.size = 0; + zcs->frameCSize = 0; + zcs->frameDSize = 0; + + /* make sure maxFrameSize has a reasonable value */ + if (maxFrameSize > ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE) { + return ERROR(frameParameter_unsupported); + } + + zcs->maxFrameSize = maxFrameSize ? + maxFrameSize : ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE; + + zcs->framelog.checksumFlag = checksumFlag; + if (zcs->framelog.checksumFlag) { + XXH64_reset(&zcs->xxhState, 0); + } + + zcs->framelog.seekTablePos = 0; + zcs->framelog.seekTableIndex = 0; + zcs->writingSeekTable = 0; + + return ZSTD_initCStream(zcs->cstream, compressionLevel); +} + +size_t ZSTD_seekable_logFrame(ZSTD_frameLog* fl, + unsigned compressedSize, + unsigned decompressedSize, + unsigned checksum) +{ + if (fl->size == ZSTD_SEEKABLE_MAXFRAMES) + return ERROR(frameIndex_tooLarge); + + /* grow the buffer if required */ + if (fl->size == fl->capacity) { + /* exponential size increase for constant amortized runtime */ + size_t const newCapacity = fl->capacity * 2; + framelogEntry_t* const newEntries = (framelogEntry_t*)realloc(fl->entries, + sizeof(framelogEntry_t) * newCapacity); + + if (newEntries == NULL) return ERROR(memory_allocation); + + fl->entries = newEntries; + assert(newCapacity <= UINT_MAX); + fl->capacity = (U32)newCapacity; + } + + fl->entries[fl->size] = (framelogEntry_t){ + compressedSize, decompressedSize, checksum + }; + fl->size++; + + return 0; +} + +size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) +{ + size_t const prevOutPos = output->pos; + /* end the frame */ + size_t ret = ZSTD_endStream(zcs->cstream, output); + + zcs->frameCSize += (U32)(output->pos - prevOutPos); + + /* need to flush before doing the rest */ + if (ret) return ret; + + /* frame done */ + + /* store the frame data for later */ + ret = ZSTD_seekable_logFrame( + &zcs->framelog, zcs->frameCSize, zcs->frameDSize, + zcs->framelog.checksumFlag + ? XXH64_digest(&zcs->xxhState) & 0xFFFFFFFFU + : 0); + if (ret) return ret; + + /* reset for the next frame */ + zcs->frameCSize = 0; + zcs->frameDSize = 0; + + ZSTD_CCtx_reset(zcs->cstream, ZSTD_reset_session_only); + if (zcs->framelog.checksumFlag) XXH64_reset(&zcs->xxhState, 0); + + return 0; +} + +size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + const BYTE* const inBase = (const BYTE*) input->src + input->pos; + size_t inLen = input->size - input->pos; + + assert(zcs->maxFrameSize < INT_MAX); + ZSTD_CCtx_setParameter(zcs->cstream, ZSTD_c_srcSizeHint, (int)zcs->maxFrameSize); + inLen = MIN(inLen, (size_t)(zcs->maxFrameSize - zcs->frameDSize)); + + /* if we haven't finished flushing the last frame, don't start writing a new one */ + if (inLen > 0) { + ZSTD_inBuffer inTmp = { inBase, inLen, 0 }; + size_t const prevOutPos = output->pos; + + size_t const ret = ZSTD_compressStream(zcs->cstream, output, &inTmp); + + if (zcs->framelog.checksumFlag) { + XXH64_update(&zcs->xxhState, inBase, inTmp.pos); + } + + zcs->frameCSize += (U32)(output->pos - prevOutPos); + zcs->frameDSize += (U32)inTmp.pos; + + input->pos += inTmp.pos; + + if (ZSTD_isError(ret)) return ret; + } + + if (zcs->maxFrameSize == zcs->frameDSize) { + /* log the frame and start over */ + size_t const ret = ZSTD_seekable_endFrame(zcs, output); + if (ZSTD_isError(ret)) return ret; + + /* get the client ready for the next frame */ + return (size_t)zcs->maxFrameSize; + } + + return (size_t)(zcs->maxFrameSize - zcs->frameDSize); +} + +static inline size_t ZSTD_seekable_seekTableSize(const ZSTD_frameLog* fl) +{ + size_t const sizePerFrame = 8 + (fl->checksumFlag?4:0); + size_t const seekTableLen = ZSTD_SKIPPABLEHEADERSIZE + + sizePerFrame * fl->size + + ZSTD_seekTableFooterSize; + + return seekTableLen; +} + +static inline size_t ZSTD_stwrite32(ZSTD_frameLog* fl, + ZSTD_outBuffer* output, U32 const value, + U32 const offset) +{ + if (fl->seekTablePos < offset + 4) { + BYTE tmp[4]; /* so that we can work with buffers too small to write a whole word to */ + size_t const lenWrite = + MIN(output->size - output->pos, offset + 4 - fl->seekTablePos); + MEM_writeLE32(tmp, value); + memcpy((BYTE*)output->dst + output->pos, + tmp + (fl->seekTablePos - offset), lenWrite); + output->pos += lenWrite; + fl->seekTablePos += (U32)lenWrite; + + if (lenWrite < 4) return ZSTD_seekable_seekTableSize(fl) - fl->seekTablePos; + } + return 0; +} + +size_t ZSTD_seekable_writeSeekTable(ZSTD_frameLog* fl, ZSTD_outBuffer* output) +{ + /* seekTableIndex: the current index in the table and + * seekTableSize: the amount of the table written so far + * + * This function is written this way so that if it has to return early + * because of a small buffer, it can keep going where it left off. + */ + + size_t const sizePerFrame = 8 + (fl->checksumFlag?4:0); + size_t const seekTableLen = ZSTD_seekable_seekTableSize(fl); + + CHECK_Z(ZSTD_stwrite32(fl, output, ZSTD_MAGIC_SKIPPABLE_START | 0xE, 0)); + assert(seekTableLen <= (size_t)UINT_MAX); + CHECK_Z(ZSTD_stwrite32(fl, output, (U32)seekTableLen - ZSTD_SKIPPABLEHEADERSIZE, 4)); + + while (fl->seekTableIndex < fl->size) { + unsigned long long const start = ZSTD_SKIPPABLEHEADERSIZE + sizePerFrame * fl->seekTableIndex; + assert(start + 8 <= UINT_MAX); + CHECK_Z(ZSTD_stwrite32(fl, output, + fl->entries[fl->seekTableIndex].cSize, + (U32)start + 0)); + + CHECK_Z(ZSTD_stwrite32(fl, output, + fl->entries[fl->seekTableIndex].dSize, + (U32)start + 4)); + + if (fl->checksumFlag) { + CHECK_Z(ZSTD_stwrite32( + fl, output, fl->entries[fl->seekTableIndex].checksum, + (U32)start + 8)); + } + + fl->seekTableIndex++; + } + + assert(seekTableLen <= UINT_MAX); + CHECK_Z(ZSTD_stwrite32(fl, output, fl->size, + (U32)seekTableLen - ZSTD_seekTableFooterSize)); + + if (output->size - output->pos < 1) return seekTableLen - fl->seekTablePos; + if (fl->seekTablePos < seekTableLen - 4) { + BYTE const sfd = (BYTE)((fl->checksumFlag) << 7); + + ((BYTE*)output->dst)[output->pos] = sfd; + output->pos++; + fl->seekTablePos++; + } + + CHECK_Z(ZSTD_stwrite32(fl, output, ZSTD_SEEKABLE_MAGICNUMBER, + (U32)seekTableLen - 4)); + + if (fl->seekTablePos != seekTableLen) return ERROR(GENERIC); + return 0; +} + +size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) +{ + if (!zcs->writingSeekTable) { + const size_t endFrame = ZSTD_seekable_endFrame(zcs, output); + if (ZSTD_isError(endFrame)) return endFrame; + /* return an accurate size hint */ + if (endFrame) return endFrame + ZSTD_seekable_seekTableSize(&zcs->framelog); + } + + zcs->writingSeekTable = 1; + + return ZSTD_seekable_writeSeekTable(&zcs->framelog, output); +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstdseek_decompress.c b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstdseek_decompress.c new file mode 100644 index 000000000..ab9088a10 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seekable_format/zstdseek_decompress.c @@ -0,0 +1,600 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* ********************************************************* +* Turn on Large Files support (>4GB) for 32-bit Linux/Unix +***********************************************************/ +#if !defined(__64BIT__) || defined(__MINGW32__) /* No point defining Large file for 64 bit but MinGW-w64 requires it */ +# if !defined(_FILE_OFFSET_BITS) +# define _FILE_OFFSET_BITS 64 /* turn off_t into a 64-bit type for ftello, fseeko */ +# endif +# if !defined(_LARGEFILE_SOURCE) /* obsolete macro, replaced with _FILE_OFFSET_BITS */ +# define _LARGEFILE_SOURCE 1 /* Large File Support extension (LFS) - fseeko, ftello */ +# endif +# if defined(_AIX) || defined(__hpux) +# define _LARGE_FILES /* Large file support on 32-bits AIX and HP-UX */ +# endif +#endif + +/* ************************************************************ +* Detect POSIX version +* PLATFORM_POSIX_VERSION = 0 for non-Unix e.g. Windows +* PLATFORM_POSIX_VERSION = 1 for Unix-like but non-POSIX +* PLATFORM_POSIX_VERSION > 1 is equal to found _POSIX_VERSION +* Value of PLATFORM_POSIX_VERSION can be forced on command line +***************************************************************/ +#ifndef PLATFORM_POSIX_VERSION + +# if (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) /* POSIX.1-2001 (SUSv3) conformant */ \ + || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* BSD distros */ + /* exception rule : force posix version to 200112L, + * note: it's better to use unistd.h's _POSIX_VERSION whenever possible */ +# define PLATFORM_POSIX_VERSION 200112L + +/* try to determine posix version through official unistd.h's _POSIX_VERSION (https://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html). + * note : there is no simple way to know in advance if is present or not on target system, + * Posix specification mandates its presence and its content, but target system must respect this spec. + * It's necessary to _not_ #include whenever target OS is not unix-like + * otherwise it will block preprocessing stage. + * The following list of build macros tries to "guess" if target OS is likely unix-like, and therefore can #include + */ +# elif !defined(_WIN32) \ + && ( defined(__unix__) || defined(__unix) \ + || defined(__midipix__) || defined(__VMS) || defined(__HAIKU__) ) + +# if defined(__linux__) || defined(__linux) || defined(__CYGWIN__) +# ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 200809L /* feature test macro : https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html */ +# endif +# endif +# include /* declares _POSIX_VERSION */ +# if defined(_POSIX_VERSION) /* POSIX compliant */ +# define PLATFORM_POSIX_VERSION _POSIX_VERSION +# else +# define PLATFORM_POSIX_VERSION 1 +# endif + +# ifdef __UCLIBC__ +# ifndef __USE_MISC +# define __USE_MISC /* enable st_mtim on uclibc */ +# endif +# endif + +# else /* non-unix target platform (like Windows) */ +# define PLATFORM_POSIX_VERSION 0 +# endif + +#endif /* PLATFORM_POSIX_VERSION */ + + +/* ************************************************************ +* Avoid fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW +***************************************************************/ +#if defined(LIBC_NO_FSEEKO) +/* Some older libc implementations don't include these functions (e.g. Bionic < 24) */ +# define LONG_SEEK fseek +#elif defined(_MSC_VER) && _MSC_VER >= 1400 +# define LONG_SEEK _fseeki64 +#elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */ +# define LONG_SEEK fseeko +#elif defined(__MINGW32__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS) && defined(__MSVCRT__) +# define LONG_SEEK fseeko64 +#elif defined(_WIN32) && !defined(__DJGPP__) +# include + static int LONG_SEEK(FILE* file, __int64 offset, int origin) { + LARGE_INTEGER off; + DWORD method; + off.QuadPart = offset; + if (origin == SEEK_END) + method = FILE_END; + else if (origin == SEEK_CUR) + method = FILE_CURRENT; + else + method = FILE_BEGIN; + + if (SetFilePointerEx((HANDLE) _get_osfhandle(_fileno(file)), off, NULL, method)) + return 0; + else + return -1; + } +#else +# define LONG_SEEK fseek +#endif + +#include /* malloc, free */ +#include /* FILE* */ +#include /* UNIT_MAX */ +#include + +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "zstd_errors.h" +#include "mem.h" +#include "zstd_seekable.h" + +#undef ERROR +#define ERROR(name) ((size_t)-ZSTD_error_##name) + +#define CHECK_IO(f) { int const errcod = (f); if (errcod < 0) return ERROR(seekableIO); } + +#undef MIN +#undef MAX +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define ZSTD_SEEKABLE_NO_OUTPUT_PROGRESS_MAX 16 + +/* Special-case callbacks for FILE* and in-memory modes, so that we can treat + * them the same way as the advanced API */ +static int ZSTD_seekable_read_FILE(void* opaque, void* buffer, size_t n) +{ + size_t const result = fread(buffer, 1, n, (FILE*)opaque); + if (result != n) { + return -1; + } + return 0; +} + +static int ZSTD_seekable_seek_FILE(void* opaque, long long offset, int origin) +{ + int const ret = LONG_SEEK((FILE*)opaque, offset, origin); + if (ret) return ret; + return fflush((FILE*)opaque); +} + +typedef struct { + const void *ptr; + size_t size; + size_t pos; +} buffWrapper_t; + +static int ZSTD_seekable_read_buff(void* opaque, void* buffer, size_t n) +{ + buffWrapper_t* const buff = (buffWrapper_t*)opaque; + assert(buff != NULL); + if (buff->pos + n > buff->size) return -1; + memcpy(buffer, (const BYTE*)buff->ptr + buff->pos, n); + buff->pos += n; + return 0; +} + +static int ZSTD_seekable_seek_buff(void* opaque, long long offset, int origin) +{ + buffWrapper_t* const buff = (buffWrapper_t*) opaque; + unsigned long long newOffset; + assert(buff != NULL); + switch (origin) { + case SEEK_SET: + assert(offset >= 0); + newOffset = (unsigned long long)offset; + break; + case SEEK_CUR: + newOffset = (unsigned long long)((long long)buff->pos + offset); + break; + case SEEK_END: + newOffset = (unsigned long long)((long long)buff->size + offset); + break; + default: + assert(0); /* not possible */ + } + if (newOffset > buff->size) { + return -1; + } + buff->pos = newOffset; + return 0; +} + +typedef struct { + U64 cOffset; + U64 dOffset; + U32 checksum; +} seekEntry_t; + +struct ZSTD_seekTable_s { + seekEntry_t* entries; + size_t tableLen; + + int checksumFlag; +}; + +#define SEEKABLE_BUFF_SIZE ZSTD_BLOCKSIZE_MAX + +struct ZSTD_seekable_s { + ZSTD_DStream* dstream; + ZSTD_seekTable seekTable; + ZSTD_seekable_customFile src; + + U64 decompressedOffset; + U32 curFrame; + + BYTE inBuff[SEEKABLE_BUFF_SIZE]; /* need to do our own input buffering */ + BYTE outBuff[SEEKABLE_BUFF_SIZE]; /* so we can efficiently decompress the + starts of chunks before we get to the + desired section */ + ZSTD_inBuffer in; /* maintain continuity across ZSTD_seekable_decompress operations */ + buffWrapper_t buffWrapper; /* for `src.opaque` in in-memory mode */ + + XXH64_state_t xxhState; +}; + +ZSTD_seekable* ZSTD_seekable_create(void) +{ + ZSTD_seekable* const zs = (ZSTD_seekable*)malloc(sizeof(ZSTD_seekable)); + if (zs == NULL) return NULL; + + /* also initializes stage to zsds_init */ + memset(zs, 0, sizeof(*zs)); + + zs->dstream = ZSTD_createDStream(); + if (zs->dstream == NULL) { + free(zs); + return NULL; + } + + return zs; +} + +size_t ZSTD_seekable_free(ZSTD_seekable* zs) +{ + if (zs == NULL) return 0; /* support free on null */ + ZSTD_freeDStream(zs->dstream); + free(zs->seekTable.entries); + free(zs); + return 0; +} + +ZSTD_seekTable* ZSTD_seekTable_create_fromSeekable(const ZSTD_seekable* zs) +{ + assert(zs != NULL); + if (zs->seekTable.entries == NULL) return NULL; + ZSTD_seekTable* const st = (ZSTD_seekTable*)malloc(sizeof(ZSTD_seekTable)); + if (st==NULL) return NULL; + + st->checksumFlag = zs->seekTable.checksumFlag; + st->tableLen = zs->seekTable.tableLen; + + /* Allocate an extra entry at the end to match logic of initial allocation */ + size_t const entriesSize = sizeof(seekEntry_t) * (zs->seekTable.tableLen + 1); + seekEntry_t* const entries = (seekEntry_t*)malloc(entriesSize); + if (entries==NULL) { + free(st); + return NULL; + } + + memcpy(entries, zs->seekTable.entries, entriesSize); + st->entries = entries; + return st; +} + +size_t ZSTD_seekTable_free(ZSTD_seekTable* st) +{ + if (st == NULL) return 0; /* support free on null */ + free(st->entries); + free(st); + return 0; +} + +/** ZSTD_seekable_offsetToFrameIndex() : + * Performs a binary search to find the last frame with a decompressed offset + * <= pos + * @return : the frame's index */ +unsigned ZSTD_seekable_offsetToFrameIndex(const ZSTD_seekable* zs, unsigned long long pos) +{ + return ZSTD_seekTable_offsetToFrameIndex(&zs->seekTable, pos); +} + +unsigned ZSTD_seekTable_offsetToFrameIndex(const ZSTD_seekTable* st, unsigned long long pos) +{ + U32 lo = 0; + U32 hi = (U32)st->tableLen; + assert(st->tableLen <= UINT_MAX); + + if (pos >= st->entries[st->tableLen].dOffset) { + return (unsigned)st->tableLen; + } + + while (lo + 1 < hi) { + U32 const mid = lo + ((hi - lo) >> 1); + if (st->entries[mid].dOffset <= pos) { + lo = mid; + } else { + hi = mid; + } + } + return lo; +} + +unsigned ZSTD_seekable_getNumFrames(const ZSTD_seekable* zs) +{ + return ZSTD_seekTable_getNumFrames(&zs->seekTable); +} + +unsigned ZSTD_seekTable_getNumFrames(const ZSTD_seekTable* st) +{ + assert(st->tableLen <= UINT_MAX); + return (unsigned)st->tableLen; +} + +unsigned long long ZSTD_seekable_getFrameCompressedOffset(const ZSTD_seekable* zs, unsigned frameIndex) +{ + return ZSTD_seekTable_getFrameCompressedOffset(&zs->seekTable, frameIndex); +} + +unsigned long long ZSTD_seekTable_getFrameCompressedOffset(const ZSTD_seekTable* st, unsigned frameIndex) +{ + if (frameIndex >= st->tableLen) return ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE; + return st->entries[frameIndex].cOffset; +} + +unsigned long long ZSTD_seekable_getFrameDecompressedOffset(const ZSTD_seekable* zs, unsigned frameIndex) +{ + return ZSTD_seekTable_getFrameDecompressedOffset(&zs->seekTable, frameIndex); +} + +unsigned long long ZSTD_seekTable_getFrameDecompressedOffset(const ZSTD_seekTable* st, unsigned frameIndex) +{ + if (frameIndex >= st->tableLen) return ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE; + return st->entries[frameIndex].dOffset; +} + +size_t ZSTD_seekable_getFrameCompressedSize(const ZSTD_seekable* zs, unsigned frameIndex) +{ + return ZSTD_seekTable_getFrameCompressedSize(&zs->seekTable, frameIndex); +} + +size_t ZSTD_seekTable_getFrameCompressedSize(const ZSTD_seekTable* st, unsigned frameIndex) +{ + if (frameIndex >= st->tableLen) return ERROR(frameIndex_tooLarge); + return st->entries[frameIndex + 1].cOffset - + st->entries[frameIndex].cOffset; +} + +size_t ZSTD_seekable_getFrameDecompressedSize(const ZSTD_seekable* zs, unsigned frameIndex) +{ + return ZSTD_seekTable_getFrameDecompressedSize(&zs->seekTable, frameIndex); +} + +size_t ZSTD_seekTable_getFrameDecompressedSize(const ZSTD_seekTable* st, unsigned frameIndex) +{ + if (frameIndex > st->tableLen) return ERROR(frameIndex_tooLarge); + return st->entries[frameIndex + 1].dOffset - + st->entries[frameIndex].dOffset; +} + +static size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable* zs) +{ + int checksumFlag; + ZSTD_seekable_customFile src = zs->src; + /* read the footer, fixed size */ + CHECK_IO(src.seek(src.opaque, -(int)ZSTD_seekTableFooterSize, SEEK_END)); + CHECK_IO(src.read(src.opaque, zs->inBuff, ZSTD_seekTableFooterSize)); + + if (MEM_readLE32(zs->inBuff + 5) != ZSTD_SEEKABLE_MAGICNUMBER) { + return ERROR(prefix_unknown); + } + + { BYTE const sfd = zs->inBuff[4]; + checksumFlag = sfd >> 7; + + /* check reserved bits */ + if ((sfd >> 2) & 0x1f) { + return ERROR(corruption_detected); + } } + + { U32 const numFrames = MEM_readLE32(zs->inBuff); + U32 const sizePerEntry = 8 + (checksumFlag?4:0); + U32 const tableSize = sizePerEntry * numFrames; + U32 const frameSize = tableSize + ZSTD_seekTableFooterSize + ZSTD_SKIPPABLEHEADERSIZE; + + U32 remaining = frameSize - ZSTD_seekTableFooterSize; /* don't need to re-read footer */ + { U32 const toRead = MIN(remaining, SEEKABLE_BUFF_SIZE); + CHECK_IO(src.seek(src.opaque, -(S64)frameSize, SEEK_END)); + CHECK_IO(src.read(src.opaque, zs->inBuff, toRead)); + remaining -= toRead; + } + + if (MEM_readLE32(zs->inBuff) != (ZSTD_MAGIC_SKIPPABLE_START | 0xE)) { + return ERROR(prefix_unknown); + } + if (MEM_readLE32(zs->inBuff+4) + ZSTD_SKIPPABLEHEADERSIZE != frameSize) { + return ERROR(prefix_unknown); + } + + { /* Allocate an extra entry at the end so that we can do size + * computations on the last element without special case */ + seekEntry_t* const entries = (seekEntry_t*)malloc(sizeof(seekEntry_t) * (numFrames + 1)); + + U32 idx = 0; + U32 pos = 8; + + U64 cOffset = 0; + U64 dOffset = 0; + + if (entries == NULL) return ERROR(memory_allocation); + + /* compute cumulative positions */ + for (; idx < numFrames; idx++) { + if (pos + sizePerEntry > SEEKABLE_BUFF_SIZE) { + U32 const offset = SEEKABLE_BUFF_SIZE - pos; + U32 const toRead = MIN(remaining, SEEKABLE_BUFF_SIZE - offset); + memmove(zs->inBuff, zs->inBuff + pos, offset); /* move any data we haven't read yet */ + CHECK_IO(src.read(src.opaque, zs->inBuff+offset, toRead)); + remaining -= toRead; + pos = 0; + } + entries[idx].cOffset = cOffset; + entries[idx].dOffset = dOffset; + + cOffset += MEM_readLE32(zs->inBuff + pos); + pos += 4; + dOffset += MEM_readLE32(zs->inBuff + pos); + pos += 4; + if (checksumFlag) { + entries[idx].checksum = MEM_readLE32(zs->inBuff + pos); + pos += 4; + } + } + entries[numFrames].cOffset = cOffset; + entries[numFrames].dOffset = dOffset; + + zs->seekTable.entries = entries; + zs->seekTable.tableLen = numFrames; + zs->seekTable.checksumFlag = checksumFlag; + return 0; + } + } +} + +size_t ZSTD_seekable_initBuff(ZSTD_seekable* zs, const void* src, size_t srcSize) +{ + zs->buffWrapper = (buffWrapper_t){src, srcSize, 0}; + { ZSTD_seekable_customFile srcFile = {&zs->buffWrapper, + &ZSTD_seekable_read_buff, + &ZSTD_seekable_seek_buff}; + return ZSTD_seekable_initAdvanced(zs, srcFile); } +} + +size_t ZSTD_seekable_initFile(ZSTD_seekable* zs, FILE* src) +{ + ZSTD_seekable_customFile srcFile = {src, &ZSTD_seekable_read_FILE, + &ZSTD_seekable_seek_FILE}; + return ZSTD_seekable_initAdvanced(zs, srcFile); +} + +size_t ZSTD_seekable_initAdvanced(ZSTD_seekable* zs, ZSTD_seekable_customFile src) +{ + zs->src = src; + + { const size_t seekTableInit = ZSTD_seekable_loadSeekTable(zs); + if (ZSTD_isError(seekTableInit)) return seekTableInit; } + + zs->decompressedOffset = (U64)-1; + zs->curFrame = (U32)-1; + + { const size_t dstreamInit = ZSTD_initDStream(zs->dstream); + if (ZSTD_isError(dstreamInit)) return dstreamInit; } + return 0; +} + +size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsigned long long offset) +{ + unsigned long long const eos = zs->seekTable.entries[zs->seekTable.tableLen].dOffset; + if (offset + len > eos) { + len = eos - offset; + } + + U32 targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, offset); + U32 noOutputProgressCount = 0; + size_t srcBytesRead = 0; + do { + /* check if we can continue from a previous decompress job */ + if (targetFrame != zs->curFrame || offset < zs->decompressedOffset) { + zs->decompressedOffset = zs->seekTable.entries[targetFrame].dOffset; + zs->curFrame = targetFrame; + + assert(zs->seekTable.entries[targetFrame].cOffset < LLONG_MAX); + CHECK_IO(zs->src.seek(zs->src.opaque, + (long long)zs->seekTable.entries[targetFrame].cOffset, + SEEK_SET)); + zs->in = (ZSTD_inBuffer){zs->inBuff, 0, 0}; + XXH64_reset(&zs->xxhState, 0); + ZSTD_DCtx_reset(zs->dstream, ZSTD_reset_session_only); + if (zs->buffWrapper.size && srcBytesRead > zs->buffWrapper.size) { + return ERROR(seekableIO); + } + } + + while (zs->decompressedOffset < offset + len) { + size_t toRead; + ZSTD_outBuffer outTmp; + size_t prevOutPos; + size_t prevInPos; + size_t forwardProgress; + if (zs->decompressedOffset < offset) { + /* dummy decompressions until we get to the target offset */ + outTmp = (ZSTD_outBuffer){zs->outBuff, (size_t) (MIN(SEEKABLE_BUFF_SIZE, offset - zs->decompressedOffset)), 0}; + } else { + outTmp = (ZSTD_outBuffer){dst, len, (size_t) (zs->decompressedOffset - offset)}; + } + + prevOutPos = outTmp.pos; + prevInPos = zs->in.pos; + toRead = ZSTD_decompressStream(zs->dstream, &outTmp, &zs->in); + if (ZSTD_isError(toRead)) { + return toRead; + } + + if (zs->seekTable.checksumFlag) { + XXH64_update(&zs->xxhState, (BYTE*)outTmp.dst + prevOutPos, + outTmp.pos - prevOutPos); + } + forwardProgress = outTmp.pos - prevOutPos; + if (forwardProgress == 0) { + if (noOutputProgressCount++ > ZSTD_SEEKABLE_NO_OUTPUT_PROGRESS_MAX) { + return ERROR(seekableIO); + } + } else { + noOutputProgressCount = 0; + } + zs->decompressedOffset += forwardProgress; + srcBytesRead += zs->in.pos - prevInPos; + + if (toRead == 0) { + /* frame complete */ + + /* verify checksum */ + if (zs->seekTable.checksumFlag && + (XXH64_digest(&zs->xxhState) & 0xFFFFFFFFU) != + zs->seekTable.entries[targetFrame].checksum) { + return ERROR(corruption_detected); + } + + if (zs->decompressedOffset < offset + len) { + /* go back to the start and force a reset of the stream */ + targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, zs->decompressedOffset); + /* in this case it will fail later with corruption_detected, since last block does not have checksum */ + assert(targetFrame != zs->seekTable.tableLen); + } + break; + } + + /* read in more data if we're done with this buffer */ + if (zs->in.pos == zs->in.size) { + toRead = MIN(toRead, SEEKABLE_BUFF_SIZE); + CHECK_IO(zs->src.read(zs->src.opaque, zs->inBuff, toRead)); + zs->in.size = toRead; + zs->in.pos = 0; + } + } /* while (zs->decompressedOffset < offset + len) */ + } while (zs->decompressedOffset != offset + len); + + return len; +} + +size_t ZSTD_seekable_decompressFrame(ZSTD_seekable* zs, void* dst, size_t dstSize, unsigned frameIndex) +{ + if (frameIndex >= zs->seekTable.tableLen) { + return ERROR(frameIndex_tooLarge); + } + + { size_t const decompressedSize = + zs->seekTable.entries[frameIndex + 1].dOffset - + zs->seekTable.entries[frameIndex].dOffset; + if (dstSize < decompressedSize) { + return ERROR(dstSize_tooSmall); + } + return ZSTD_seekable_decompress( + zs, dst, decompressedSize, + zs->seekTable.entries[frameIndex].dOffset); + } +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/seqBench/Makefile b/cpp/third_party/zstd-1.5.7/contrib/seqBench/Makefile new file mode 100644 index 000000000..e7f08a42c --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seqBench/Makefile @@ -0,0 +1,58 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ################################################################ + +PROGDIR = ../../programs +LIBDIR = ../../lib + +LIBZSTD = $(LIBDIR)/libzstd.a + +CPPFLAGS+= -I$(LIBDIR) -I$(LIBDIR)/common -I$(LIBDIR)/dictBuilder -I$(PROGDIR) + +CFLAGS ?= -O3 -g +CFLAGS += -std=gnu99 +DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum \ + -Wstrict-prototypes -Wundef -Wpointer-arith \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls +CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) + + +default: seqBench + +all : seqBench + +seqBench: util.o timefn.o benchfn.o datagen.o xxhash.o seqBench.c $(LIBZSTD) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +.PHONY: $(LIBZSTD) +$(LIBZSTD): + $(MAKE) -C $(LIBDIR) libzstd.a CFLAGS="$(CFLAGS)" + +benchfn.o: $(PROGDIR)/benchfn.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + +timefn.o: $(PROGDIR)/timefn.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + +datagen.o: $(PROGDIR)/datagen.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + +util.o: $(PROGDIR)/util.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + + +xxhash.o : $(LIBDIR)/common/xxhash.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c + + +clean: + $(RM) *.o + $(MAKE) -C $(LIBDIR) clean > /dev/null + $(RM) seqBench diff --git a/cpp/third_party/zstd-1.5.7/contrib/seqBench/seqBench.c b/cpp/third_party/zstd-1.5.7/contrib/seqBench/seqBench.c new file mode 100644 index 000000000..7efebec7b --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/seqBench/seqBench.c @@ -0,0 +1,53 @@ +#define ZSTD_STATIC_LINKING_ONLY +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + ZSTD_CCtx* zc = ZSTD_createCCtx(); + + if (argc != 2) { + printf("Usage: seqBench \n"); // TODO provide the block delim option here + return 1; + } + + FILE *f = fopen(argv[1], "rb"); + fseek(f, 0, SEEK_END); + long inBufSize = ftell(f); + fseek(f, 0, SEEK_SET); + + char *inBuf = malloc(inBufSize + 1); + fread(inBuf, inBufSize, 1, f); + fclose(f); + + size_t seqsSize = ZSTD_sequenceBound(inBufSize); + ZSTD_Sequence *seqs = (ZSTD_Sequence*)malloc(seqsSize * sizeof(ZSTD_Sequence)); + char *outBuf = malloc(ZSTD_compressBound(inBufSize)); + + ZSTD_generateSequences(zc, seqs, seqsSize, inBuf, inBufSize); + ZSTD_CCtx_setParameter(zc, ZSTD_c_blockDelimiters, ZSTD_sf_explicitBlockDelimiters); + size_t outBufSize = ZSTD_compressSequences(zc, outBuf, inBufSize, seqs, seqsSize, inBuf, inBufSize); + if (ZSTD_isError(outBufSize)) { + printf("ERROR: %lu\n", outBufSize); + return 1; + } + + char *validationBuf = malloc(inBufSize); + ZSTD_decompress(validationBuf, inBufSize, outBuf, outBufSize); + + if (memcmp(inBuf, validationBuf, inBufSize) == 0) { + printf("Compression and decompression were successful!\n"); + } else { + printf("ERROR: input and validation buffers don't match!\n"); + for (int i = 0; i < inBufSize; i++) { + if (inBuf[i] != validationBuf[i]) { + printf("First bad index: %d\n", i); + break; + } + } + } + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/contrib/snap/snapcraft.yaml b/cpp/third_party/zstd-1.5.7/contrib/snap/snapcraft.yaml new file mode 100644 index 000000000..0a77946ae --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/contrib/snap/snapcraft.yaml @@ -0,0 +1,28 @@ +name: zstd +version: git +summary: Zstandard - Fast real-time compression algorithm +description: | + Zstandard, or zstd as short version, is a fast lossless compression + algorithm, targeting real-time compression scenarios at zlib-level and better + compression ratios. It's backed by a very fast entropy stage, provided by + Huff0 and FSE library + +grade: devel # must be 'stable' to release into candidate/stable channels +confinement: devmode # use 'strict' once you have the right plugs and slots + +apps: + zstd: + command: usr/local/bin/zstd + plugs: [home, removable-media] + zstdgrep: + command: usr/local/bin/zstdgrep + plugs: [home, removable-media] + zstdless: + command: usr/local/bin/zstdless + plugs: [home, removable-media] + +parts: + zstd: + source: . + plugin: make + build-packages: [g++] diff --git a/cpp/third_party/zstd-1.5.7/doc/README.md b/cpp/third_party/zstd-1.5.7/doc/README.md new file mode 100644 index 000000000..8f3babcdb --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/README.md @@ -0,0 +1,26 @@ +Zstandard Documentation +======================= + +This directory contains material defining the Zstandard format, +as well as detailed instructions to use `zstd` library. + +__`zstd_manual.html`__ : Documentation of `zstd.h` API, in html format. +Unfortunately, Github doesn't display `html` files in parsed format, just as source code. +For a readable display of html API documentation of latest release, +use this link: [https://raw.githack.com/facebook/zstd/release/doc/zstd_manual.html](https://raw.githack.com/facebook/zstd/release/doc/zstd_manual.html) . + +__`zstd_compression_format.md`__ : This document defines the Zstandard compression format. +Compliant decoders must adhere to this document, +and compliant encoders must generate data that follows it. + +Should you look for resources to develop your own port of Zstandard algorithm, +you may find the following resources useful : + +__`educational_decoder`__ : This directory contains an implementation of a Zstandard decoder, +compliant with the Zstandard compression format. +It can be used, for example, to better understand the format, +or as the basis for a separate implementation of Zstandard decoder. + +[__`decode_corpus`__](https://github.com/facebook/zstd/tree/dev/tests#decodecorpus---tool-to-generate-zstandard-frames-for-decoder-testing) : +This tool, stored in `/tests` directory, is able to generate random valid frames, +which is useful if you wish to test your decoder and verify it fully supports the specification. diff --git a/cpp/third_party/zstd-1.5.7/doc/decompressor_errata.md b/cpp/third_party/zstd-1.5.7/doc/decompressor_errata.md new file mode 100644 index 000000000..b570f7314 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/decompressor_errata.md @@ -0,0 +1,148 @@ +Decompressor Errata +=================== + +This document captures known decompressor bugs, where the decompressor rejects a valid zstd frame. +Each entry will contain: +1. The last affected decompressor versions. +2. The decompressor components affected. +2. Whether the compressed frame could ever be produced by the reference compressor. +3. An example frame (hexadecimal string when it can be short enough, link to golden file otherwise) +4. A description of the bug. + +The document is in reverse chronological order, with the bugs that affect the most recent zstd decompressor versions listed first. + + +No sequence using the 2-bytes format +------------------------------------------------ + +**Last affected version**: v1.5.5 + +**Affected decompressor component(s)**: Library & CLI + +**Produced by the reference compressor**: No + +**Example Frame**: see zstd/tests/golden-decompression/zeroSeq_2B.zst + +The zstd decoder incorrectly expects FSE tables when there are 0 sequences present in the block +if the value 0 is encoded using the 2-bytes format. +Instead, it should immediately end the sequence section, and move on to next block. + +This situation was never generated by the reference compressor, +because representing 0 sequences with the 2-bytes format is inefficient +(the 1-byte format is always used in this case). + + +Compressed block with a size of exactly 128 KB +------------------------------------------------ + +**Last affected version**: v1.5.2 + +**Affected decompressor component(s)**: Library & CLI + +**Produced by the reference compressor**: No + +**Example Frame**: see zstd/tests/golden-decompression/block-128k.zst + +The zstd decoder incorrectly rejected blocks of type `Compressed_Block` when their size was exactly 128 KB. +Note that `128 KB - 1` was accepted, and `128 KB + 1` is forbidden by the spec. + +This type of block was never generated by the reference compressor. + +These blocks used to be disallowed by the spec up until spec version 0.3.2 when the restriction was lifted by [PR#1689](https://github.com/facebook/zstd/pull/1689). + +> A Compressed_Block has the extra restriction that Block_Size is always strictly less than the decompressed size. If this condition cannot be respected, the block must be sent uncompressed instead (Raw_Block). + + +Compressed block with 0 literals and 0 sequences +------------------------------------------------ + +**Last affected version**: v1.5.2 + +**Affected decompressor component(s)**: Library & CLI + +**Produced by the reference compressor**: No + +**Example Frame**: `28b5 2ffd 2000 1500 0000 00` + +The zstd decoder incorrectly rejected blocks of type `Compressed_Block` that encodes literals as `Raw_Literals_Block` with no literals, and has no sequences. + +This type of block was never generated by the reference compressor. + +Additionally, these blocks were disallowed by the spec up until spec version 0.3.2 when the restriction was lifted by [PR#1689](https://github.com/facebook/zstd/pull/1689). + +> A Compressed_Block has the extra restriction that Block_Size is always strictly less than the decompressed size. If this condition cannot be respected, the block must be sent uncompressed instead (Raw_Block). + + +First block is RLE block +------------------------ + +**Last affected version**: v1.4.3 + +**Affected decompressor component(s)**: CLI only + +**Produced by the reference compressor**: No + +**Example Frame**: `28b5 2ffd a001 0002 0002 0010 000b 0000 00` + +The zstd CLI decompressor rejected cases where the first block was an RLE block whose `Block_Size` is 131072, and the frame contains more than one block. +This only affected the zstd CLI, and not the library. + +The example is an RLE block with 131072 bytes, followed by a second RLE block with 1 byte. + +The compressor currently works around this limitation by explicitly avoiding producing RLE blocks as the first +block. + +https://github.com/facebook/zstd/blob/8814aa5bfa74f05a86e55e9d508da177a893ceeb/lib/compress/zstd_compress.c#L3527-L3535 + + +Tiny FSE Table & Block +---------------------- + +**Last affected version**: v1.3.4 + +**Affected decompressor component(s)**: Library & CLI + +**Produced by the reference compressor**: Possibly until version v1.3.4, but probably never + +**Example Frame**: `28b5 2ffd 2027 c500 0080 f3f1 f0ec ebc6 c5c7 f09d 4300 0000 e0e0 0658 0100 603e 52` + +The zstd library rejected blocks of type `Compressed_Block` whose offset of the last table with type `FSE_Compressed_Mode` was less than 4 bytes from the end of the block. + +In more depth, let `Last_Table_Offset` be the offset in the compressed block (excluding the header) that +the last table with type `FSE_Compressed_Mode` started. If `Block_Content - Last_Table_Offset < 4` then +the buggy zstd decompressor would reject the block. This occurs when the last serialized table is 2 bytes +and the bitstream size is 1 byte. + +For example: +* There is 1 sequence in the block +* `Literals_Lengths_Mode` is `FSE_Compressed_Mode` & the serialized table size is 2 bytes +* `Offsets_Mode` is `Predefined_Mode` +* `Match_Lengths_Mode` is `Predefined_Mode` +* The bitstream is 1 byte. E.g. there is only one sequence and it fits in 1 byte. + +The total `Block_Content` is `5` bytes, and `Last_Table_Offset` is `2`. + +See the compressor workaround code: + +https://github.com/facebook/zstd/blob/8814aa5bfa74f05a86e55e9d508da177a893ceeb/lib/compress/zstd_compress.c#L2667-L2682 + +Magicless format +---------------------- + +**Last affected version**: v1.5.5 + +**Affected decompressor component(s)**: Library + +**Produced by the reference compressor**: Yes (example: https://gist.github.com/embg/9940726094f4cf2cef162cffe9319232) + +**Example Frame**: `27 b5 2f fd 00 03 19 00 00 66 6f 6f 3f ba c4 59` + +v1.5.6 fixes several bugs in which the magicless-format decoder rejects valid frames. +These include but are not limited to: +* Valid frames that happen to begin with a legacy magic number (little-endian) +* Valid frames that happen to begin with a skippable magic number (little-endian) + +If you are affected by this issue and cannot update to v1.5.6 or later, there is a +workaround to recover affected data. Simply prepend the ZSTD magic number +`0xFD2FB528` (little-endian) to your data and decompress using the standard-format +decoder. diff --git a/cpp/third_party/zstd-1.5.7/doc/decompressor_permissive.md b/cpp/third_party/zstd-1.5.7/doc/decompressor_permissive.md new file mode 100644 index 000000000..164d6c86d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/decompressor_permissive.md @@ -0,0 +1,80 @@ +Decompressor Permissiveness to Invalid Data +=========================================== + +This document describes the behavior of the reference decompressor in cases +where it accepts formally invalid data instead of reporting an error. + +While the reference decompressor *must* decode any compliant frame following +the specification, its ability to detect erroneous data is on a best effort +basis: the decoder may accept input data that would be formally invalid, +when it causes no risk to the decoder, and which detection would cost too much +complexity or speed regression. + +In practice, the vast majority of invalid data are detected, if only because +many corruption events are dangerous for the decoder process (such as +requesting an out-of-bound memory access) and many more are easy to check. + +This document lists a few known cases where invalid data was formerly accepted +by the decoder, and what has changed since. + + +Truncated Huffman states +------------------------ + +**Last affected version**: v1.5.6 + +**Produced by the reference compressor**: No + +**Example Frame**: `28b5 2ffd 0000 5500 0072 8001 0420 7e1f 02aa 00` + +When using FSE-compressed Huffman weights, the compressed weight bitstream +could contain fewer bits than necessary to decode the initial states. + +The reference decompressor up to v1.5.6 will decode truncated or missing +initial states as zero, which can result in a valid Huffman tree if only +the second state is truncated. + +In newer versions, truncated initial states are reported as a corruption +error by the decoder. + + +Offset == 0 +----------- + +**Last affected version**: v1.5.5 + +**Produced by the reference compressor**: No + +**Example Frame**: `28b5 2ffd 0000 4500 0008 0002 002f 430b ae` + +If a sequence is decoded with `literals_length = 0` and `offset_value = 3` +while `Repeated_Offset_1 = 1`, the computed offset will be `0`, which is +invalid. + +The reference decompressor up to v1.5.5 processes this case as if the computed +offset was `1`, including inserting `1` into the repeated offset list. +This prevents the output buffer from remaining uninitialized, thus denying a +potential attack vector from an untrusted source. +However, in the rare case where this scenario would be the outcome of a +transmission or storage error, the decoder relies on the checksum to detect +the error. + +In newer versions, this case is always detected and reported as a corruption error. + + +Non-zeroes reserved bits +------------------------ + +**Last affected version**: v1.5.5 + +**Produced by the reference compressor**: No + +The Sequences section of each block has a header, and one of its elements is a +byte, which describes the compression mode of each symbol. +This byte contains 2 reserved bits which must be set to zero. + +The reference decompressor up to v1.5.5 just ignores these 2 bits. +This behavior has no consequence for the rest of the frame decoding process. + +In newer versions, the 2 reserved bits are actively checked for value zero, +and the decoder reports a corruption error if they are not. diff --git a/cpp/third_party/zstd-1.5.7/doc/educational_decoder/.gitignore b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/.gitignore new file mode 100644 index 000000000..b801306fa --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/.gitignore @@ -0,0 +1,2 @@ +# Build artifacts +harness diff --git a/cpp/third_party/zstd-1.5.7/doc/educational_decoder/Makefile b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/Makefile new file mode 100644 index 000000000..b3154d9af --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/Makefile @@ -0,0 +1,62 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ + +ZSTD ?= zstd # note: requires zstd installation on local system + +UNAME?= $(shell sh -c 'MSYSTEM="MSYS" uname') +ifeq ($(UNAME), SunOS) +DIFF ?= gdiff +else +DIFF ?= diff +endif + +HARNESS_FILES=*.c + +MULTITHREAD_LDFLAGS = -pthread +DEBUGFLAGS= -g -DZSTD_DEBUG=1 +CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ + -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) +CFLAGS ?= -O2 +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum \ + -Wredundant-decls -Wstrict-prototypes -Wundef \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -std=c99 +CFLAGS += $(DEBUGFLAGS) +CFLAGS += $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MULTITHREAD_LDFLAGS) + +harness: $(HARNESS_FILES) + $(CC) $(FLAGS) $^ -o $@ + +clean: + @$(RM) harness *.o + @$(RM) -rf harness.dSYM # MacOS specific + +test: harness + # + # Testing single-file decompression with educational decoder + # + @$(ZSTD) -f README.md -o tmp.zst + @./harness tmp.zst tmp + @$(DIFF) -s tmp README.md + @$(RM) tmp* + # + # Testing dictionary decompression with education decoder + # + # note : files are presented multiple for training, to reach minimum threshold + @$(ZSTD) --train harness.c zstd_decompress.c zstd_decompress.h README.md \ + harness.c zstd_decompress.c zstd_decompress.h README.md \ + harness.c zstd_decompress.c zstd_decompress.h README.md \ + -o dictionary + @$(ZSTD) -f README.md -D dictionary -o tmp.zst + @./harness tmp.zst tmp dictionary + @$(DIFF) -s tmp README.md + @$(RM) tmp* dictionary diff --git a/cpp/third_party/zstd-1.5.7/doc/educational_decoder/README.md b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/README.md new file mode 100644 index 000000000..c89451ca0 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/README.md @@ -0,0 +1,36 @@ +Educational Decoder +=================== + +`zstd_decompress.c` is a self-contained implementation in C99 of a decoder, +according to the [Zstandard format specification]. +While it does not implement as many features as the reference decoder, +such as the streaming API or content checksums, it is written to be easy to +follow and understand, to help understand how the Zstandard format works. +It's laid out to match the [format specification], +so it can be used to understand how complex segments could be implemented. +It also contains implementations of Huffman and FSE table decoding. + +[Zstandard format specification]: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md +[format specification]: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md + +While the library's primary objective is code clarity, +it also happens to compile into a small object file. +The object file can be made even smaller by removing error messages, +using the macro directive `ZDEC_NO_MESSAGE` at compilation time. +This can be reduced even further by foregoing dictionary support, +by defining `ZDEC_NO_DICTIONARY`. + +`harness.c` provides a simple test harness around the decoder: + + harness [dictionary] + +As an additional resource to be used with this decoder, +see the `decodecorpus` tool in the [tests] directory. +It generates valid Zstandard frames that can be used to verify +a Zstandard decoder implementation. +Note that to use the tool to verify this decoder implementation, +the --content-size flag should be set, +as this decoder does not handle streaming decoding, +and so it must know the decompressed size in advance. + +[tests]: https://github.com/facebook/zstd/blob/dev/tests/ diff --git a/cpp/third_party/zstd-1.5.7/doc/educational_decoder/harness.c b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/harness.c new file mode 100644 index 000000000..12c5a801b --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/harness.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include +#include + +#include "zstd_decompress.h" + +typedef unsigned char u8; + +// If the data doesn't have decompressed size with it, fallback on assuming the +// compression ratio is at most 16 +#define MAX_COMPRESSION_RATIO (16) + +// Protect against allocating too much memory for output +#define MAX_OUTPUT_SIZE ((size_t)1024 * 1024 * 1024) + +// Error message then exit +#define ERR_OUT(...) { fprintf(stderr, __VA_ARGS__); exit(1); } + + +typedef struct { + u8* address; + size_t size; +} buffer_s; + +static void freeBuffer(buffer_s b) { free(b.address); } + +static buffer_s read_file(const char *path) +{ + FILE* const f = fopen(path, "rb"); + if (!f) ERR_OUT("failed to open file %s \n", path); + + fseek(f, 0L, SEEK_END); + size_t const size = (size_t)ftell(f); + rewind(f); + + void* const ptr = malloc(size); + if (!ptr) ERR_OUT("failed to allocate memory to hold %s \n", path); + + size_t const read = fread(ptr, 1, size, f); + if (read != size) ERR_OUT("error while reading file %s \n", path); + + fclose(f); + buffer_s const b = { ptr, size }; + return b; +} + +static void write_file(const char* path, const u8* ptr, size_t size) +{ + FILE* const f = fopen(path, "wb"); + if (!f) ERR_OUT("failed to open file %s \n", path); + + size_t written = 0; + while (written < size) { + written += fwrite(ptr+written, 1, size, f); + if (ferror(f)) ERR_OUT("error while writing file %s\n", path); + } + + fclose(f); +} + +int main(int argc, char **argv) +{ + if (argc < 3) + ERR_OUT("usage: %s [dictionary] \n", argv[0]); + + buffer_s const input = read_file(argv[1]); + + buffer_s dict = { NULL, 0 }; + if (argc >= 4) { + dict = read_file(argv[3]); + } + + size_t out_capacity = ZSTD_get_decompressed_size(input.address, input.size); + if (out_capacity == (size_t)-1) { + out_capacity = MAX_COMPRESSION_RATIO * input.size; + fprintf(stderr, "WARNING: Compressed data does not contain " + "decompressed size, going to assume the compression " + "ratio is at most %d (decompressed size of at most " + "%u) \n", + MAX_COMPRESSION_RATIO, (unsigned)out_capacity); + } + if (out_capacity > MAX_OUTPUT_SIZE) + ERR_OUT("Required output size too large for this implementation \n"); + + u8* const output = malloc(out_capacity); + if (!output) ERR_OUT("failed to allocate memory \n"); + + dictionary_t* const parsed_dict = create_dictionary(); + if (dict.size) { +#if defined (ZDEC_NO_DICTIONARY) + printf("dict.size = %zu \n", dict.size); + ERR_OUT("no dictionary support \n"); +#else + parse_dictionary(parsed_dict, dict.address, dict.size); +#endif + } + size_t const decompressed_size = + ZSTD_decompress_with_dict(output, out_capacity, + input.address, input.size, + parsed_dict); + + free_dictionary(parsed_dict); + + write_file(argv[2], output, decompressed_size); + + freeBuffer(input); + freeBuffer(dict); + free(output); + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/doc/educational_decoder/zstd_decompress.c b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/zstd_decompress.c new file mode 100644 index 000000000..839e085b4 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/zstd_decompress.c @@ -0,0 +1,2323 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/// Zstandard educational decoder implementation +/// See https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md + +#include // uint8_t, etc. +#include // malloc, free, exit +#include // fprintf +#include // memset, memcpy +#include "zstd_decompress.h" + + +/******* IMPORTANT CONSTANTS *********************************************/ + +// Zstandard frame +// "Magic_Number +// 4 Bytes, little-endian format. Value : 0xFD2FB528" +#define ZSTD_MAGIC_NUMBER 0xFD2FB528U + +// The size of `Block_Content` is limited by `Block_Maximum_Size`, +#define ZSTD_BLOCK_SIZE_MAX ((size_t)128 * 1024) + +// literal blocks can't be larger than their block +#define MAX_LITERALS_SIZE ZSTD_BLOCK_SIZE_MAX + + +/******* UTILITY MACROS AND TYPES *********************************************/ +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#if defined(ZDEC_NO_MESSAGE) +#define MESSAGE(...) +#else +#define MESSAGE(...) fprintf(stderr, "" __VA_ARGS__) +#endif + +/// This decoder calls exit(1) when it encounters an error, however a production +/// library should propagate error codes +#define ERROR(s) \ + do { \ + MESSAGE("Error: %s\n", s); \ + exit(1); \ + } while (0) +#define INP_SIZE() \ + ERROR("Input buffer smaller than it should be or input is " \ + "corrupted") +#define OUT_SIZE() ERROR("Output buffer too small for output") +#define CORRUPTION() ERROR("Corruption detected while decompressing") +#define BAD_ALLOC() ERROR("Memory allocation error") +#define IMPOSSIBLE() ERROR("An impossibility has occurred") + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; +/******* END UTILITY MACROS AND TYPES *****************************************/ + +/******* IMPLEMENTATION PRIMITIVE PROTOTYPES **********************************/ +/// The implementations for these functions can be found at the bottom of this +/// file. They implement low-level functionality needed for the higher level +/// decompression functions. + +/*** IO STREAM OPERATIONS *************/ + +/// ostream_t/istream_t are used to wrap the pointers/length data passed into +/// ZSTD_decompress, so that all IO operations are safely bounds checked +/// They are written/read forward, and reads are treated as little-endian +/// They should be used opaquely to ensure safety +typedef struct { + u8 *ptr; + size_t len; +} ostream_t; + +typedef struct { + const u8 *ptr; + size_t len; + + // Input often reads a few bits at a time, so maintain an internal offset + int bit_offset; +} istream_t; + +/// The following two functions are the only ones that allow the istream to be +/// non-byte aligned + +/// Reads `num` bits from a bitstream, and updates the internal offset +static inline u64 IO_read_bits(istream_t *const in, const int num_bits); +/// Backs-up the stream by `num` bits so they can be read again +static inline void IO_rewind_bits(istream_t *const in, const int num_bits); +/// If the remaining bits in a byte will be unused, advance to the end of the +/// byte +static inline void IO_align_stream(istream_t *const in); + +/// Write the given byte into the output stream +static inline void IO_write_byte(ostream_t *const out, u8 symb); + +/// Returns the number of bytes left to be read in this stream. The stream must +/// be byte aligned. +static inline size_t IO_istream_len(const istream_t *const in); + +/// Advances the stream by `len` bytes, and returns a pointer to the chunk that +/// was skipped. The stream must be byte aligned. +static inline const u8 *IO_get_read_ptr(istream_t *const in, size_t len); +/// Advances the stream by `len` bytes, and returns a pointer to the chunk that +/// was skipped so it can be written to. +static inline u8 *IO_get_write_ptr(ostream_t *const out, size_t len); + +/// Advance the inner state by `len` bytes. The stream must be byte aligned. +static inline void IO_advance_input(istream_t *const in, size_t len); + +/// Returns an `ostream_t` constructed from the given pointer and length. +static inline ostream_t IO_make_ostream(u8 *out, size_t len); +/// Returns an `istream_t` constructed from the given pointer and length. +static inline istream_t IO_make_istream(const u8 *in, size_t len); + +/// Returns an `istream_t` with the same base as `in`, and length `len`. +/// Then, advance `in` to account for the consumed bytes. +/// `in` must be byte aligned. +static inline istream_t IO_make_sub_istream(istream_t *const in, size_t len); +/*** END IO STREAM OPERATIONS *********/ + +/*** BITSTREAM OPERATIONS *************/ +/// Read `num` bits (up to 64) from `src + offset`, where `offset` is in bits, +/// and return them interpreted as a little-endian unsigned integer. +static inline u64 read_bits_LE(const u8 *src, const int num_bits, + const size_t offset); + +/// Read bits from the end of a HUF or FSE bitstream. `offset` is in bits, so +/// it updates `offset` to `offset - bits`, and then reads `bits` bits from +/// `src + offset`. If the offset becomes negative, the extra bits at the +/// bottom are filled in with `0` bits instead of reading from before `src`. +static inline u64 STREAM_read_bits(const u8 *src, const int bits, + i64 *const offset); +/*** END BITSTREAM OPERATIONS *********/ + +/*** BIT COUNTING OPERATIONS **********/ +/// Returns the index of the highest set bit in `num`, or `-1` if `num == 0` +static inline int highest_set_bit(const u64 num); +/*** END BIT COUNTING OPERATIONS ******/ + +/*** HUFFMAN PRIMITIVES ***************/ +// Table decode method uses exponential memory, so we need to limit depth +#define HUF_MAX_BITS (16) + +// Limit the maximum number of symbols to 256 so we can store a symbol in a byte +#define HUF_MAX_SYMBS (256) + +/// Structure containing all tables necessary for efficient Huffman decoding +typedef struct { + u8 *symbols; + u8 *num_bits; + int max_bits; +} HUF_dtable; + +/// Decode a single symbol and read in enough bits to refresh the state +static inline u8 HUF_decode_symbol(const HUF_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset); +/// Read in a full state's worth of bits to initialize it +static inline void HUF_init_state(const HUF_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset); + +/// Decompresses a single Huffman stream, returns the number of bytes decoded. +/// `src_len` must be the exact length of the Huffman-coded block. +static size_t HUF_decompress_1stream(const HUF_dtable *const dtable, + ostream_t *const out, istream_t *const in); +/// Same as previous but decodes 4 streams, formatted as in the Zstandard +/// specification. +/// `src_len` must be the exact length of the Huffman-coded block. +static size_t HUF_decompress_4stream(const HUF_dtable *const dtable, + ostream_t *const out, istream_t *const in); + +/// Initialize a Huffman decoding table using the table of bit counts provided +static void HUF_init_dtable(HUF_dtable *const table, const u8 *const bits, + const int num_symbs); +/// Initialize a Huffman decoding table using the table of weights provided +/// Weights follow the definition provided in the Zstandard specification +static void HUF_init_dtable_usingweights(HUF_dtable *const table, + const u8 *const weights, + const int num_symbs); + +/// Free the malloc'ed parts of a decoding table +static void HUF_free_dtable(HUF_dtable *const dtable); +/*** END HUFFMAN PRIMITIVES ***********/ + +/*** FSE PRIMITIVES *******************/ +/// For more description of FSE see +/// https://github.com/Cyan4973/FiniteStateEntropy/ + +// FSE table decoding uses exponential memory, so limit the maximum accuracy +#define FSE_MAX_ACCURACY_LOG (15) +// Limit the maximum number of symbols so they can be stored in a single byte +#define FSE_MAX_SYMBS (256) + +/// The tables needed to decode FSE encoded streams +typedef struct { + u8 *symbols; + u8 *num_bits; + u16 *new_state_base; + int accuracy_log; +} FSE_dtable; + +/// Return the symbol for the current state +static inline u8 FSE_peek_symbol(const FSE_dtable *const dtable, + const u16 state); +/// Read the number of bits necessary to update state, update, and shift offset +/// back to reflect the bits read +static inline void FSE_update_state(const FSE_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset); + +/// Combine peek and update: decode a symbol and update the state +static inline u8 FSE_decode_symbol(const FSE_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset); + +/// Read bits from the stream to initialize the state and shift offset back +static inline void FSE_init_state(const FSE_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset); + +/// Decompress two interleaved bitstreams (e.g. compressed Huffman weights) +/// using an FSE decoding table. `src_len` must be the exact length of the +/// block. +static size_t FSE_decompress_interleaved2(const FSE_dtable *const dtable, + ostream_t *const out, + istream_t *const in); + +/// Initialize a decoding table using normalized frequencies. +static void FSE_init_dtable(FSE_dtable *const dtable, + const i16 *const norm_freqs, const int num_symbs, + const int accuracy_log); + +/// Decode an FSE header as defined in the Zstandard format specification and +/// use the decoded frequencies to initialize a decoding table. +static void FSE_decode_header(FSE_dtable *const dtable, istream_t *const in, + const int max_accuracy_log); + +/// Initialize an FSE table that will always return the same symbol and consume +/// 0 bits per symbol, to be used for RLE mode in sequence commands +static void FSE_init_dtable_rle(FSE_dtable *const dtable, const u8 symb); + +/// Free the malloc'ed parts of a decoding table +static void FSE_free_dtable(FSE_dtable *const dtable); +/*** END FSE PRIMITIVES ***************/ + +/******* END IMPLEMENTATION PRIMITIVE PROTOTYPES ******************************/ + +/******* ZSTD HELPER STRUCTS AND PROTOTYPES ***********************************/ + +/// A small structure that can be reused in various places that need to access +/// frame header information +typedef struct { + // The size of window that we need to be able to contiguously store for + // references + size_t window_size; + // The total output size of this compressed frame + size_t frame_content_size; + + // The dictionary id if this frame uses one + u32 dictionary_id; + + // Whether or not the content of this frame has a checksum + int content_checksum_flag; + // Whether or not the output for this frame is in a single segment + int single_segment_flag; +} frame_header_t; + +/// The context needed to decode blocks in a frame +typedef struct { + frame_header_t header; + + // The total amount of data available for backreferences, to determine if an + // offset too large to be correct + size_t current_total_output; + + const u8 *dict_content; + size_t dict_content_len; + + // Entropy encoding tables so they can be repeated by future blocks instead + // of retransmitting + HUF_dtable literals_dtable; + FSE_dtable ll_dtable; + FSE_dtable ml_dtable; + FSE_dtable of_dtable; + + // The last 3 offsets for the special "repeat offsets". + u64 previous_offsets[3]; +} frame_context_t; + +/// The decoded contents of a dictionary so that it doesn't have to be repeated +/// for each frame that uses it +struct dictionary_s { + // Entropy tables + HUF_dtable literals_dtable; + FSE_dtable ll_dtable; + FSE_dtable ml_dtable; + FSE_dtable of_dtable; + + // Raw content for backreferences + u8 *content; + size_t content_size; + + // Offset history to prepopulate the frame's history + u64 previous_offsets[3]; + + u32 dictionary_id; +}; + +/// A tuple containing the parts necessary to decode and execute a ZSTD sequence +/// command +typedef struct { + u32 literal_length; + u32 match_length; + u32 offset; +} sequence_command_t; + +/// The decoder works top-down, starting at the high level like Zstd frames, and +/// working down to lower more technical levels such as blocks, literals, and +/// sequences. The high-level functions roughly follow the outline of the +/// format specification: +/// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md + +/// Before the implementation of each high-level function declared here, the +/// prototypes for their helper functions are defined and explained + +/// Decode a single Zstd frame, or error if the input is not a valid frame. +/// Accepts a dict argument, which may be NULL indicating no dictionary. +/// See +/// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#frame-concatenation +static void decode_frame(ostream_t *const out, istream_t *const in, + const dictionary_t *const dict); + +// Decode data in a compressed block +static void decompress_block(frame_context_t *const ctx, ostream_t *const out, + istream_t *const in); + +// Decode the literals section of a block +static size_t decode_literals(frame_context_t *const ctx, istream_t *const in, + u8 **const literals); + +// Decode the sequences part of a block +static size_t decode_sequences(frame_context_t *const ctx, istream_t *const in, + sequence_command_t **const sequences); + +// Execute the decoded sequences on the literals block +static void execute_sequences(frame_context_t *const ctx, ostream_t *const out, + const u8 *const literals, + const size_t literals_len, + const sequence_command_t *const sequences, + const size_t num_sequences); + +// Copies literals and returns the total literal length that was copied +static u32 copy_literals(const size_t seq, istream_t *litstream, + ostream_t *const out); + +// Given an offset code from a sequence command (either an actual offset value +// or an index for previous offset), computes the correct offset and updates +// the offset history +static size_t compute_offset(sequence_command_t seq, u64 *const offset_hist); + +// Given an offset, match length, and total output, as well as the frame +// context for the dictionary, determines if the dictionary is used and +// executes the copy operation +static void execute_match_copy(frame_context_t *const ctx, size_t offset, + size_t match_length, size_t total_output, + ostream_t *const out); + +/******* END ZSTD HELPER STRUCTS AND PROTOTYPES *******************************/ + +size_t ZSTD_decompress(void *const dst, const size_t dst_len, + const void *const src, const size_t src_len) { + dictionary_t* const uninit_dict = create_dictionary(); + size_t const decomp_size = ZSTD_decompress_with_dict(dst, dst_len, src, + src_len, uninit_dict); + free_dictionary(uninit_dict); + return decomp_size; +} + +size_t ZSTD_decompress_with_dict(void *const dst, const size_t dst_len, + const void *const src, const size_t src_len, + dictionary_t* parsed_dict) { + + istream_t in = IO_make_istream(src, src_len); + ostream_t out = IO_make_ostream(dst, dst_len); + + // "A content compressed by Zstandard is transformed into a Zstandard frame. + // Multiple frames can be appended into a single file or stream. A frame is + // totally independent, has a defined beginning and end, and a set of + // parameters which tells the decoder how to decompress it." + + /* this decoder assumes decompression of a single frame */ + decode_frame(&out, &in, parsed_dict); + + return (size_t)(out.ptr - (u8 *)dst); +} + +/******* FRAME DECODING ******************************************************/ + +static void decode_data_frame(ostream_t *const out, istream_t *const in, + const dictionary_t *const dict); +static void init_frame_context(frame_context_t *const context, + istream_t *const in, + const dictionary_t *const dict); +static void free_frame_context(frame_context_t *const context); +static void parse_frame_header(frame_header_t *const header, + istream_t *const in); +static void frame_context_apply_dict(frame_context_t *const ctx, + const dictionary_t *const dict); + +static void decompress_data(frame_context_t *const ctx, ostream_t *const out, + istream_t *const in); + +static void decode_frame(ostream_t *const out, istream_t *const in, + const dictionary_t *const dict) { + const u32 magic_number = (u32)IO_read_bits(in, 32); + if (magic_number == ZSTD_MAGIC_NUMBER) { + // ZSTD frame + decode_data_frame(out, in, dict); + + return; + } + + // not a real frame or a skippable frame + ERROR("Tried to decode non-ZSTD frame"); +} + +/// Decode a frame that contains compressed data. Not all frames do as there +/// are skippable frames. +/// See +/// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#general-structure-of-zstandard-frame-format +static void decode_data_frame(ostream_t *const out, istream_t *const in, + const dictionary_t *const dict) { + frame_context_t ctx; + + // Initialize the context that needs to be carried from block to block + init_frame_context(&ctx, in, dict); + + if (ctx.header.frame_content_size != 0 && + ctx.header.frame_content_size > out->len) { + OUT_SIZE(); + } + + decompress_data(&ctx, out, in); + + free_frame_context(&ctx); +} + +/// Takes the information provided in the header and dictionary, and initializes +/// the context for this frame +static void init_frame_context(frame_context_t *const context, + istream_t *const in, + const dictionary_t *const dict) { + // Most fields in context are correct when initialized to 0 + memset(context, 0, sizeof(frame_context_t)); + + // Parse data from the frame header + parse_frame_header(&context->header, in); + + // Set up the offset history for the repeat offset commands + context->previous_offsets[0] = 1; + context->previous_offsets[1] = 4; + context->previous_offsets[2] = 8; + + // Apply details from the dict if it exists + frame_context_apply_dict(context, dict); +} + +static void free_frame_context(frame_context_t *const context) { + HUF_free_dtable(&context->literals_dtable); + + FSE_free_dtable(&context->ll_dtable); + FSE_free_dtable(&context->ml_dtable); + FSE_free_dtable(&context->of_dtable); + + memset(context, 0, sizeof(frame_context_t)); +} + +static void parse_frame_header(frame_header_t *const header, + istream_t *const in) { + // "The first header's byte is called the Frame_Header_Descriptor. It tells + // which other fields are present. Decoding this byte is enough to tell the + // size of Frame_Header. + // + // Bit number Field name + // 7-6 Frame_Content_Size_flag + // 5 Single_Segment_flag + // 4 Unused_bit + // 3 Reserved_bit + // 2 Content_Checksum_flag + // 1-0 Dictionary_ID_flag" + const u8 descriptor = (u8)IO_read_bits(in, 8); + + // decode frame header descriptor into flags + const u8 frame_content_size_flag = descriptor >> 6; + const u8 single_segment_flag = (descriptor >> 5) & 1; + const u8 reserved_bit = (descriptor >> 3) & 1; + const u8 content_checksum_flag = (descriptor >> 2) & 1; + const u8 dictionary_id_flag = descriptor & 3; + + if (reserved_bit != 0) { + CORRUPTION(); + } + + header->single_segment_flag = single_segment_flag; + header->content_checksum_flag = content_checksum_flag; + + // decode window size + if (!single_segment_flag) { + // "Provides guarantees on maximum back-reference distance that will be + // used within compressed data. This information is important for + // decoders to allocate enough memory. + // + // Bit numbers 7-3 2-0 + // Field name Exponent Mantissa" + u8 window_descriptor = (u8)IO_read_bits(in, 8); + u8 exponent = window_descriptor >> 3; + u8 mantissa = window_descriptor & 7; + + // Use the algorithm from the specification to compute window size + // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor + size_t window_base = (size_t)1 << (10 + exponent); + size_t window_add = (window_base / 8) * mantissa; + header->window_size = window_base + window_add; + } + + // decode dictionary id if it exists + if (dictionary_id_flag) { + // "This is a variable size field, which contains the ID of the + // dictionary required to properly decode the frame. Note that this + // field is optional. When it's not present, it's up to the caller to + // make sure it uses the correct dictionary. Format is little-endian." + const int bytes_array[] = {0, 1, 2, 4}; + const int bytes = bytes_array[dictionary_id_flag]; + + header->dictionary_id = (u32)IO_read_bits(in, bytes * 8); + } else { + header->dictionary_id = 0; + } + + // decode frame content size if it exists + if (single_segment_flag || frame_content_size_flag) { + // "This is the original (uncompressed) size. This information is + // optional. The Field_Size is provided according to value of + // Frame_Content_Size_flag. The Field_Size can be equal to 0 (not + // present), 1, 2, 4 or 8 bytes. Format is little-endian." + // + // if frame_content_size_flag == 0 but single_segment_flag is set, we + // still have a 1 byte field + const int bytes_array[] = {1, 2, 4, 8}; + const int bytes = bytes_array[frame_content_size_flag]; + + header->frame_content_size = IO_read_bits(in, bytes * 8); + if (bytes == 2) { + // "When Field_Size is 2, the offset of 256 is added." + header->frame_content_size += 256; + } + } else { + header->frame_content_size = 0; + } + + if (single_segment_flag) { + // "The Window_Descriptor byte is optional. It is absent when + // Single_Segment_flag is set. In this case, the maximum back-reference + // distance is the content size itself, which can be any value from 1 to + // 2^64-1 bytes (16 EB)." + header->window_size = header->frame_content_size; + } +} + +/// Decompress the data from a frame block by block +static void decompress_data(frame_context_t *const ctx, ostream_t *const out, + istream_t *const in) { + // "A frame encapsulates one or multiple blocks. Each block can be + // compressed or not, and has a guaranteed maximum content size, which + // depends on frame parameters. Unlike frames, each block depends on + // previous blocks for proper decoding. However, each block can be + // decompressed without waiting for its successor, allowing streaming + // operations." + int last_block = 0; + do { + // "Last_Block + // + // The lowest bit signals if this block is the last one. Frame ends + // right after this block. + // + // Block_Type and Block_Size + // + // The next 2 bits represent the Block_Type, while the remaining 21 bits + // represent the Block_Size. Format is little-endian." + last_block = (int)IO_read_bits(in, 1); + const int block_type = (int)IO_read_bits(in, 2); + const size_t block_len = IO_read_bits(in, 21); + + switch (block_type) { + case 0: { + // "Raw_Block - this is an uncompressed block. Block_Size is the + // number of bytes to read and copy." + const u8 *const read_ptr = IO_get_read_ptr(in, block_len); + u8 *const write_ptr = IO_get_write_ptr(out, block_len); + + // Copy the raw data into the output + memcpy(write_ptr, read_ptr, block_len); + + ctx->current_total_output += block_len; + break; + } + case 1: { + // "RLE_Block - this is a single byte, repeated N times. In which + // case, Block_Size is the size to regenerate, while the + // "compressed" block is just 1 byte (the byte to repeat)." + const u8 *const read_ptr = IO_get_read_ptr(in, 1); + u8 *const write_ptr = IO_get_write_ptr(out, block_len); + + // Copy `block_len` copies of `read_ptr[0]` to the output + memset(write_ptr, read_ptr[0], block_len); + + ctx->current_total_output += block_len; + break; + } + case 2: { + // "Compressed_Block - this is a Zstandard compressed block, + // detailed in another section of this specification. Block_Size is + // the compressed size. + + // Create a sub-stream for the block + istream_t block_stream = IO_make_sub_istream(in, block_len); + decompress_block(ctx, out, &block_stream); + break; + } + case 3: + // "Reserved - this is not a block. This value cannot be used with + // current version of this specification." + CORRUPTION(); + break; + default: + IMPOSSIBLE(); + } + } while (!last_block); + + if (ctx->header.content_checksum_flag) { + // This program does not support checking the checksum, so skip over it + // if it's present + IO_advance_input(in, 4); + } +} +/******* END FRAME DECODING ***************************************************/ + +/******* BLOCK DECOMPRESSION **************************************************/ +static void decompress_block(frame_context_t *const ctx, ostream_t *const out, + istream_t *const in) { + // "A compressed block consists of 2 sections : + // + // Literals_Section + // Sequences_Section" + + + // Part 1: decode the literals block + u8 *literals = NULL; + const size_t literals_size = decode_literals(ctx, in, &literals); + + // Part 2: decode the sequences block + sequence_command_t *sequences = NULL; + const size_t num_sequences = + decode_sequences(ctx, in, &sequences); + + // Part 3: combine literals and sequence commands to generate output + execute_sequences(ctx, out, literals, literals_size, sequences, + num_sequences); + free(literals); + free(sequences); +} +/******* END BLOCK DECOMPRESSION **********************************************/ + +/******* LITERALS DECODING ****************************************************/ +static size_t decode_literals_simple(istream_t *const in, u8 **const literals, + const int block_type, + const int size_format); +static size_t decode_literals_compressed(frame_context_t *const ctx, + istream_t *const in, + u8 **const literals, + const int block_type, + const int size_format); +static void decode_huf_table(HUF_dtable *const dtable, istream_t *const in); +static void fse_decode_hufweights(ostream_t *weights, istream_t *const in, + int *const num_symbs); + +static size_t decode_literals(frame_context_t *const ctx, istream_t *const in, + u8 **const literals) { + // "Literals can be stored uncompressed or compressed using Huffman prefix + // codes. When compressed, an optional tree description can be present, + // followed by 1 or 4 streams." + // + // "Literals_Section_Header + // + // Header is in charge of describing how literals are packed. It's a + // byte-aligned variable-size bitfield, ranging from 1 to 5 bytes, using + // little-endian convention." + // + // "Literals_Block_Type + // + // This field uses 2 lowest bits of first byte, describing 4 different block + // types" + // + // size_format takes between 1 and 2 bits + int block_type = (int)IO_read_bits(in, 2); + int size_format = (int)IO_read_bits(in, 2); + + if (block_type <= 1) { + // Raw or RLE literals block + return decode_literals_simple(in, literals, block_type, + size_format); + } else { + // Huffman compressed literals + return decode_literals_compressed(ctx, in, literals, block_type, + size_format); + } +} + +/// Decodes literals blocks in raw or RLE form +static size_t decode_literals_simple(istream_t *const in, u8 **const literals, + const int block_type, + const int size_format) { + size_t size; + switch (size_format) { + // These cases are in the form ?0 + // In this case, the ? bit is actually part of the size field + case 0: + case 2: + // "Size_Format uses 1 bit. Regenerated_Size uses 5 bits (0-31)." + IO_rewind_bits(in, 1); + size = IO_read_bits(in, 5); + break; + case 1: + // "Size_Format uses 2 bits. Regenerated_Size uses 12 bits (0-4095)." + size = IO_read_bits(in, 12); + break; + case 3: + // "Size_Format uses 2 bits. Regenerated_Size uses 20 bits (0-1048575)." + size = IO_read_bits(in, 20); + break; + default: + // Size format is in range 0-3 + IMPOSSIBLE(); + } + + if (size > MAX_LITERALS_SIZE) { + CORRUPTION(); + } + + *literals = malloc(size); + if (!*literals) { + BAD_ALLOC(); + } + + switch (block_type) { + case 0: { + // "Raw_Literals_Block - Literals are stored uncompressed." + const u8 *const read_ptr = IO_get_read_ptr(in, size); + memcpy(*literals, read_ptr, size); + break; + } + case 1: { + // "RLE_Literals_Block - Literals consist of a single byte value repeated N times." + const u8 *const read_ptr = IO_get_read_ptr(in, 1); + memset(*literals, read_ptr[0], size); + break; + } + default: + IMPOSSIBLE(); + } + + return size; +} + +/// Decodes Huffman compressed literals +static size_t decode_literals_compressed(frame_context_t *const ctx, + istream_t *const in, + u8 **const literals, + const int block_type, + const int size_format) { + size_t regenerated_size, compressed_size; + // Only size_format=0 has 1 stream, so default to 4 + int num_streams = 4; + switch (size_format) { + case 0: + // "A single stream. Both Compressed_Size and Regenerated_Size use 10 + // bits (0-1023)." + num_streams = 1; + // Fall through as it has the same size format + /* fallthrough */ + case 1: + // "4 streams. Both Compressed_Size and Regenerated_Size use 10 bits + // (0-1023)." + regenerated_size = IO_read_bits(in, 10); + compressed_size = IO_read_bits(in, 10); + break; + case 2: + // "4 streams. Both Compressed_Size and Regenerated_Size use 14 bits + // (0-16383)." + regenerated_size = IO_read_bits(in, 14); + compressed_size = IO_read_bits(in, 14); + break; + case 3: + // "4 streams. Both Compressed_Size and Regenerated_Size use 18 bits + // (0-262143)." + regenerated_size = IO_read_bits(in, 18); + compressed_size = IO_read_bits(in, 18); + break; + default: + // Impossible + IMPOSSIBLE(); + } + if (regenerated_size > MAX_LITERALS_SIZE) { + CORRUPTION(); + } + + *literals = malloc(regenerated_size); + if (!*literals) { + BAD_ALLOC(); + } + + ostream_t lit_stream = IO_make_ostream(*literals, regenerated_size); + istream_t huf_stream = IO_make_sub_istream(in, compressed_size); + + if (block_type == 2) { + // Decode the provided Huffman table + // "This section is only present when Literals_Block_Type type is + // Compressed_Literals_Block (2)." + + HUF_free_dtable(&ctx->literals_dtable); + decode_huf_table(&ctx->literals_dtable, &huf_stream); + } else { + // If the previous Huffman table is being repeated, ensure it exists + if (!ctx->literals_dtable.symbols) { + CORRUPTION(); + } + } + + size_t symbols_decoded; + if (num_streams == 1) { + symbols_decoded = HUF_decompress_1stream(&ctx->literals_dtable, &lit_stream, &huf_stream); + } else { + symbols_decoded = HUF_decompress_4stream(&ctx->literals_dtable, &lit_stream, &huf_stream); + } + + if (symbols_decoded != regenerated_size) { + CORRUPTION(); + } + + return regenerated_size; +} + +// Decode the Huffman table description +static void decode_huf_table(HUF_dtable *const dtable, istream_t *const in) { + // "All literal values from zero (included) to last present one (excluded) + // are represented by Weight with values from 0 to Max_Number_of_Bits." + + // "This is a single byte value (0-255), which describes how to decode the list of weights." + const u8 header = IO_read_bits(in, 8); + + u8 weights[HUF_MAX_SYMBS]; + memset(weights, 0, sizeof(weights)); + + int num_symbs; + + if (header >= 128) { + // "This is a direct representation, where each Weight is written + // directly as a 4 bits field (0-15). The full representation occupies + // ((Number_of_Symbols+1)/2) bytes, meaning it uses a last full byte + // even if Number_of_Symbols is odd. Number_of_Symbols = headerByte - + // 127" + num_symbs = header - 127; + const size_t bytes = (num_symbs + 1) / 2; + + const u8 *const weight_src = IO_get_read_ptr(in, bytes); + + for (int i = 0; i < num_symbs; i++) { + // "They are encoded forward, 2 + // weights to a byte with the first weight taking the top four bits + // and the second taking the bottom four (e.g. the following + // operations could be used to read the weights: Weight[0] = + // (Byte[0] >> 4), Weight[1] = (Byte[0] & 0xf), etc.)." + if (i % 2 == 0) { + weights[i] = weight_src[i / 2] >> 4; + } else { + weights[i] = weight_src[i / 2] & 0xf; + } + } + } else { + // The weights are FSE encoded, decode them before we can construct the + // table + istream_t fse_stream = IO_make_sub_istream(in, header); + ostream_t weight_stream = IO_make_ostream(weights, HUF_MAX_SYMBS); + fse_decode_hufweights(&weight_stream, &fse_stream, &num_symbs); + } + + // Construct the table using the decoded weights + HUF_init_dtable_usingweights(dtable, weights, num_symbs); +} + +static void fse_decode_hufweights(ostream_t *weights, istream_t *const in, + int *const num_symbs) { + const int MAX_ACCURACY_LOG = 7; + + FSE_dtable dtable; + + // "An FSE bitstream starts by a header, describing probabilities + // distribution. It will create a Decoding Table. For a list of Huffman + // weights, maximum accuracy is 7 bits." + FSE_decode_header(&dtable, in, MAX_ACCURACY_LOG); + + // Decode the weights + *num_symbs = FSE_decompress_interleaved2(&dtable, weights, in); + + FSE_free_dtable(&dtable); +} +/******* END LITERALS DECODING ************************************************/ + +/******* SEQUENCE DECODING ****************************************************/ +/// The combination of FSE states needed to decode sequences +typedef struct { + FSE_dtable ll_table; + FSE_dtable of_table; + FSE_dtable ml_table; + + u16 ll_state; + u16 of_state; + u16 ml_state; +} sequence_states_t; + +/// Different modes to signal to decode_seq_tables what to do +typedef enum { + seq_literal_length = 0, + seq_offset = 1, + seq_match_length = 2, +} seq_part_t; + +typedef enum { + seq_predefined = 0, + seq_rle = 1, + seq_fse = 2, + seq_repeat = 3, +} seq_mode_t; + +/// The predefined FSE distribution tables for `seq_predefined` mode +static const i16 SEQ_LITERAL_LENGTH_DEFAULT_DIST[36] = { + 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, -1, -1, -1, -1}; +static const i16 SEQ_OFFSET_DEFAULT_DIST[29] = { + 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1}; +static const i16 SEQ_MATCH_LENGTH_DEFAULT_DIST[53] = { + 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1}; + +/// The sequence decoding baseline and number of additional bits to read/add +/// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#the-codes-for-literals-lengths-match-lengths-and-offsets +static const u32 SEQ_LITERAL_LENGTH_BASELINES[36] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 18, 20, 22, 24, 28, 32, 40, + 48, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}; +static const u8 SEQ_LITERAL_LENGTH_EXTRA_BITS[36] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + +static const u32 SEQ_MATCH_LENGTH_BASELINES[53] = { + 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, 37, 39, 41, 43, 47, 51, 59, 67, 83, + 99, 131, 259, 515, 1027, 2051, 4099, 8195, 16387, 32771, 65539}; +static const u8 SEQ_MATCH_LENGTH_EXTRA_BITS[53] = { + 0, 0, 0, 0, 0, 0, 0, 0, 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, + 2, 2, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + +/// Offset decoding is simpler so we just need a maximum code value +static const u8 SEQ_MAX_CODES[3] = {35, (u8)-1, 52}; + +static void decompress_sequences(frame_context_t *const ctx, + istream_t *const in, + sequence_command_t *const sequences, + const size_t num_sequences); +static sequence_command_t decode_sequence(sequence_states_t *const state, + const u8 *const src, + i64 *const offset, + int lastSequence); +static void decode_seq_table(FSE_dtable *const table, istream_t *const in, + const seq_part_t type, const seq_mode_t mode); + +static size_t decode_sequences(frame_context_t *const ctx, istream_t *in, + sequence_command_t **const sequences) { + // "A compressed block is a succession of sequences . A sequence is a + // literal copy command, followed by a match copy command. A literal copy + // command specifies a length. It is the number of bytes to be copied (or + // extracted) from the literal section. A match copy command specifies an + // offset and a length. The offset gives the position to copy from, which + // can be within a previous block." + + size_t num_sequences; + + // "Number_of_Sequences + // + // This is a variable size field using between 1 and 3 bytes. Let's call its + // first byte byte0." + u8 header = IO_read_bits(in, 8); + if (header < 128) { + // "Number_of_Sequences = byte0 . Uses 1 byte." + num_sequences = header; + } else if (header < 255) { + // "Number_of_Sequences = ((byte0-128) << 8) + byte1 . Uses 2 bytes." + num_sequences = ((header - 128) << 8) + IO_read_bits(in, 8); + } else { + // "Number_of_Sequences = byte1 + (byte2<<8) + 0x7F00 . Uses 3 bytes." + num_sequences = IO_read_bits(in, 16) + 0x7F00; + } + + if (num_sequences == 0) { + // "There are no sequences. The sequence section stops there." + *sequences = NULL; + return 0; + } + + *sequences = malloc(num_sequences * sizeof(sequence_command_t)); + if (!*sequences) { + BAD_ALLOC(); + } + + decompress_sequences(ctx, in, *sequences, num_sequences); + return num_sequences; +} + +/// Decompress the FSE encoded sequence commands +static void decompress_sequences(frame_context_t *const ctx, istream_t *in, + sequence_command_t *const sequences, + const size_t num_sequences) { + // "The Sequences_Section regroup all symbols required to decode commands. + // There are 3 symbol types : literals lengths, offsets and match lengths. + // They are encoded together, interleaved, in a single bitstream." + + // "Symbol compression modes + // + // This is a single byte, defining the compression mode of each symbol + // type." + // + // Bit number : Field name + // 7-6 : Literals_Lengths_Mode + // 5-4 : Offsets_Mode + // 3-2 : Match_Lengths_Mode + // 1-0 : Reserved + u8 compression_modes = IO_read_bits(in, 8); + + if ((compression_modes & 3) != 0) { + // Reserved bits set + CORRUPTION(); + } + + // "Following the header, up to 3 distribution tables can be described. When + // present, they are in this order : + // + // Literals lengths + // Offsets + // Match Lengths" + // Update the tables we have stored in the context + decode_seq_table(&ctx->ll_dtable, in, seq_literal_length, + (compression_modes >> 6) & 3); + + decode_seq_table(&ctx->of_dtable, in, seq_offset, + (compression_modes >> 4) & 3); + + decode_seq_table(&ctx->ml_dtable, in, seq_match_length, + (compression_modes >> 2) & 3); + + + sequence_states_t states; + + // Initialize the decoding tables + { + states.ll_table = ctx->ll_dtable; + states.of_table = ctx->of_dtable; + states.ml_table = ctx->ml_dtable; + } + + const size_t len = IO_istream_len(in); + const u8 *const src = IO_get_read_ptr(in, len); + + // "After writing the last bit containing information, the compressor writes + // a single 1-bit and then fills the byte with 0-7 0 bits of padding." + const int padding = 8 - highest_set_bit(src[len - 1]); + // The offset starts at the end because FSE streams are read backwards + i64 bit_offset = (i64)(len * 8 - (size_t)padding); + + // "The bitstream starts with initial state values, each using the required + // number of bits in their respective accuracy, decoded previously from + // their normalized distribution. + // + // It starts by Literals_Length_State, followed by Offset_State, and finally + // Match_Length_State." + FSE_init_state(&states.ll_table, &states.ll_state, src, &bit_offset); + FSE_init_state(&states.of_table, &states.of_state, src, &bit_offset); + FSE_init_state(&states.ml_table, &states.ml_state, src, &bit_offset); + + for (size_t i = 0; i < num_sequences; i++) { + // Decode sequences one by one + sequences[i] = decode_sequence(&states, src, &bit_offset, i==num_sequences-1); + } + + if (bit_offset != 0) { + CORRUPTION(); + } +} + +// Decode a single sequence and update the state +static sequence_command_t decode_sequence(sequence_states_t *const states, + const u8 *const src, + i64 *const offset, + int lastSequence) { + // "Each symbol is a code in its own context, which specifies Baseline and + // Number_of_Bits to add. Codes are FSE compressed, and interleaved with raw + // additional bits in the same bitstream." + + // Decode symbols, but don't update states + const u8 of_code = FSE_peek_symbol(&states->of_table, states->of_state); + const u8 ll_code = FSE_peek_symbol(&states->ll_table, states->ll_state); + const u8 ml_code = FSE_peek_symbol(&states->ml_table, states->ml_state); + + // Offset doesn't need a max value as it's not decoded using a table + if (ll_code > SEQ_MAX_CODES[seq_literal_length] || + ml_code > SEQ_MAX_CODES[seq_match_length]) { + CORRUPTION(); + } + + // Read the interleaved bits + sequence_command_t seq; + // "Decoding starts by reading the Number_of_Bits required to decode Offset. + // It then does the same for Match_Length, and then for Literals_Length." + seq.offset = ((u32)1 << of_code) + STREAM_read_bits(src, of_code, offset); + + seq.match_length = + SEQ_MATCH_LENGTH_BASELINES[ml_code] + + STREAM_read_bits(src, SEQ_MATCH_LENGTH_EXTRA_BITS[ml_code], offset); + + seq.literal_length = + SEQ_LITERAL_LENGTH_BASELINES[ll_code] + + STREAM_read_bits(src, SEQ_LITERAL_LENGTH_EXTRA_BITS[ll_code], offset); + + // "If it is not the last sequence in the block, the next operation is to + // update states. Using the rules pre-calculated in the decoding tables, + // Literals_Length_State is updated, followed by Match_Length_State, and + // then Offset_State." + // If the stream is complete don't read bits to update state + if (!lastSequence) { + FSE_update_state(&states->ll_table, &states->ll_state, src, offset); + FSE_update_state(&states->ml_table, &states->ml_state, src, offset); + FSE_update_state(&states->of_table, &states->of_state, src, offset); + } + + return seq; +} + +/// Given a sequence part and table mode, decode the FSE distribution +/// Errors if the mode is `seq_repeat` without a pre-existing table in `table` +static void decode_seq_table(FSE_dtable *const table, istream_t *const in, + const seq_part_t type, const seq_mode_t mode) { + // Constant arrays indexed by seq_part_t + const i16 *const default_distributions[] = {SEQ_LITERAL_LENGTH_DEFAULT_DIST, + SEQ_OFFSET_DEFAULT_DIST, + SEQ_MATCH_LENGTH_DEFAULT_DIST}; + const size_t default_distribution_lengths[] = {36, 29, 53}; + const size_t default_distribution_accuracies[] = {6, 5, 6}; + + const size_t max_accuracies[] = {9, 8, 9}; + + if (mode != seq_repeat) { + // Free old one before overwriting + FSE_free_dtable(table); + } + + switch (mode) { + case seq_predefined: { + // "Predefined_Mode : uses a predefined distribution table." + const i16 *distribution = default_distributions[type]; + const size_t symbs = default_distribution_lengths[type]; + const size_t accuracy_log = default_distribution_accuracies[type]; + + FSE_init_dtable(table, distribution, symbs, accuracy_log); + break; + } + case seq_rle: { + // "RLE_Mode : it's a single code, repeated Number_of_Sequences times." + const u8 symb = IO_get_read_ptr(in, 1)[0]; + FSE_init_dtable_rle(table, symb); + break; + } + case seq_fse: { + // "FSE_Compressed_Mode : standard FSE compression. A distribution table + // will be present " + FSE_decode_header(table, in, max_accuracies[type]); + break; + } + case seq_repeat: + // "Repeat_Mode : reuse distribution table from previous compressed + // block." + // Nothing to do here, table will be unchanged + if (!table->symbols) { + // This mode is invalid if we don't already have a table + CORRUPTION(); + } + break; + default: + // Impossible, as mode is from 0-3 + IMPOSSIBLE(); + break; + } + +} +/******* END SEQUENCE DECODING ************************************************/ + +/******* SEQUENCE EXECUTION ***************************************************/ +static void execute_sequences(frame_context_t *const ctx, ostream_t *const out, + const u8 *const literals, + const size_t literals_len, + const sequence_command_t *const sequences, + const size_t num_sequences) { + istream_t litstream = IO_make_istream(literals, literals_len); + + u64 *const offset_hist = ctx->previous_offsets; + size_t total_output = ctx->current_total_output; + + for (size_t i = 0; i < num_sequences; i++) { + const sequence_command_t seq = sequences[i]; + { + const u32 literals_size = copy_literals(seq.literal_length, &litstream, out); + total_output += literals_size; + } + + size_t const offset = compute_offset(seq, offset_hist); + + size_t const match_length = seq.match_length; + + execute_match_copy(ctx, offset, match_length, total_output, out); + + total_output += match_length; + } + + // Copy any leftover literals + { + size_t len = IO_istream_len(&litstream); + copy_literals(len, &litstream, out); + total_output += len; + } + + ctx->current_total_output = total_output; +} + +static u32 copy_literals(const size_t literal_length, istream_t *litstream, + ostream_t *const out) { + // If the sequence asks for more literals than are left, the + // sequence must be corrupted + if (literal_length > IO_istream_len(litstream)) { + CORRUPTION(); + } + + u8 *const write_ptr = IO_get_write_ptr(out, literal_length); + const u8 *const read_ptr = + IO_get_read_ptr(litstream, literal_length); + // Copy literals to output + memcpy(write_ptr, read_ptr, literal_length); + + return literal_length; +} + +static size_t compute_offset(sequence_command_t seq, u64 *const offset_hist) { + size_t offset; + // Offsets are special, we need to handle the repeat offsets + if (seq.offset <= 3) { + // "The first 3 values define a repeated offset and we will call + // them Repeated_Offset1, Repeated_Offset2, and Repeated_Offset3. + // They are sorted in recency order, with Repeated_Offset1 meaning + // 'most recent one'". + + // Use 0 indexing for the array + u32 idx = seq.offset - 1; + if (seq.literal_length == 0) { + // "There is an exception though, when current sequence's + // literals length is 0. In this case, repeated offsets are + // shifted by one, so Repeated_Offset1 becomes Repeated_Offset2, + // Repeated_Offset2 becomes Repeated_Offset3, and + // Repeated_Offset3 becomes Repeated_Offset1 - 1_byte." + idx++; + } + + if (idx == 0) { + offset = offset_hist[0]; + } else { + // If idx == 3 then literal length was 0 and the offset was 3, + // as per the exception listed above + offset = idx < 3 ? offset_hist[idx] : offset_hist[0] - 1; + + // If idx == 1 we don't need to modify offset_hist[2], since + // we're using the second-most recent code + if (idx > 1) { + offset_hist[2] = offset_hist[1]; + } + offset_hist[1] = offset_hist[0]; + offset_hist[0] = offset; + } + } else { + // When it's not a repeat offset: + // "if (Offset_Value > 3) offset = Offset_Value - 3;" + offset = seq.offset - 3; + + // Shift back history + offset_hist[2] = offset_hist[1]; + offset_hist[1] = offset_hist[0]; + offset_hist[0] = offset; + } + return offset; +} + +static void execute_match_copy(frame_context_t *const ctx, size_t offset, + size_t match_length, size_t total_output, + ostream_t *const out) { + u8 *write_ptr = IO_get_write_ptr(out, match_length); + if (total_output <= ctx->header.window_size) { + // In this case offset might go back into the dictionary + if (offset > total_output + ctx->dict_content_len) { + // The offset goes beyond even the dictionary + CORRUPTION(); + } + + if (offset > total_output) { + // "The rest of the dictionary is its content. The content act + // as a "past" in front of data to compress or decompress, so it + // can be referenced in sequence commands." + const size_t dict_copy = + MIN(offset - total_output, match_length); + const size_t dict_offset = + ctx->dict_content_len - (offset - total_output); + + memcpy(write_ptr, ctx->dict_content + dict_offset, dict_copy); + write_ptr += dict_copy; + match_length -= dict_copy; + } + } else if (offset > ctx->header.window_size) { + CORRUPTION(); + } + + // We must copy byte by byte because the match length might be larger + // than the offset + // ex: if the output so far was "abc", a command with offset=3 and + // match_length=6 would produce "abcabcabc" as the new output + for (size_t j = 0; j < match_length; j++) { + *write_ptr = *(write_ptr - offset); + write_ptr++; + } +} +/******* END SEQUENCE EXECUTION ***********************************************/ + +/******* OUTPUT SIZE COUNTING *************************************************/ +/// Get the decompressed size of an input stream so memory can be allocated in +/// advance. +/// This implementation assumes `src` points to a single ZSTD-compressed frame +size_t ZSTD_get_decompressed_size(const void *src, const size_t src_len) { + istream_t in = IO_make_istream(src, src_len); + + // get decompressed size from ZSTD frame header + { + const u32 magic_number = (u32)IO_read_bits(&in, 32); + + if (magic_number == ZSTD_MAGIC_NUMBER) { + // ZSTD frame + frame_header_t header; + parse_frame_header(&header, &in); + + if (header.frame_content_size == 0 && !header.single_segment_flag) { + // Content size not provided, we can't tell + return (size_t)-1; + } + + return header.frame_content_size; + } else { + // not a real frame or skippable frame + ERROR("ZSTD frame magic number did not match"); + } + } +} +/******* END OUTPUT SIZE COUNTING *********************************************/ + +/******* DICTIONARY PARSING ***************************************************/ +dictionary_t* create_dictionary(void) { + dictionary_t* const dict = calloc(1, sizeof(dictionary_t)); + if (!dict) { + BAD_ALLOC(); + } + return dict; +} + +/// Free an allocated dictionary +void free_dictionary(dictionary_t *const dict) { + HUF_free_dtable(&dict->literals_dtable); + FSE_free_dtable(&dict->ll_dtable); + FSE_free_dtable(&dict->of_dtable); + FSE_free_dtable(&dict->ml_dtable); + + free(dict->content); + + memset(dict, 0, sizeof(dictionary_t)); + + free(dict); +} + + +#if !defined(ZDEC_NO_DICTIONARY) +#define DICT_SIZE_ERROR() ERROR("Dictionary size cannot be less than 8 bytes") +#define NULL_SRC() ERROR("Tried to create dictionary with pointer to null src"); + +static void init_dictionary_content(dictionary_t *const dict, + istream_t *const in); + +void parse_dictionary(dictionary_t *const dict, const void *src, + size_t src_len) { + const u8 *byte_src = (const u8 *)src; + memset(dict, 0, sizeof(dictionary_t)); + if (src == NULL) { /* cannot initialize dictionary with null src */ + NULL_SRC(); + } + if (src_len < 8) { + DICT_SIZE_ERROR(); + } + + istream_t in = IO_make_istream(byte_src, src_len); + + const u32 magic_number = IO_read_bits(&in, 32); + if (magic_number != 0xEC30A437) { + // raw content dict + IO_rewind_bits(&in, 32); + init_dictionary_content(dict, &in); + return; + } + + dict->dictionary_id = IO_read_bits(&in, 32); + + // "Entropy_Tables : following the same format as the tables in compressed + // blocks. They are stored in following order : Huffman tables for literals, + // FSE table for offsets, FSE table for match lengths, and FSE table for + // literals lengths. It's finally followed by 3 offset values, populating + // recent offsets (instead of using {1,4,8}), stored in order, 4-bytes + // little-endian each, for a total of 12 bytes. Each recent offset must have + // a value < dictionary size." + decode_huf_table(&dict->literals_dtable, &in); + decode_seq_table(&dict->of_dtable, &in, seq_offset, seq_fse); + decode_seq_table(&dict->ml_dtable, &in, seq_match_length, seq_fse); + decode_seq_table(&dict->ll_dtable, &in, seq_literal_length, seq_fse); + + // Read in the previous offset history + dict->previous_offsets[0] = IO_read_bits(&in, 32); + dict->previous_offsets[1] = IO_read_bits(&in, 32); + dict->previous_offsets[2] = IO_read_bits(&in, 32); + + // Ensure the provided offsets aren't too large + // "Each recent offset must have a value < dictionary size." + for (int i = 0; i < 3; i++) { + if (dict->previous_offsets[i] > src_len) { + ERROR("Dictionary corrupted"); + } + } + + // "Content : The rest of the dictionary is its content. The content act as + // a "past" in front of data to compress or decompress, so it can be + // referenced in sequence commands." + init_dictionary_content(dict, &in); +} + +static void init_dictionary_content(dictionary_t *const dict, + istream_t *const in) { + // Copy in the content + dict->content_size = IO_istream_len(in); + dict->content = malloc(dict->content_size); + if (!dict->content) { + BAD_ALLOC(); + } + + const u8 *const content = IO_get_read_ptr(in, dict->content_size); + + memcpy(dict->content, content, dict->content_size); +} + +static void HUF_copy_dtable(HUF_dtable *const dst, + const HUF_dtable *const src) { + if (src->max_bits == 0) { + memset(dst, 0, sizeof(HUF_dtable)); + return; + } + + const size_t size = (size_t)1 << src->max_bits; + dst->max_bits = src->max_bits; + + dst->symbols = malloc(size); + dst->num_bits = malloc(size); + if (!dst->symbols || !dst->num_bits) { + BAD_ALLOC(); + } + + memcpy(dst->symbols, src->symbols, size); + memcpy(dst->num_bits, src->num_bits, size); +} + +static void FSE_copy_dtable(FSE_dtable *const dst, const FSE_dtable *const src) { + if (src->accuracy_log == 0) { + memset(dst, 0, sizeof(FSE_dtable)); + return; + } + + size_t size = (size_t)1 << src->accuracy_log; + dst->accuracy_log = src->accuracy_log; + + dst->symbols = malloc(size); + dst->num_bits = malloc(size); + dst->new_state_base = malloc(size * sizeof(u16)); + if (!dst->symbols || !dst->num_bits || !dst->new_state_base) { + BAD_ALLOC(); + } + + memcpy(dst->symbols, src->symbols, size); + memcpy(dst->num_bits, src->num_bits, size); + memcpy(dst->new_state_base, src->new_state_base, size * sizeof(u16)); +} + +/// A dictionary acts as initializing values for the frame context before +/// decompression, so we implement it by applying it's predetermined +/// tables and content to the context before beginning decompression +static void frame_context_apply_dict(frame_context_t *const ctx, + const dictionary_t *const dict) { + // If the content pointer is NULL then it must be an empty dict + if (!dict || !dict->content) + return; + + // If the requested dictionary_id is non-zero, the correct dictionary must + // be present + if (ctx->header.dictionary_id != 0 && + ctx->header.dictionary_id != dict->dictionary_id) { + ERROR("Wrong dictionary provided"); + } + + // Copy the dict content to the context for references during sequence + // execution + ctx->dict_content = dict->content; + ctx->dict_content_len = dict->content_size; + + // If it's a formatted dict copy the precomputed tables in so they can + // be used in the table repeat modes + if (dict->dictionary_id != 0) { + // Deep copy the entropy tables so they can be freed independently of + // the dictionary struct + HUF_copy_dtable(&ctx->literals_dtable, &dict->literals_dtable); + FSE_copy_dtable(&ctx->ll_dtable, &dict->ll_dtable); + FSE_copy_dtable(&ctx->of_dtable, &dict->of_dtable); + FSE_copy_dtable(&ctx->ml_dtable, &dict->ml_dtable); + + // Copy the repeated offsets + memcpy(ctx->previous_offsets, dict->previous_offsets, + sizeof(ctx->previous_offsets)); + } +} + +#else // ZDEC_NO_DICTIONARY is defined + +static void frame_context_apply_dict(frame_context_t *const ctx, + const dictionary_t *const dict) { + (void)ctx; + if (dict && dict->content) ERROR("dictionary not supported"); +} + +#endif +/******* END DICTIONARY PARSING ***********************************************/ + +/******* IO STREAM OPERATIONS *************************************************/ + +/// Reads `num` bits from a bitstream, and updates the internal offset +static inline u64 IO_read_bits(istream_t *const in, const int num_bits) { + if (num_bits > 64 || num_bits <= 0) { + ERROR("Attempt to read an invalid number of bits"); + } + + const size_t bytes = (num_bits + in->bit_offset + 7) / 8; + const size_t full_bytes = (num_bits + in->bit_offset) / 8; + if (bytes > in->len) { + INP_SIZE(); + } + + const u64 result = read_bits_LE(in->ptr, num_bits, in->bit_offset); + + in->bit_offset = (num_bits + in->bit_offset) % 8; + in->ptr += full_bytes; + in->len -= full_bytes; + + return result; +} + +/// If a non-zero number of bits have been read from the current byte, advance +/// the offset to the next byte +static inline void IO_rewind_bits(istream_t *const in, int num_bits) { + if (num_bits < 0) { + ERROR("Attempting to rewind stream by a negative number of bits"); + } + + // move the offset back by `num_bits` bits + const int new_offset = in->bit_offset - num_bits; + // determine the number of whole bytes we have to rewind, rounding up to an + // integer number (e.g. if `new_offset == -5`, `bytes == 1`) + const i64 bytes = -(new_offset - 7) / 8; + + in->ptr -= bytes; + in->len += bytes; + // make sure the resulting `bit_offset` is positive, as mod in C does not + // convert numbers from negative to positive (e.g. -22 % 8 == -6) + in->bit_offset = ((new_offset % 8) + 8) % 8; +} + +/// If the remaining bits in a byte will be unused, advance to the end of the +/// byte +static inline void IO_align_stream(istream_t *const in) { + if (in->bit_offset != 0) { + if (in->len == 0) { + INP_SIZE(); + } + in->ptr++; + in->len--; + in->bit_offset = 0; + } +} + +/// Write the given byte into the output stream +static inline void IO_write_byte(ostream_t *const out, u8 symb) { + if (out->len == 0) { + OUT_SIZE(); + } + + out->ptr[0] = symb; + out->ptr++; + out->len--; +} + +/// Returns the number of bytes left to be read in this stream. The stream must +/// be byte aligned. +static inline size_t IO_istream_len(const istream_t *const in) { + return in->len; +} + +/// Returns a pointer where `len` bytes can be read, and advances the internal +/// state. The stream must be byte aligned. +static inline const u8 *IO_get_read_ptr(istream_t *const in, size_t len) { + if (len > in->len) { + INP_SIZE(); + } + if (in->bit_offset != 0) { + ERROR("Attempting to operate on a non-byte aligned stream"); + } + const u8 *const ptr = in->ptr; + in->ptr += len; + in->len -= len; + + return ptr; +} +/// Returns a pointer to write `len` bytes to, and advances the internal state +static inline u8 *IO_get_write_ptr(ostream_t *const out, size_t len) { + if (len > out->len) { + OUT_SIZE(); + } + u8 *const ptr = out->ptr; + out->ptr += len; + out->len -= len; + + return ptr; +} + +/// Advance the inner state by `len` bytes +static inline void IO_advance_input(istream_t *const in, size_t len) { + if (len > in->len) { + INP_SIZE(); + } + if (in->bit_offset != 0) { + ERROR("Attempting to operate on a non-byte aligned stream"); + } + + in->ptr += len; + in->len -= len; +} + +/// Returns an `ostream_t` constructed from the given pointer and length +static inline ostream_t IO_make_ostream(u8 *out, size_t len) { + return (ostream_t) { out, len }; +} + +/// Returns an `istream_t` constructed from the given pointer and length +static inline istream_t IO_make_istream(const u8 *in, size_t len) { + return (istream_t) { in, len, 0 }; +} + +/// Returns an `istream_t` with the same base as `in`, and length `len` +/// Then, advance `in` to account for the consumed bytes +/// `in` must be byte aligned +static inline istream_t IO_make_sub_istream(istream_t *const in, size_t len) { + // Consume `len` bytes of the parent stream + const u8 *const ptr = IO_get_read_ptr(in, len); + + // Make a substream using the pointer to those `len` bytes + return IO_make_istream(ptr, len); +} +/******* END IO STREAM OPERATIONS *********************************************/ + +/******* BITSTREAM OPERATIONS *************************************************/ +/// Read `num` bits (up to 64) from `src + offset`, where `offset` is in bits +static inline u64 read_bits_LE(const u8 *src, const int num_bits, + const size_t offset) { + if (num_bits > 64) { + ERROR("Attempt to read an invalid number of bits"); + } + + // Skip over bytes that aren't in range + src += offset / 8; + size_t bit_offset = offset % 8; + u64 res = 0; + + int shift = 0; + int left = num_bits; + while (left > 0) { + u64 mask = left >= 8 ? 0xff : (((u64)1 << left) - 1); + // Read the next byte, shift it to account for the offset, and then mask + // out the top part if we don't need all the bits + res += (((u64)*src++ >> bit_offset) & mask) << shift; + shift += 8 - bit_offset; + left -= 8 - bit_offset; + bit_offset = 0; + } + + return res; +} + +/// Read bits from the end of a HUF or FSE bitstream. `offset` is in bits, so +/// it updates `offset` to `offset - bits`, and then reads `bits` bits from +/// `src + offset`. If the offset becomes negative, the extra bits at the +/// bottom are filled in with `0` bits instead of reading from before `src`. +static inline u64 STREAM_read_bits(const u8 *const src, const int bits, + i64 *const offset) { + *offset = *offset - bits; + size_t actual_off = *offset; + size_t actual_bits = bits; + // Don't actually read bits from before the start of src, so if `*offset < + // 0` fix actual_off and actual_bits to reflect the quantity to read + if (*offset < 0) { + actual_bits += *offset; + actual_off = 0; + } + u64 res = read_bits_LE(src, actual_bits, actual_off); + + if (*offset < 0) { + // Fill in the bottom "overflowed" bits with 0's + res = -*offset >= 64 ? 0 : (res << -*offset); + } + return res; +} +/******* END BITSTREAM OPERATIONS *********************************************/ + +/******* BIT COUNTING OPERATIONS **********************************************/ +/// Returns `x`, where `2^x` is the largest power of 2 less than or equal to +/// `num`, or `-1` if `num == 0`. +static inline int highest_set_bit(const u64 num) { + for (int i = 63; i >= 0; i--) { + if (((u64)1 << i) <= num) { + return i; + } + } + return -1; +} +/******* END BIT COUNTING OPERATIONS ******************************************/ + +/******* HUFFMAN PRIMITIVES ***************************************************/ +static inline u8 HUF_decode_symbol(const HUF_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset) { + // Look up the symbol and number of bits to read + const u8 symb = dtable->symbols[*state]; + const u8 bits = dtable->num_bits[*state]; + const u16 rest = STREAM_read_bits(src, bits, offset); + // Shift `bits` bits out of the state, keeping the low order bits that + // weren't necessary to determine this symbol. Then add in the new bits + // read from the stream. + *state = ((*state << bits) + rest) & (((u16)1 << dtable->max_bits) - 1); + + return symb; +} + +static inline void HUF_init_state(const HUF_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset) { + // Read in a full `dtable->max_bits` bits to initialize the state + const u8 bits = dtable->max_bits; + *state = STREAM_read_bits(src, bits, offset); +} + +static size_t HUF_decompress_1stream(const HUF_dtable *const dtable, + ostream_t *const out, + istream_t *const in) { + const size_t len = IO_istream_len(in); + if (len == 0) { + INP_SIZE(); + } + const u8 *const src = IO_get_read_ptr(in, len); + + // "Each bitstream must be read backward, that is starting from the end down + // to the beginning. Therefore it's necessary to know the size of each + // bitstream. + // + // It's also necessary to know exactly which bit is the latest. This is + // detected by a final bit flag : the highest bit of latest byte is a + // final-bit-flag. Consequently, a last byte of 0 is not possible. And the + // final-bit-flag itself is not part of the useful bitstream. Hence, the + // last byte contains between 0 and 7 useful bits." + const int padding = 8 - highest_set_bit(src[len - 1]); + + // Offset starts at the end because HUF streams are read backwards + i64 bit_offset = len * 8 - padding; + u16 state; + + HUF_init_state(dtable, &state, src, &bit_offset); + + size_t symbols_written = 0; + while (bit_offset > -dtable->max_bits) { + // Iterate over the stream, decoding one symbol at a time + IO_write_byte(out, HUF_decode_symbol(dtable, &state, src, &bit_offset)); + symbols_written++; + } + // "The process continues up to reading the required number of symbols per + // stream. If a bitstream is not entirely and exactly consumed, hence + // reaching exactly its beginning position with all bits consumed, the + // decoding process is considered faulty." + + // When all symbols have been decoded, the final state value shouldn't have + // any data from the stream, so it should have "read" dtable->max_bits from + // before the start of `src` + // Therefore `offset`, the edge to start reading new bits at, should be + // dtable->max_bits before the start of the stream + if (bit_offset != -dtable->max_bits) { + CORRUPTION(); + } + + return symbols_written; +} + +static size_t HUF_decompress_4stream(const HUF_dtable *const dtable, + ostream_t *const out, istream_t *const in) { + // "Compressed size is provided explicitly : in the 4-streams variant, + // bitstreams are preceded by 3 unsigned little-endian 16-bits values. Each + // value represents the compressed size of one stream, in order. The last + // stream size is deducted from total compressed size and from previously + // decoded stream sizes" + const size_t csize1 = IO_read_bits(in, 16); + const size_t csize2 = IO_read_bits(in, 16); + const size_t csize3 = IO_read_bits(in, 16); + + istream_t in1 = IO_make_sub_istream(in, csize1); + istream_t in2 = IO_make_sub_istream(in, csize2); + istream_t in3 = IO_make_sub_istream(in, csize3); + istream_t in4 = IO_make_sub_istream(in, IO_istream_len(in)); + + size_t total_output = 0; + // Decode each stream independently for simplicity + // If we wanted to we could decode all 4 at the same time for speed, + // utilizing more execution units + total_output += HUF_decompress_1stream(dtable, out, &in1); + total_output += HUF_decompress_1stream(dtable, out, &in2); + total_output += HUF_decompress_1stream(dtable, out, &in3); + total_output += HUF_decompress_1stream(dtable, out, &in4); + + return total_output; +} + +/// Initializes a Huffman table using canonical Huffman codes +/// For more explanation on canonical Huffman codes see +/// https://www.cs.scranton.edu/~mccloske/courses/cmps340/huff_canonical_dec2015.html +/// Codes within a level are allocated in symbol order (i.e. smaller symbols get +/// earlier codes) +static void HUF_init_dtable(HUF_dtable *const table, const u8 *const bits, + const int num_symbs) { + memset(table, 0, sizeof(HUF_dtable)); + if (num_symbs > HUF_MAX_SYMBS) { + ERROR("Too many symbols for Huffman"); + } + + u8 max_bits = 0; + u16 rank_count[HUF_MAX_BITS + 1]; + memset(rank_count, 0, sizeof(rank_count)); + + // Count the number of symbols for each number of bits, and determine the + // depth of the tree + for (int i = 0; i < num_symbs; i++) { + if (bits[i] > HUF_MAX_BITS) { + ERROR("Huffman table depth too large"); + } + max_bits = MAX(max_bits, bits[i]); + rank_count[bits[i]]++; + } + + const size_t table_size = 1 << max_bits; + table->max_bits = max_bits; + table->symbols = malloc(table_size); + table->num_bits = malloc(table_size); + + if (!table->symbols || !table->num_bits) { + free(table->symbols); + free(table->num_bits); + BAD_ALLOC(); + } + + // "Symbols are sorted by Weight. Within same Weight, symbols keep natural + // order. Symbols with a Weight of zero are removed. Then, starting from + // lowest weight, prefix codes are distributed in order." + + u32 rank_idx[HUF_MAX_BITS + 1]; + // Initialize the starting codes for each rank (number of bits) + rank_idx[max_bits] = 0; + for (int i = max_bits; i >= 1; i--) { + rank_idx[i - 1] = rank_idx[i] + rank_count[i] * (1 << (max_bits - i)); + // The entire range takes the same number of bits so we can memset it + memset(&table->num_bits[rank_idx[i]], i, rank_idx[i - 1] - rank_idx[i]); + } + + if (rank_idx[0] != table_size) { + CORRUPTION(); + } + + // Allocate codes and fill in the table + for (int i = 0; i < num_symbs; i++) { + if (bits[i] != 0) { + // Allocate a code for this symbol and set its range in the table + const u16 code = rank_idx[bits[i]]; + // Since the code doesn't care about the bottom `max_bits - bits[i]` + // bits of state, it gets a range that spans all possible values of + // the lower bits + const u16 len = 1 << (max_bits - bits[i]); + memset(&table->symbols[code], i, len); + rank_idx[bits[i]] += len; + } + } +} + +static void HUF_init_dtable_usingweights(HUF_dtable *const table, + const u8 *const weights, + const int num_symbs) { + // +1 because the last weight is not transmitted in the header + if (num_symbs + 1 > HUF_MAX_SYMBS) { + ERROR("Too many symbols for Huffman"); + } + + u8 bits[HUF_MAX_SYMBS]; + + u64 weight_sum = 0; + for (int i = 0; i < num_symbs; i++) { + // Weights are in the same range as bit count + if (weights[i] > HUF_MAX_BITS) { + CORRUPTION(); + } + weight_sum += weights[i] > 0 ? (u64)1 << (weights[i] - 1) : 0; + } + + // Find the first power of 2 larger than the sum + const int max_bits = highest_set_bit(weight_sum) + 1; + const u64 left_over = ((u64)1 << max_bits) - weight_sum; + // If the left over isn't a power of 2, the weights are invalid + if (left_over & (left_over - 1)) { + CORRUPTION(); + } + + // left_over is used to find the last weight as it's not transmitted + // by inverting 2^(weight - 1) we can determine the value of last_weight + const int last_weight = highest_set_bit(left_over) + 1; + + for (int i = 0; i < num_symbs; i++) { + // "Number_of_Bits = Number_of_Bits ? Max_Number_of_Bits + 1 - Weight : 0" + bits[i] = weights[i] > 0 ? (max_bits + 1 - weights[i]) : 0; + } + bits[num_symbs] = + max_bits + 1 - last_weight; // Last weight is always non-zero + + HUF_init_dtable(table, bits, num_symbs + 1); +} + +static void HUF_free_dtable(HUF_dtable *const dtable) { + free(dtable->symbols); + free(dtable->num_bits); + memset(dtable, 0, sizeof(HUF_dtable)); +} +/******* END HUFFMAN PRIMITIVES ***********************************************/ + +/******* FSE PRIMITIVES *******************************************************/ +/// For more description of FSE see +/// https://github.com/Cyan4973/FiniteStateEntropy/ + +/// Allow a symbol to be decoded without updating state +static inline u8 FSE_peek_symbol(const FSE_dtable *const dtable, + const u16 state) { + return dtable->symbols[state]; +} + +/// Consumes bits from the input and uses the current state to determine the +/// next state +static inline void FSE_update_state(const FSE_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset) { + const u8 bits = dtable->num_bits[*state]; + const u16 rest = STREAM_read_bits(src, bits, offset); + *state = dtable->new_state_base[*state] + rest; +} + +/// Decodes a single FSE symbol and updates the offset +static inline u8 FSE_decode_symbol(const FSE_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset) { + const u8 symb = FSE_peek_symbol(dtable, *state); + FSE_update_state(dtable, state, src, offset); + return symb; +} + +static inline void FSE_init_state(const FSE_dtable *const dtable, + u16 *const state, const u8 *const src, + i64 *const offset) { + // Read in a full `accuracy_log` bits to initialize the state + const u8 bits = dtable->accuracy_log; + *state = STREAM_read_bits(src, bits, offset); +} + +static size_t FSE_decompress_interleaved2(const FSE_dtable *const dtable, + ostream_t *const out, + istream_t *const in) { + const size_t len = IO_istream_len(in); + if (len == 0) { + INP_SIZE(); + } + const u8 *const src = IO_get_read_ptr(in, len); + + // "Each bitstream must be read backward, that is starting from the end down + // to the beginning. Therefore it's necessary to know the size of each + // bitstream. + // + // It's also necessary to know exactly which bit is the latest. This is + // detected by a final bit flag : the highest bit of latest byte is a + // final-bit-flag. Consequently, a last byte of 0 is not possible. And the + // final-bit-flag itself is not part of the useful bitstream. Hence, the + // last byte contains between 0 and 7 useful bits." + const int padding = 8 - highest_set_bit(src[len - 1]); + i64 offset = len * 8 - padding; + + u16 state1, state2; + // "The first state (State1) encodes the even indexed symbols, and the + // second (State2) encodes the odd indexes. State1 is initialized first, and + // then State2, and they take turns decoding a single symbol and updating + // their state." + FSE_init_state(dtable, &state1, src, &offset); + FSE_init_state(dtable, &state2, src, &offset); + + // Decode until we overflow the stream + // Since we decode in reverse order, overflowing the stream is offset going + // negative + size_t symbols_written = 0; + while (1) { + // "The number of symbols to decode is determined by tracking bitStream + // overflow condition: If updating state after decoding a symbol would + // require more bits than remain in the stream, it is assumed the extra + // bits are 0. Then, the symbols for each of the final states are + // decoded and the process is complete." + IO_write_byte(out, FSE_decode_symbol(dtable, &state1, src, &offset)); + symbols_written++; + if (offset < 0) { + // There's still a symbol to decode in state2 + IO_write_byte(out, FSE_peek_symbol(dtable, state2)); + symbols_written++; + break; + } + + IO_write_byte(out, FSE_decode_symbol(dtable, &state2, src, &offset)); + symbols_written++; + if (offset < 0) { + // There's still a symbol to decode in state1 + IO_write_byte(out, FSE_peek_symbol(dtable, state1)); + symbols_written++; + break; + } + } + + return symbols_written; +} + +static void FSE_init_dtable(FSE_dtable *const dtable, + const i16 *const norm_freqs, const int num_symbs, + const int accuracy_log) { + if (accuracy_log > FSE_MAX_ACCURACY_LOG) { + ERROR("FSE accuracy too large"); + } + if (num_symbs > FSE_MAX_SYMBS) { + ERROR("Too many symbols for FSE"); + } + + dtable->accuracy_log = accuracy_log; + + const size_t size = (size_t)1 << accuracy_log; + dtable->symbols = malloc(size * sizeof(u8)); + dtable->num_bits = malloc(size * sizeof(u8)); + dtable->new_state_base = malloc(size * sizeof(u16)); + + if (!dtable->symbols || !dtable->num_bits || !dtable->new_state_base) { + BAD_ALLOC(); + } + + // Used to determine how many bits need to be read for each state, + // and where the destination range should start + // Needs to be u16 because max value is 2 * max number of symbols, + // which can be larger than a byte can store + u16 state_desc[FSE_MAX_SYMBS]; + + // "Symbols are scanned in their natural order for "less than 1" + // probabilities. Symbols with this probability are being attributed a + // single cell, starting from the end of the table. These symbols define a + // full state reset, reading Accuracy_Log bits." + int high_threshold = size; + for (int s = 0; s < num_symbs; s++) { + // Scan for low probability symbols to put at the top + if (norm_freqs[s] == -1) { + dtable->symbols[--high_threshold] = s; + state_desc[s] = 1; + } + } + + // "All remaining symbols are sorted in their natural order. Starting from + // symbol 0 and table position 0, each symbol gets attributed as many cells + // as its probability. Cell allocation is spread, not linear." + // Place the rest in the table + const u16 step = (size >> 1) + (size >> 3) + 3; + const u16 mask = size - 1; + u16 pos = 0; + for (int s = 0; s < num_symbs; s++) { + if (norm_freqs[s] <= 0) { + continue; + } + + state_desc[s] = norm_freqs[s]; + + for (int i = 0; i < norm_freqs[s]; i++) { + // Give `norm_freqs[s]` states to symbol s + dtable->symbols[pos] = s; + // "A position is skipped if already occupied, typically by a "less + // than 1" probability symbol." + do { + pos = (pos + step) & mask; + } while (pos >= + high_threshold); + // Note: no other collision checking is necessary as `step` is + // coprime to `size`, so the cycle will visit each position exactly + // once + } + } + if (pos != 0) { + CORRUPTION(); + } + + // Now we can fill baseline and num bits + for (size_t i = 0; i < size; i++) { + u8 symbol = dtable->symbols[i]; + u16 next_state_desc = state_desc[symbol]++; + // Fills in the table appropriately, next_state_desc increases by symbol + // over time, decreasing number of bits + dtable->num_bits[i] = (u8)(accuracy_log - highest_set_bit(next_state_desc)); + // Baseline increases until the bit threshold is passed, at which point + // it resets to 0 + dtable->new_state_base[i] = + ((u16)next_state_desc << dtable->num_bits[i]) - size; + } +} + +/// Decode an FSE header as defined in the Zstandard format specification and +/// use the decoded frequencies to initialize a decoding table. +static void FSE_decode_header(FSE_dtable *const dtable, istream_t *const in, + const int max_accuracy_log) { + // "An FSE distribution table describes the probabilities of all symbols + // from 0 to the last present one (included) on a normalized scale of 1 << + // Accuracy_Log . + // + // It's a bitstream which is read forward, in little-endian fashion. It's + // not necessary to know its exact size, since it will be discovered and + // reported by the decoding process. + if (max_accuracy_log > FSE_MAX_ACCURACY_LOG) { + ERROR("FSE accuracy too large"); + } + + // The bitstream starts by reporting on which scale it operates. + // Accuracy_Log = low4bits + 5. Note that maximum Accuracy_Log for literal + // and match lengths is 9, and for offsets is 8. Higher values are + // considered errors." + const int accuracy_log = 5 + IO_read_bits(in, 4); + if (accuracy_log > max_accuracy_log) { + ERROR("FSE accuracy too large"); + } + + // "Then follows each symbol value, from 0 to last present one. The number + // of bits used by each field is variable. It depends on : + // + // Remaining probabilities + 1 : example : Presuming an Accuracy_Log of 8, + // and presuming 100 probabilities points have already been distributed, the + // decoder may read any value from 0 to 255 - 100 + 1 == 156 (inclusive). + // Therefore, it must read log2sup(156) == 8 bits. + // + // Value decoded : small values use 1 less bit : example : Presuming values + // from 0 to 156 (inclusive) are possible, 255-156 = 99 values are remaining + // in an 8-bits field. They are used this way : first 99 values (hence from + // 0 to 98) use only 7 bits, values from 99 to 156 use 8 bits. " + + i32 remaining = 1 << accuracy_log; + i16 frequencies[FSE_MAX_SYMBS]; + + int symb = 0; + while (remaining > 0 && symb < FSE_MAX_SYMBS) { + // Log of the number of possible values we could read + int bits = highest_set_bit(remaining + 1) + 1; + + u16 val = IO_read_bits(in, bits); + + // Try to mask out the lower bits to see if it qualifies for the "small + // value" threshold + const u16 lower_mask = ((u16)1 << (bits - 1)) - 1; + const u16 threshold = ((u16)1 << bits) - 1 - (remaining + 1); + + if ((val & lower_mask) < threshold) { + IO_rewind_bits(in, 1); + val = val & lower_mask; + } else if (val > lower_mask) { + val = val - threshold; + } + + // "Probability is obtained from Value decoded by following formula : + // Proba = value - 1" + const i16 proba = (i16)val - 1; + + // "It means value 0 becomes negative probability -1. -1 is a special + // probability, which means "less than 1". Its effect on distribution + // table is described in next paragraph. For the purpose of calculating + // cumulated distribution, it counts as one." + remaining -= proba < 0 ? -proba : proba; + + frequencies[symb] = proba; + symb++; + + // "When a symbol has a probability of zero, it is followed by a 2-bits + // repeat flag. This repeat flag tells how many probabilities of zeroes + // follow the current one. It provides a number ranging from 0 to 3. If + // it is a 3, another 2-bits repeat flag follows, and so on." + if (proba == 0) { + // Read the next two bits to see how many more 0s + int repeat = IO_read_bits(in, 2); + + while (1) { + for (int i = 0; i < repeat && symb < FSE_MAX_SYMBS; i++) { + frequencies[symb++] = 0; + } + if (repeat == 3) { + repeat = IO_read_bits(in, 2); + } else { + break; + } + } + } + } + IO_align_stream(in); + + // "When last symbol reaches cumulated total of 1 << Accuracy_Log, decoding + // is complete. If the last symbol makes cumulated total go above 1 << + // Accuracy_Log, distribution is considered corrupted." + if (remaining != 0 || symb >= FSE_MAX_SYMBS) { + CORRUPTION(); + } + + // Initialize the decoding table using the determined weights + FSE_init_dtable(dtable, frequencies, symb, accuracy_log); +} + +static void FSE_init_dtable_rle(FSE_dtable *const dtable, const u8 symb) { + dtable->symbols = malloc(sizeof(u8)); + dtable->num_bits = malloc(sizeof(u8)); + dtable->new_state_base = malloc(sizeof(u16)); + + if (!dtable->symbols || !dtable->num_bits || !dtable->new_state_base) { + BAD_ALLOC(); + } + + // This setup will always have a state of 0, always return symbol `symb`, + // and never consume any bits + dtable->symbols[0] = symb; + dtable->num_bits[0] = 0; + dtable->new_state_base[0] = 0; + dtable->accuracy_log = 0; +} + +static void FSE_free_dtable(FSE_dtable *const dtable) { + free(dtable->symbols); + free(dtable->num_bits); + free(dtable->new_state_base); + memset(dtable, 0, sizeof(FSE_dtable)); +} +/******* END FSE PRIMITIVES ***************************************************/ diff --git a/cpp/third_party/zstd-1.5.7/doc/educational_decoder/zstd_decompress.h b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/zstd_decompress.h new file mode 100644 index 000000000..c13c8134d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/educational_decoder/zstd_decompress.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include /* size_t */ + +/******* EXPOSED TYPES ********************************************************/ +/* +* Contains the parsed contents of a dictionary +* This includes Huffman and FSE tables used for decoding and data on offsets +*/ +typedef struct dictionary_s dictionary_t; +/******* END EXPOSED TYPES ****************************************************/ + +/******* DECOMPRESSION FUNCTIONS **********************************************/ +/// Zstandard decompression functions. +/// `dst` must point to a space at least as large as the reconstructed output. +size_t ZSTD_decompress(void *const dst, const size_t dst_len, + const void *const src, const size_t src_len); + +/// If `dict != NULL` and `dict_len >= 8`, does the same thing as +/// `ZSTD_decompress` but uses the provided dict +size_t ZSTD_decompress_with_dict(void *const dst, const size_t dst_len, + const void *const src, const size_t src_len, + dictionary_t* parsed_dict); + +/// Get the decompressed size of an input stream so memory can be allocated in +/// advance +/// Returns -1 if the size can't be determined +/// Assumes decompression of a single frame +size_t ZSTD_get_decompressed_size(const void *const src, const size_t src_len); +/******* END DECOMPRESSION FUNCTIONS ******************************************/ + +/******* DICTIONARY MANAGEMENT ***********************************************/ +/* + * Return a valid dictionary_t pointer for use with dictionary initialization + * or decompression + */ +dictionary_t* create_dictionary(void); + +/* + * Parse a provided dictionary blob for use in decompression + * `src` -- must point to memory space representing the dictionary + * `src_len` -- must provide the dictionary size + * `dict` -- will contain the parsed contents of the dictionary and + * can be used for decompression + */ +void parse_dictionary(dictionary_t *const dict, const void *src, + size_t src_len); + +/* + * Free internal Huffman tables, FSE tables, and dictionary content + */ +void free_dictionary(dictionary_t *const dict); +/******* END DICTIONARY MANAGEMENT *******************************************/ diff --git a/cpp/third_party/zstd-1.5.7/doc/images/CSpeed2.png b/cpp/third_party/zstd-1.5.7/doc/images/CSpeed2.png new file mode 100644 index 0000000000000000000000000000000000000000..42affa46ea4789c4d722fc47e3aa71d23058faf2 GIT binary patch literal 73335 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�q`%Hd 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�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 kkNMaC_Sd5~#zZ%vFoveu=-i&l647a4m#-~a#s literal 0 HcmV?d00001 diff --git a/cpp/third_party/zstd-1.5.7/doc/images/DSpeed3.png b/cpp/third_party/zstd-1.5.7/doc/images/DSpeed3.png new file mode 100644 index 0000000000000000000000000000000000000000..4818b11180a74514e1f7af61e0a9dcd91e6b4b07 GIT binary patch literal 27123 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/zstd-1.5.7/doc/images/dict-cr.png b/cpp/third_party/zstd-1.5.7/doc/images/dict-cr.png new file mode 100644 index 0000000000000000000000000000000000000000..6da34da46bde23942c10e100a3354681399c3e66 GIT binary patch literal 90412 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 OBjjlKmo;CU%=;hEEK0rr literal 0 HcmV?d00001 diff --git a/cpp/third_party/zstd-1.5.7/doc/images/dict-cs.png b/cpp/third_party/zstd-1.5.7/doc/images/dict-cs.png new file mode 100644 index 0000000000000000000000000000000000000000..a0d8d250565c82f1634b434b93c80d034650e080 GIT binary patch literal 91518 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 acdSTXZ#N^(p8E=Tojc?9d&w!kJO2-1)RnUU literal 0 HcmV?d00001 diff --git a/cpp/third_party/zstd-1.5.7/doc/images/zstd_cdict_v1_3_5.png b/cpp/third_party/zstd-1.5.7/doc/images/zstd_cdict_v1_3_5.png new file mode 100644 index 0000000000000000000000000000000000000000..cce67c83abbf8a8ff62f16eda279fc3088efc8f3 GIT binary patch literal 93969 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 HB{Ts5ea1Wy literal 0 HcmV?d00001 diff --git a/cpp/third_party/zstd-1.5.7/doc/images/zstd_logo86.png b/cpp/third_party/zstd-1.5.7/doc/images/zstd_logo86.png new file mode 100644 index 0000000000000000000000000000000000000000..8abefe21b1e172b9683392057421984f64c8c9a4 GIT binary patch literal 13069 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/zstd-1.5.7/doc/zstd_compression_format.md b/cpp/third_party/zstd-1.5.7/doc/zstd_compression_format.md new file mode 100644 index 000000000..a2bf20cbc --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/zstd_compression_format.md @@ -0,0 +1,1771 @@ +Zstandard Compression Format +============================ + +### Notices + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is granted to copy and distribute this document +for any purpose and without charge, +including translations into other languages +and incorporation into compilations, +provided that the copyright notice and this notice are preserved, +and that any substantive changes or deletions from the original +are clearly marked. +Distribution of this document is unlimited. + +### Version + +0.4.3 (2024-10-07) + + +Introduction +------------ + +The purpose of this document is to define a lossless compressed data format, +that is independent of CPU type, operating system, +file system and character set, suitable for +file compression, pipe and streaming compression, +using the [Zstandard algorithm](https://facebook.github.io/zstd/). +The text of the specification assumes a basic background in programming +at the level of bits and other primitive data representations. + +The data can be produced or consumed, +even for an arbitrarily long sequentially presented input data stream, +using only an a priori bounded amount of intermediate storage, +and hence can be used in data communications. +The format uses the Zstandard compression method, +and optional [xxHash-64 checksum method](https://cyan4973.github.io/xxHash/), +for detection of data corruption. + +The data format defined by this specification +does not attempt to allow random access to compressed data. + +Unless otherwise indicated below, +a compliant compressor must produce data sets +that conform to the specifications presented here. +It doesn’t need to support all options though. + +A compliant decompressor must be able to decompress +at least one working set of parameters +that conforms to the specifications presented here. +It may also ignore informative fields, such as checksum. +Whenever it does not support a parameter defined in the compressed stream, +it must produce a non-ambiguous error code and associated error message +explaining which parameter is unsupported. + +This specification is intended for use by implementers of software +to compress data into Zstandard format and/or decompress data from Zstandard format. +The Zstandard format is supported by an open source reference implementation, +written in portable C, and available at : https://github.com/facebook/zstd . + + +### Overall conventions +In this document: +- square brackets i.e. `[` and `]` are used to indicate optional fields or parameters. +- the naming convention for identifiers is `Mixed_Case_With_Underscores` + +### Definitions +Content compressed by Zstandard is transformed into a Zstandard __frame__. +Multiple frames can be appended into a single file or stream. +A frame is completely independent, has a defined beginning and end, +and a set of parameters which tells the decoder how to decompress it. + +A frame encapsulates one or multiple __blocks__. +Each block contains arbitrary content, which is described by its header, +and has a guaranteed maximum content size, which depends on frame parameters. +Unlike frames, each block depends on previous blocks for proper decoding. +However, each block can be decompressed without waiting for its successor, +allowing streaming operations. + +Overview +--------- +- [Frames](#frames) + - [Zstandard frames](#zstandard-frames) + - [Blocks](#blocks) + - [Literals Section](#literals-section) + - [Sequences Section](#sequences-section) + - [Sequence Execution](#sequence-execution) + - [Skippable frames](#skippable-frames) +- [Entropy Encoding](#entropy-encoding) + - [FSE](#fse) + - [Huffman Coding](#huffman-coding) +- [Dictionary Format](#dictionary-format) + +Frames +------ +Zstandard compressed data is made of one or more __frames__. +Each frame is independent and can be decompressed independently of other frames. +The decompressed content of multiple concatenated frames is the concatenation of +each frame decompressed content. + +There are two frame formats defined by Zstandard: + Zstandard frames and Skippable frames. +Zstandard frames contain compressed data, while +skippable frames contain custom user metadata. + +## Zstandard frames +The structure of a single Zstandard frame is following: + +| `Magic_Number` | `Frame_Header` |`Data_Block`| [More data blocks] | [`Content_Checksum`] | +|:--------------:|:--------------:|:----------:| ------------------ |:--------------------:| +| 4 bytes | 2-14 bytes | n bytes | | 0-4 bytes | + +__`Magic_Number`__ + +4 Bytes, __little-endian__ format. +Value : 0xFD2FB528 +Note: This value was selected to be less probable to find at the beginning of some random file. +It avoids trivial patterns (0x00, 0xFF, repeated bytes, increasing bytes, etc.), +contains byte values outside of ASCII range, +and doesn't map into UTF8 space. +It reduces the chances that a text file represent this value by accident. + +__`Frame_Header`__ + +2 to 14 Bytes, detailed in [`Frame_Header`](#frame_header). + +__`Data_Block`__ + +Detailed in [`Blocks`](#blocks). +That’s where compressed data is stored. + +__`Content_Checksum`__ + +An optional 32-bit checksum, only present if `Content_Checksum_flag` is set. +The content checksum is the result +of [xxh64() hash function](https://cyan4973.github.io/xxHash/) +digesting the original (decoded) data as input, and a seed of zero. +The low 4 bytes of the checksum are stored in __little-endian__ format. + +### `Frame_Header` + +The `Frame_Header` has a variable size, with a minimum of 2 bytes, +and up to 14 bytes depending on optional parameters. +The structure of `Frame_Header` is following: + +| `Frame_Header_Descriptor` | [`Window_Descriptor`] | [`Dictionary_ID`] | [`Frame_Content_Size`] | +| ------------------------- | --------------------- | ----------------- | ---------------------- | +| 1 byte | 0-1 byte | 0-4 bytes | 0-8 bytes | + +#### `Frame_Header_Descriptor` + +The first header's byte is called the `Frame_Header_Descriptor`. +It describes which other fields are present. +Decoding this byte is enough to tell the size of `Frame_Header`. + +| Bit number | Field name | +| ---------- | ---------- | +| 7-6 | `Frame_Content_Size_flag` | +| 5 | `Single_Segment_flag` | +| 4 | `Unused_bit` | +| 3 | `Reserved_bit` | +| 2 | `Content_Checksum_flag` | +| 1-0 | `Dictionary_ID_flag` | + +In this table, bit 7 is the highest bit, while bit 0 is the lowest one. + +__`Frame_Content_Size_flag`__ + +This is a 2-bits flag (`= Frame_Header_Descriptor >> 6`), +specifying if `Frame_Content_Size` (the decompressed data size) +is provided within the header. +`Flag_Value` provides `FCS_Field_Size`, +which is the number of bytes used by `Frame_Content_Size` +according to the following table: + +| `Flag_Value` | 0 | 1 | 2 | 3 | +| -------------- | ------ | --- | --- | --- | +|`FCS_Field_Size`| 0 or 1 | 2 | 4 | 8 | + +When `Flag_Value` is `0`, `FCS_Field_Size` depends on `Single_Segment_flag` : +if `Single_Segment_flag` is set, `FCS_Field_Size` is 1. +Otherwise, `FCS_Field_Size` is 0 : `Frame_Content_Size` is not provided. + +__`Single_Segment_flag`__ + +If this flag is set, +data must be regenerated within a single continuous memory segment. + +In this case, `Window_Descriptor` byte is skipped, +but `Frame_Content_Size` is necessarily present. +As a consequence, the decoder must allocate a memory segment +of size equal or larger than `Frame_Content_Size`. + +In order to preserve the decoder from unreasonable memory requirements, +a decoder is allowed to reject a compressed frame +which requests a memory size beyond decoder's authorized range. + +For broader compatibility, decoders are recommended to support +memory sizes of at least 8 MB. +This is only a recommendation, +each decoder is free to support higher or lower limits, +depending on local limitations. + +__`Unused_bit`__ + +A decoder compliant with this specification version shall not interpret this bit. +It might be used in any future version, +to signal a property which is transparent to properly decode the frame. +An encoder compliant with this specification version must set this bit to zero. + +__`Reserved_bit`__ + +This bit is reserved for some future feature. +Its value _must be zero_. +A decoder compliant with this specification version must ensure it is not set. +This bit may be used in a future revision, +to signal a feature that must be interpreted to decode the frame correctly. + +__`Content_Checksum_flag`__ + +If this flag is set, a 32-bits `Content_Checksum` will be present at frame's end. +See `Content_Checksum` paragraph. + +__`Dictionary_ID_flag`__ + +This is a 2-bits flag (`= FHD & 3`), +telling if a dictionary ID is provided within the header. +It also specifies the size of this field as `DID_Field_Size`. + +|`Flag_Value` | 0 | 1 | 2 | 3 | +| -------------- | --- | --- | --- | --- | +|`DID_Field_Size`| 0 | 1 | 2 | 4 | + +#### `Window_Descriptor` + +Provides guarantees on minimum memory buffer required to decompress a frame. +This information is important for decoders to allocate enough memory. + +The `Window_Descriptor` byte is optional. +When `Single_Segment_flag` is set, `Window_Descriptor` is not present. +In this case, `Window_Size` is `Frame_Content_Size`, +which can be any value from 0 to 2^64-1 bytes (16 ExaBytes). + +| Bit numbers | 7-3 | 2-0 | +| ----------- | ---------- | ---------- | +| Field name | `Exponent` | `Mantissa` | + +The minimum memory buffer size is called `Window_Size`. +It is described by the following formulas : +``` +windowLog = 10 + Exponent; +windowBase = 1 << windowLog; +windowAdd = (windowBase / 8) * Mantissa; +Window_Size = windowBase + windowAdd; +``` +The minimum `Window_Size` is 1 KB. +The maximum `Window_Size` is `(1<<41) + 7*(1<<38)` bytes, which is 3.75 TB. + +In general, larger `Window_Size` tend to improve compression ratio, +but at the cost of memory usage. + +To properly decode compressed data, +a decoder will need to allocate a buffer of at least `Window_Size` bytes. + +In order to preserve decoder from unreasonable memory requirements, +a decoder is allowed to reject a compressed frame +which requests a memory size beyond decoder's authorized range. + +For improved interoperability, +it's recommended for decoders to support `Window_Size` of up to 8 MB, +and it's recommended for encoders to not generate frame requiring `Window_Size` larger than 8 MB. +It's merely a recommendation though, +decoders are free to support larger or lower limits, +depending on local limitations. + +#### `Dictionary_ID` + +This is a variable size field, which contains +the ID of the dictionary required to properly decode the frame. +`Dictionary_ID` field is optional. When it's not present, +it's up to the decoder to know which dictionary to use. + +`Dictionary_ID` field size is provided by `DID_Field_Size`. +`DID_Field_Size` is directly derived from value of `Dictionary_ID_flag`. +1 byte can represent an ID 0-255. +2 bytes can represent an ID 0-65535. +4 bytes can represent an ID 0-4294967295. +Format is __little-endian__. + +It's allowed to represent a small ID (for example `13`) +with a large 4-bytes dictionary ID, even if it is less efficient. + +A value of `0` has same meaning as no `Dictionary_ID`, +in which case the frame may or may not need a dictionary to be decoded, +and the ID of such a dictionary is not specified. +The decoder must know this information by other means. + +#### `Frame_Content_Size` + +This is the original (uncompressed) size. This information is optional. +`Frame_Content_Size` uses a variable number of bytes, provided by `FCS_Field_Size`. +`FCS_Field_Size` is provided by the value of `Frame_Content_Size_flag`. +`FCS_Field_Size` can be equal to 0 (not present), 1, 2, 4 or 8 bytes. + +| `FCS_Field_Size` | Range | +| ---------------- | ---------- | +| 0 | unknown | +| 1 | 0 - 255 | +| 2 | 256 - 65791| +| 4 | 0 - 2^32-1 | +| 8 | 0 - 2^64-1 | + +`Frame_Content_Size` format is __little-endian__. +When `FCS_Field_Size` is 1, 4 or 8 bytes, the value is read directly. +When `FCS_Field_Size` is 2, _the offset of 256 is added_. +It's allowed to represent a small size (for example `18`) using any compatible variant. + + +Blocks +------- + +After `Magic_Number` and `Frame_Header`, there are some number of blocks. +Each frame must have at least one block, +but there is no upper limit on the number of blocks per frame. + +The structure of a block is as follows: + +| `Block_Header` | `Block_Content` | +|:--------------:|:---------------:| +| 3 bytes | n bytes | + +__`Block_Header`__ + +`Block_Header` uses 3 bytes, written using __little-endian__ convention. +It contains 3 fields : + +| `Last_Block` | `Block_Type` | `Block_Size` | +|:------------:|:------------:|:------------:| +| bit 0 | bits 1-2 | bits 3-23 | + +__`Last_Block`__ + +The lowest bit signals if this block is the last one. +The frame will end after this last block. +It may be followed by an optional `Content_Checksum` +(see [Zstandard Frames](#zstandard-frames)). + +__`Block_Type`__ + +The next 2 bits represent the `Block_Type`. +`Block_Type` influences the meaning of `Block_Size`. +There are 4 block types : + +| Value | 0 | 1 | 2 | 3 | +| ------------ | ----------- | ----------- | ------------------ | --------- | +| `Block_Type` | `Raw_Block` | `RLE_Block` | `Compressed_Block` | `Reserved`| + +- `Raw_Block` - this is an uncompressed block. + `Block_Content` contains `Block_Size` bytes. + +- `RLE_Block` - this is a single byte, repeated `Block_Size` times. + `Block_Content` consists of a single byte. + On the decompression side, this byte must be repeated `Block_Size` times. + +- `Compressed_Block` - this is a [Zstandard compressed block](#compressed-blocks), + explained later on. + `Block_Size` is the length of `Block_Content`, the compressed data. + The decompressed size is not known, + but its maximum possible value is guaranteed (see below) + +- `Reserved` - this is not a block. + This value cannot be used with current version of this specification. + If such a value is present, it is considered corrupted data. + +__`Block_Size`__ + +The upper 21 bits of `Block_Header` represent the `Block_Size`. + +When `Block_Type` is `Compressed_Block` or `Raw_Block`, +`Block_Size` is the size of `Block_Content` (hence excluding `Block_Header`). + +When `Block_Type` is `RLE_Block`, since `Block_Content`’s size is always 1, +`Block_Size` represents the number of times this byte must be repeated. + +`Block_Size` is limited by `Block_Maximum_Size` (see below). + +__`Block_Content`__ and __`Block_Maximum_Size`__ + +The size of `Block_Content` is limited by `Block_Maximum_Size`, +which is the smallest of: +- `Window_Size` +- 128 KB + +`Block_Maximum_Size` is constant for a given frame. +This maximum is applicable to both the decompressed size +and the compressed size of any block in the frame. + +The reasoning for this limit is that a decoder can read this information +at the beginning of a frame and use it to allocate buffers. +The guarantees on the size of blocks ensure that +the buffers will be large enough for any following block of the valid frame. + + +Compressed Blocks +----------------- +To decompress a compressed block, the compressed size must be provided +from `Block_Size` field within `Block_Header`. + +A compressed block consists of 2 sections : +- [Literals Section](#literals-section) +- [Sequences Section](#sequences-section) + +The results of the two sections are then combined to produce the decompressed +data in [Sequence Execution](#sequence-execution) + +#### Prerequisites +To decode a compressed block, the following elements are necessary : +- Previous decoded data, up to a distance of `Window_Size`, + or beginning of the Frame, whichever is smaller. +- List of "recent offsets" from previous `Compressed_Block`. +- The previous Huffman tree, required by `Treeless_Literals_Block` type +- Previous FSE decoding tables, required by `Repeat_Mode` + for each symbol type (literals lengths, match lengths, offsets) + +Note that decoding tables aren't always from the previous `Compressed_Block`. + +- Every decoding table can come from a dictionary. +- The Huffman tree comes from the previous `Compressed_Literals_Block`. + +Literals Section +---------------- +All literals are regrouped in the first part of the block. +They can be decoded first, and then copied during [Sequence Execution], +or they can be decoded on the flow during [Sequence Execution]. + +Literals can be stored uncompressed or compressed using Huffman prefix codes. +When compressed, a tree description may optionally be present, +followed by 1 or 4 streams. + +| `Literals_Section_Header` | [`Huffman_Tree_Description`] | [jumpTable] | Stream1 | [Stream2] | [Stream3] | [Stream4] | +| ------------------------- | ---------------------------- | ----------- | ------- | --------- | --------- | --------- | + + +### `Literals_Section_Header` + +Header is in charge of describing how literals are packed. +It's a byte-aligned variable-size bitfield, ranging from 1 to 5 bytes, +using __little-endian__ convention. + +| `Literals_Block_Type` | `Size_Format` | `Regenerated_Size` | [`Compressed_Size`] | +| --------------------- | ------------- | ------------------ | ------------------- | +| 2 bits | 1 - 2 bits | 5 - 20 bits | 0 - 18 bits | + +In this representation, bits on the left are the lowest bits. + +__`Literals_Block_Type`__ + +This field uses 2 lowest bits of first byte, describing 4 different block types : + +| `Literals_Block_Type` | Value | +| --------------------------- | ----- | +| `Raw_Literals_Block` | 0 | +| `RLE_Literals_Block` | 1 | +| `Compressed_Literals_Block` | 2 | +| `Treeless_Literals_Block` | 3 | + +- `Raw_Literals_Block` - Literals are stored uncompressed. +- `RLE_Literals_Block` - Literals consist of a single byte value + repeated `Regenerated_Size` times. +- `Compressed_Literals_Block` - This is a standard Huffman-compressed block, + starting with a Huffman tree description. + In this mode, there are at least 2 different literals represented in the Huffman tree description. + See details below. +- `Treeless_Literals_Block` - This is a Huffman-compressed block, + using Huffman tree _from previous Huffman-compressed literals block_. + `Huffman_Tree_Description` will be skipped. + Note: If this mode is triggered without any previous Huffman-table in the frame + (or [dictionary](#dictionary-format)), this should be treated as data corruption. + +__`Size_Format`__ + +`Size_Format` is divided into 2 families : + +- For `Raw_Literals_Block` and `RLE_Literals_Block`, + it's only necessary to decode `Regenerated_Size`. + There is no `Compressed_Size` field. +- For `Compressed_Block` and `Treeless_Literals_Block`, + it's required to decode both `Compressed_Size` + and `Regenerated_Size` (the decompressed size). + It's also necessary to decode the number of streams (1 or 4). + +For values spanning several bytes, convention is __little-endian__. + +__`Size_Format` for `Raw_Literals_Block` and `RLE_Literals_Block`__ : + +`Size_Format` uses 1 _or_ 2 bits. +Its value is : `Size_Format = (Literals_Section_Header[0]>>2) & 3` + +- `Size_Format` == 00 or 10 : `Size_Format` uses 1 bit. + `Regenerated_Size` uses 5 bits (0-31). + `Literals_Section_Header` uses 1 byte. + `Regenerated_Size = Literals_Section_Header[0]>>3` +- `Size_Format` == 01 : `Size_Format` uses 2 bits. + `Regenerated_Size` uses 12 bits (0-4095). + `Literals_Section_Header` uses 2 bytes. + `Regenerated_Size = (Literals_Section_Header[0]>>4) + (Literals_Section_Header[1]<<4)` +- `Size_Format` == 11 : `Size_Format` uses 2 bits. + `Regenerated_Size` uses 20 bits (0-1048575). + `Literals_Section_Header` uses 3 bytes. + `Regenerated_Size = (Literals_Section_Header[0]>>4) + (Literals_Section_Header[1]<<4) + (Literals_Section_Header[2]<<12)` + +Only Stream1 is present for these cases. +Note : it's allowed to represent a short value (for example `27`) +using a long format, even if it's less efficient. + +__`Size_Format` for `Compressed_Literals_Block` and `Treeless_Literals_Block`__ : + +`Size_Format` always uses 2 bits. + +- `Size_Format` == 00 : _A single stream_. + Both `Regenerated_Size` and `Compressed_Size` use 10 bits (0-1023). + `Literals_Section_Header` uses 3 bytes. +- `Size_Format` == 01 : 4 streams. + Both `Regenerated_Size` and `Compressed_Size` use 10 bits (6-1023). + `Literals_Section_Header` uses 3 bytes. +- `Size_Format` == 10 : 4 streams. + Both `Regenerated_Size` and `Compressed_Size` use 14 bits (6-16383). + `Literals_Section_Header` uses 4 bytes. +- `Size_Format` == 11 : 4 streams. + Both `Regenerated_Size` and `Compressed_Size` use 18 bits (6-262143). + `Literals_Section_Header` uses 5 bytes. + +Both `Compressed_Size` and `Regenerated_Size` fields follow __little-endian__ convention. +Note: `Compressed_Size` __includes__ the size of the Huffman Tree description +_when_ it is present. +Note 2: `Compressed_Size` can never be `==0`. +Even in single-stream scenario, assuming an empty content, it must be `>=1`, +since it contains at least the final end bit flag. +In 4-streams scenario, a valid `Compressed_Size` is necessarily `>= 10` +(6 bytes for the jump table, + 4x1 bytes for the 4 streams). + +4 streams is faster than 1 stream in decompression speed, +by exploiting instruction level parallelism. +But it's also more expensive, +costing on average ~7.3 bytes more than the 1 stream mode, mostly from the jump table. + +In general, use the 4 streams mode when there are more literals to decode, +to favor higher decompression speeds. +Note that beyond >1KB of literals, the 4 streams mode is compulsory. + +Note that a minimum of 6 bytes is required for the 4 streams mode. +That's a technical minimum, but it's not recommended to employ the 4 streams mode +for such a small quantity, that would be wasteful. +A more practical lower bound would be around ~256 bytes. + +#### Raw Literals Block +The data in Stream1 is `Regenerated_Size` bytes long, +it contains the raw literals data to be used during [Sequence Execution]. + +#### RLE Literals Block +Stream1 consists of a single byte which should be repeated `Regenerated_Size` times +to generate the decoded literals. + +#### Compressed Literals Block and Treeless Literals Block +Both of these modes contain Huffman encoded data. + +For `Treeless_Literals_Block`, +the Huffman table comes from previously compressed literals block, +or from a dictionary. + + +### `Huffman_Tree_Description` +This section is only present when `Literals_Block_Type` type is `Compressed_Literals_Block` (`2`). +The tree describes the weights of all literals symbols that can be present in the literals block, at least 2 and up to 256. +The format of the Huffman tree description can be found at [Huffman Tree description](#huffman-tree-description). +The size of `Huffman_Tree_Description` is determined during decoding process, +it must be used to determine where streams begin. +`Total_Streams_Size = Compressed_Size - Huffman_Tree_Description_Size`. + + +### Jump Table +The Jump Table is only present when there are 4 Huffman-coded streams. + +Reminder : Huffman compressed data consists of either 1 or 4 streams. + +If only one stream is present, it is a single bitstream occupying the entire +remaining portion of the literals block, encoded as described in +[Huffman-Coded Streams](#huffman-coded-streams). + +If there are four streams, `Literals_Section_Header` only provided +enough information to know the decompressed and compressed sizes +of all four streams _combined_. +The decompressed size of _each_ stream is equal to `(Regenerated_Size+3)/4`, +except for the last stream which may be up to 3 bytes smaller, +to reach a total decompressed size as specified in `Regenerated_Size`. + +The compressed size of each stream is provided explicitly in the Jump Table. +Jump Table is 6 bytes long, and consists of three 2-byte __little-endian__ fields, +describing the compressed sizes of the first three streams. +`Stream4_Size` is computed from `Total_Streams_Size` minus sizes of other streams: + +`Stream4_Size = Total_Streams_Size - 6 - Stream1_Size - Stream2_Size - Stream3_Size`. + +`Stream4_Size` is necessarily `>= 1`. Therefore, +if `Total_Streams_Size < Stream1_Size + Stream2_Size + Stream3_Size + 6 + 1`, +data is considered corrupted. + +Each of these 4 bitstreams is then decoded independently as a Huffman-Coded stream, +as described in [Huffman-Coded Streams](#huffman-coded-streams) + + +Sequences Section +----------------- +A compressed block is a succession of _sequences_ . +A sequence is a literal copy command, followed by a match copy command. +A literal copy command specifies a length. +It is the number of bytes to be copied (or extracted) from the Literals Section. +A match copy command specifies an offset and a length. + +When all _sequences_ are decoded, +if there are literals left in the _literals section_, +these bytes are added at the end of the block. + +This is described in more detail in [Sequence Execution](#sequence-execution). + +The `Sequences_Section` regroup all symbols required to decode commands. +There are 3 symbol types : literals lengths, offsets and match lengths. +They are encoded together, interleaved, in a single _bitstream_. + +The `Sequences_Section` starts by a header, +followed by optional probability tables for each symbol type, +followed by the bitstream. + +| `Sequences_Section_Header` | [`Literals_Length_Table`] | [`Offset_Table`] | [`Match_Length_Table`] | bitStream | +| -------------------------- | ------------------------- | ---------------- | ---------------------- | --------- | + +To decode the `Sequences_Section`, it's required to know its size. +Its size is deduced from the size of `Literals_Section`: +`Sequences_Section_Size = Block_Size - Literals_Section_Size`. + + +#### `Sequences_Section_Header` + +Consists of 2 items: +- `Number_of_Sequences` +- Symbol compression modes + +__`Number_of_Sequences`__ + +This is a variable size field using between 1 and 3 bytes. +Let's call its first byte `byte0`. +- `if (byte0 < 128)` : `Number_of_Sequences = byte0` . Uses 1 byte. +- `if (byte0 < 255)` : `Number_of_Sequences = ((byte0 - 0x80) << 8) + byte1`. Uses 2 bytes. + Note that the 2 bytes format fully overlaps the 1 byte format. +- `if (byte0 == 255)`: `Number_of_Sequences = byte1 + (byte2<<8) + 0x7F00`. Uses 3 bytes. + +`if (Number_of_Sequences == 0)` : there are no sequences. + The sequence section stops immediately, + FSE tables used in `Repeat_Mode` aren't updated. + Block's decompressed content is defined solely by the Literals Section content. + +__Symbol compression modes__ + +This is a single byte, defining the compression mode of each symbol type. + +|Bit number| 7-6 | 5-4 | 3-2 | 1-0 | +| -------- | ----------------------- | -------------- | -------------------- | ---------- | +|Field name| `Literals_Lengths_Mode` | `Offsets_Mode` | `Match_Lengths_Mode` | `Reserved` | + +The last field, `Reserved`, must be all-zeroes. + +`Literals_Lengths_Mode`, `Offsets_Mode` and `Match_Lengths_Mode` define the `Compression_Mode` of +literals lengths, offsets, and match lengths symbols respectively. + +They follow the same enumeration : + +| Value | 0 | 1 | 2 | 3 | +| ------------------ | ----------------- | ---------- | --------------------- | ------------- | +| `Compression_Mode` | `Predefined_Mode` | `RLE_Mode` | `FSE_Compressed_Mode` | `Repeat_Mode` | + +- `Predefined_Mode` : A predefined FSE distribution table is used, defined in + [default distributions](#default-distributions). + No distribution table will be present. +- `RLE_Mode` : The table description consists of a single byte, which contains the symbol's value. + This symbol will be used for all sequences. +- `FSE_Compressed_Mode` : standard FSE compression. + A distribution table will be present. + The format of this distribution table is described in [FSE Table Description](#fse-table-description). + Note that the maximum allowed accuracy log for literals length and match length tables is 9, + and the maximum accuracy log for the offsets table is 8. + `FSE_Compressed_Mode` must not be used when only one symbol is present, + `RLE_Mode` should be used instead (although any other mode will work). +- `Repeat_Mode` : The table used in the previous `Compressed_Block` with `Number_of_Sequences > 0` will be used again, + or if this is the first block, table in the dictionary will be used. + Note that this includes `RLE_mode`, so if `Repeat_Mode` follows `RLE_Mode`, the same symbol will be repeated. + It also includes `Predefined_Mode`, in which case `Repeat_Mode` will have same outcome as `Predefined_Mode`. + No distribution table will be present. + If this mode is used without any previous sequence table in the frame + (nor [dictionary](#dictionary-format)) to repeat, this should be treated as corruption. + +#### The codes for literals lengths, match lengths, and offsets. + +Each symbol is a _code_ in its own context, +which specifies `Baseline` and `Number_of_Bits` to add. +_Codes_ are FSE compressed, +and interleaved with raw additional bits in the same bitstream. + +##### Literals length codes + +Literals length codes are values ranging from `0` to `35` included. +They define lengths from 0 to 131071 bytes. +The literals length is equal to the decoded `Baseline` plus +the result of reading `Number_of_Bits` bits from the bitstream, +as a __little-endian__ value. + +| `Literals_Length_Code` | 0-15 | +| ---------------------- | ---------------------- | +| length | `Literals_Length_Code` | +| `Number_of_Bits` | 0 | + +| `Literals_Length_Code` | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | +| ---------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| `Baseline` | 16 | 18 | 20 | 22 | 24 | 28 | 32 | 40 | +| `Number_of_Bits` | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 3 | + +| `Literals_Length_Code` | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | +| ---------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| `Baseline` | 48 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | +| `Number_of_Bits` | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | + +| `Literals_Length_Code` | 32 | 33 | 34 | 35 | +| ---------------------- | ---- | ---- | ---- | ---- | +| `Baseline` | 8192 |16384 |32768 |65536 | +| `Number_of_Bits` | 13 | 14 | 15 | 16 | + + +##### Match length codes + +Match length codes are values ranging from `0` to `52` included. +They define lengths from 3 to 131074 bytes. +The match length is equal to the decoded `Baseline` plus +the result of reading `Number_of_Bits` bits from the bitstream, +as a __little-endian__ value. + +| `Match_Length_Code` | 0-31 | +| ------------------- | ----------------------- | +| value | `Match_Length_Code` + 3 | +| `Number_of_Bits` | 0 | + +| `Match_Length_Code` | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | +| ------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| `Baseline` | 35 | 37 | 39 | 41 | 43 | 47 | 51 | 59 | +| `Number_of_Bits` | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 3 | + +| `Match_Length_Code` | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | +| ------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| `Baseline` | 67 | 83 | 99 | 131 | 259 | 515 | 1027 | 2051 | +| `Number_of_Bits` | 4 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | + +| `Match_Length_Code` | 48 | 49 | 50 | 51 | 52 | +| ------------------- | ---- | ---- | ---- | ---- | ---- | +| `Baseline` | 4099 | 8195 |16387 |32771 |65539 | +| `Number_of_Bits` | 12 | 13 | 14 | 15 | 16 | + +##### Offset codes + +Offset codes are values ranging from `0` to `N`. + +A decoder is free to limit its maximum `N` supported. +Recommendation is to support at least up to `22`. +For information, at the time of this writing. +the reference decoder supports a maximum `N` value of `31`. + +An offset code is also the number of additional bits to read in __little-endian__ fashion, +and can be translated into an `Offset_Value` using the following formulas : + +``` +Offset_Value = (1 << offsetCode) + readNBits(offsetCode); +if (Offset_Value > 3) offset = Offset_Value - 3; +``` +It means that maximum `Offset_Value` is `(2^(N+1))-1` +supporting back-reference distances up to `(2^(N+1))-4`, +but is limited by [maximum back-reference distance](#window_descriptor). + +`Offset_Value` from 1 to 3 are special : they define "repeat codes". +This is described in more detail in [Repeat Offsets](#repeat-offsets). + +#### Decoding Sequences +FSE bitstreams are read in reverse direction than written. In zstd, +the compressor writes bits forward into a block and the decompressor +must read the bitstream _backwards_. + +To find the start of the bitstream it is therefore necessary to +know the offset of the last byte of the block which can be found +by counting `Block_Size` bytes after the block header. + +After writing the last bit containing information, the compressor +writes a single `1`-bit and then fills the byte with 0-7 `0` bits of +padding. The last byte of the compressed bitstream cannot be `0` for +that reason. + +When decompressing, the last byte containing the padding is the first +byte to read. The decompressor needs to skip 0-7 initial `0`-bits and +the first `1`-bit it occurs. Afterwards, the useful part of the bitstream +begins. + +FSE decoding requires a 'state' to be carried from symbol to symbol. +For more explanation on FSE decoding, see the [FSE section](#fse). + +For sequence decoding, a separate state keeps track of each +literal lengths, offsets, and match lengths symbols. +Some FSE primitives are also used. +For more details on the operation of these primitives, see the [FSE section](#fse). + +##### Starting states +The bitstream starts with initial FSE state values, +each using the required number of bits in their respective _accuracy_, +decoded previously from their normalized distribution. + +It starts by `Literals_Length_State`, +followed by `Offset_State`, +and finally `Match_Length_State`. + +Reminder : always keep in mind that all values are read _backward_, +so the 'start' of the bitstream is at the highest position in memory, +immediately before the last `1`-bit for padding. + +After decoding the starting states, a single sequence is decoded +`Number_Of_Sequences` times. +These sequences are decoded in order from first to last. +Since the compressor writes the bitstream in the forward direction, +this means the compressor must encode the sequences starting with the last +one and ending with the first. + +##### Decoding a sequence +For each of the symbol types, the FSE state can be used to determine the appropriate code. +The code then defines the `Baseline` and `Number_of_Bits` to read for each type. +See the [description of the codes] for how to determine these values. + +[description of the codes]: #the-codes-for-literals-lengths-match-lengths-and-offsets + +Decoding starts by reading the `Number_of_Bits` required to decode `Offset`. +It then does the same for `Match_Length`, and then for `Literals_Length`. +This sequence is then used for [sequence execution](#sequence-execution). + +If it is not the last sequence in the block, +the next operation is to update states. +Using the rules pre-calculated in the decoding tables, +`Literals_Length_State` is updated, +followed by `Match_Length_State`, +and then `Offset_State`. +See the [FSE section](#fse) for details on how to update states from the bitstream. + +This operation will be repeated `Number_of_Sequences` times. +At the end, the bitstream shall be entirely consumed, +otherwise the bitstream is considered corrupted. + +#### Default Distributions +If `Predefined_Mode` is selected for a symbol type, +its FSE decoding table is generated from a predefined distribution table defined here. +For details on how to convert this distribution into a decoding table, see the [FSE section]. + +[FSE section]: #from-normalized-distribution-to-decoding-tables + +##### Literals Length +The decoding table uses an accuracy log of 6 bits (64 states). +``` +short literalsLength_defaultDistribution[36] = + { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, + -1,-1,-1,-1 }; +``` + +##### Match Length +The decoding table uses an accuracy log of 6 bits (64 states). +``` +short matchLengths_defaultDistribution[53] = + { 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1, + -1,-1,-1,-1,-1 }; +``` + +##### Offset Codes +The decoding table uses an accuracy log of 5 bits (32 states), +and supports a maximum `N` value of 28, allowing offset values up to 536,870,908 . + +If any sequence in the compressed block requires a larger offset than this, +it's not possible to use the default distribution to represent it. +``` +short offsetCodes_defaultDistribution[29] = + { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 }; +``` + + +Sequence Execution +------------------ +Once literals and sequences have been decoded, +they are combined to produce the decoded content of a block. + +Each sequence consists of a tuple of (`literals_length`, `offset_value`, `match_length`), +decoded as described in the [Sequences Section](#sequences-section). +To execute a sequence, first copy `literals_length` bytes +from the decoded literals to the output. + +Then `match_length` bytes are copied from previous decoded data. +The offset to copy from is determined by `offset_value`: +if `offset_value > 3`, then the offset is `offset_value - 3`. +If `offset_value` is from 1-3, the offset is a special repeat offset value. +See the [repeat offset](#repeat-offsets) section for how the offset is determined +in this case. + +The offset is defined as from the current position, so an offset of 6 +and a match length of 3 means that 3 bytes should be copied from 6 bytes back. +Note that all offsets leading to previously decoded data +must be smaller than `Window_Size` defined in `Frame_Header_Descriptor`. + +#### Repeat offsets +As seen in [Sequence Execution](#sequence-execution), +the first 3 values define a repeated offset and we will call them +`Repeated_Offset1`, `Repeated_Offset2`, and `Repeated_Offset3`. +They are sorted in recency order, with `Repeated_Offset1` meaning "most recent one". + +If `offset_value == 1`, then the offset used is `Repeated_Offset1`, etc. + +There is an exception though, when current sequence's `literals_length = 0`. +In this case, repeated offsets are shifted by one, +so an `offset_value` of 1 means `Repeated_Offset2`, +an `offset_value` of 2 means `Repeated_Offset3`, +and an `offset_value` of 3 means `Repeated_Offset1 - 1`. + +In the final case, if `Repeated_Offset1 - 1` evaluates to 0, then the +data is considered corrupted. + +For the first block, the starting offset history is populated with following values : +`Repeated_Offset1`=1, `Repeated_Offset2`=4, `Repeated_Offset3`=8, +unless a dictionary is used, in which case they come from the dictionary. + +Then each block gets its starting offset history from the ending values of the most recent `Compressed_Block`. +Note that blocks which are not `Compressed_Block` are skipped, they do not contribute to offset history. + +[Offset Codes]: #offset-codes + +###### Offset updates rules + +During the execution of the sequences of a `Compressed_Block`, the +`Repeated_Offsets`' values are kept up to date, so that they always represent +the three most-recently used offsets. In order to achieve that, they are +updated after executing each sequence in the following way: + +When the sequence's `offset_value` does not refer to one of the +`Repeated_Offsets`--when it has value greater than 3, or when it has value 3 +and the sequence's `literals_length` is zero--the `Repeated_Offsets`' values +are shifted back one, and `Repeated_Offset1` takes on the value of the +just-used offset. + +Otherwise, when the sequence's `offset_value` refers to one of the +`Repeated_Offsets`--when it has value 1 or 2, or when it has value 3 and the +sequence's `literals_length` is non-zero--the `Repeated_Offsets` are re-ordered +so that `Repeated_Offset1` takes on the value of the used Repeated_Offset, and +the existing values are pushed back from the first `Repeated_Offset` through to +the `Repeated_Offset` selected by the `offset_value`. This effectively performs +a single-stepped wrapping rotation of the values of these offsets, so that +their order again reflects the recency of their use. + +The following table shows the values of the `Repeated_Offsets` as a series of +sequences are applied to them: + +| `offset_value` | `literals_length` | `Repeated_Offset1` | `Repeated_Offset2` | `Repeated_Offset3` | Comment | +|:--------------:|:-----------------:|:------------------:|:------------------:|:------------------:|:-----------------------:| +| | | 1 | 4 | 8 | starting values | +| 1114 | 11 | 1111 | 1 | 4 | non-repeat | +| 1 | 22 | 1111 | 1 | 4 | repeat 1: no change | +| 2225 | 22 | 2222 | 1111 | 1 | non-repeat | +| 1114 | 111 | 1111 | 2222 | 1111 | non-repeat | +| 3336 | 33 | 3333 | 1111 | 2222 | non-repeat | +| 2 | 22 | 1111 | 3333 | 2222 | repeat 2: swap 1 & 2 | +| 3 | 33 | 2222 | 1111 | 3333 | repeat 3: rotate 3 to 1 | +| 3 | 0 | 2221 | 2222 | 1111 | special case : insert `repeat1 - 1` | +| 1 | 0 | 2222 | 2221 | 1111 | == repeat 2 | + + +Skippable Frames +---------------- + +| `Magic_Number` | `Frame_Size` | `User_Data` | +|:--------------:|:------------:|:-----------:| +| 4 bytes | 4 bytes | n bytes | + +Skippable frames allow the insertion of user-defined metadata +into a flow of concatenated frames. + +Skippable frames defined in this specification are compatible with [LZ4] ones. + +[LZ4]:https://lz4.github.io/lz4/ + +From a compliant decoder perspective, skippable frames need just be skipped, +and their content ignored, resuming decoding after the skippable frame. + +It can be noted that a skippable frame +can be used to watermark a stream of concatenated frames +embedding any kind of tracking information (even just a UUID). +Users wary of such possibility should scan the stream of concatenated frames +in an attempt to detect such frame for analysis or removal. + +__`Magic_Number`__ + +4 Bytes, __little-endian__ format. +Value : 0x184D2A5?, which means any value from 0x184D2A50 to 0x184D2A5F. +All 16 values are valid to identify a skippable frame. +This specification doesn't detail any specific tagging for skippable frames. + +__`Frame_Size`__ + +This is the size, in bytes, of the following `User_Data` +(without including the magic number nor the size field itself). +This field is represented using 4 Bytes, __little-endian__ format, unsigned 32-bits. +This means `User_Data` can’t be bigger than (2^32-1) bytes. + +__`User_Data`__ + +The `User_Data` can be anything. Data will just be skipped by the decoder. + + + +Entropy Encoding +---------------- +Two types of entropy encoding are used by the Zstandard format: +FSE, and Huffman coding. +Huffman is used to compress literals, +while FSE is used for all other symbols +(`Literals_Length_Code`, `Match_Length_Code`, offset codes) +and to compress Huffman headers. + + +FSE +--- +FSE, short for Finite State Entropy, is an entropy codec based on [ANS]. +FSE encoding/decoding involves a state that is carried over between symbols. +Decoding must be done in the opposite direction as encoding. +Therefore, all FSE bitstreams are read from end to beginning. +Note that the order of the bits in the stream is not reversed, +we just read each multi-bits element in the reverse order they are encoded. + +For additional details on FSE, see [Finite State Entropy]. + +[Finite State Entropy]:https://github.com/Cyan4973/FiniteStateEntropy/ + +FSE decoding is directed by a decoding table with a power of 2 size, each row containing three elements: +`Symbol`, `Num_Bits`, and `Baseline`. +The `log2` of the table size is its `Accuracy_Log`. +An FSE state value represents an index in this table. + +To obtain the initial state value, consume `Accuracy_Log` bits from the stream as a __little-endian__ value. +The first symbol in the stream is the `Symbol` indicated in the table for that state. +To obtain the next state value, +the decoder should consume `Num_Bits` bits from the stream as a __little-endian__ value and add it to `Baseline`. + +[ANS]: https://en.wikipedia.org/wiki/Asymmetric_Numeral_Systems + +### FSE Table Description +To decode an FSE bitstream, it is necessary to build its FSE decoding table. +The decoding table is derived from a distribution of Probabilities. +The Zstandard format encodes distributions of Probabilities as follows: + +The distribution of probabilities is described in a bitstream which is read forward, +in __little-endian__ fashion. +The amount of bytes consumed from the bitstream to describe the distribution +is discovered at the end of the decoding process. + +The bitstream starts by reporting on which scale the distribution operates. +Let's `low4Bits` designate the lowest 4 bits of the first byte : +`Accuracy_Log = low4bits + 5`. + +An FSE distribution table describes the probabilities of all symbols +from `0` to the last present one (included) in natural order. +The sum of probabilities is normalized to reach a power of 2 total of `1 << Accuracy_Log` . +There must be two or more symbols with non-zero probabilities. + +The number of bits used to decode each probability is variable. +It depends on : + +- Remaining probabilities + 1 : + __example__ : + Presuming an `Accuracy_Log` of 8, + and presuming 100 probability points have already been distributed, + the decoder may read any value from `0` to `256 - 100 + 1 == 157` (inclusive). + Therefore, it may read up to `log2sup(157) == 8` bits, where `log2sup(N)` + is the smallest integer `T` that satisfies `(1 << T) > N`. + +- Value decoded : small values use 1 less bit : + __example__ : + Presuming values from 0 to 157 (inclusive) are possible, + 255-157 = 98 values are remaining in an 8-bits field. + They are used this way : + first 98 values (hence from 0 to 97) use only 7 bits, + values from 98 to 157 use 8 bits. + This is achieved through this scheme : + + | 8-bit field read | Value decoded | Nb of bits consumed | + | ---------------- | ------------- | ------------------- | + | 0 - 97 | 0 - 97 | 7 | + | 98 - 127 | 98 - 127 | 8 | + | 128 - 225 | 0 - 97 | 7 | + | 226 - 255 | 128 - 157 | 8 | + +Probability is derived from Value decoded using the following formula: +`Probality = Value - 1` + +Consequently, a Probability of `0` is described by a Value `1`. + +A Value `0` is used to signal a special case, named "Probability `-1`". +It describes a probability which should have been "less than 1". +Its effect on the decoding table building process is described in the [next section]. +For the purpose of counting total allocated probability points, it counts as one. + +[next section]:#from-normalized-distribution-to-decoding-tables + +Symbols probabilities are read one by one, in order. +After each probability is decoded, the total nb of probability points is updated. +This is used to determine how many bits must be read to decode the probability of next symbol. + +When a symbol has a __probability__ of `zero` (decoded from reading a Value `1`), +it is followed by a 2-bits repeat flag. +This repeat flag tells how many probabilities of zeroes follow the current one. +It provides a number ranging from 0 to 3. +If it is a 3, another 2-bits repeat flag follows, and so on. + +When the Probability for a symbol makes cumulated total reach `1 << Accuracy_Log`, +then it's the last symbol, and decoding is complete. + +Then the decoder can tell how many bytes were used in this process, +and how many symbols are present. +The bitstream consumes a round number of bytes. +Any remaining bit within the last byte is just unused. + +If this process results in a non-zero probability for a symbol outside of the +valid range of symbols that the FSE table is defined for, even if that symbol is +not used, then the data is considered corrupted. +For the specific case of offset codes, +a decoder implementation may reject a frame containing a non-zero probability +for an offset code larger than the largest offset code supported by the decoder +implementation. + +#### From normalized distribution to decoding tables + +The normalized distribution of probabilities is enough +to create a unique decoding table. +It is generated using the following build rule : + +The table has a size of `Table_Size = 1 << Accuracy_Log`. +Each row specifies the decoded symbol, +and instructions to reach the next state (`Number_of_Bits` and `Baseline`). + +Symbols are first scanned in their natural order for "less than 1" probabilities +(previously decoded from a Value of `0`). +Symbols with this special probability are being attributed a single row, +starting from the end of the table and retreating. +These symbols define a full state reset, reading `Accuracy_Log` bits. + +Then, all remaining symbols, sorted in natural order, are allocated rows. +Starting from smallest present symbol, and table position `0`, +each symbol gets allocated as many rows as its probability. + +Row allocation is not linear, it follows this order, in modular arithmetic: +``` +position += (tableSize>>1) + (tableSize>>3) + 3; +position &= tableSize-1; +``` + +Using above ordering rule, each symbol gets allocated as many rows as its probability. +If a position is already occupied by a "less than 1" probability symbol, +it is simply skipped, and the next position is allocated instead. +Once enough rows have been allocated for the current symbol, +the allocation process continues, using the next symbol, in natural order. +This process guarantees that the table is entirely and exactly filled. + +Each row specifies a decoded symbol, and is accessed by current state value. +It also specifies `Number_of_Bits` and `Baseline`, which are required to determine next state value. + +To correctly set these fields, it's necessary to sort all occurrences of each symbol in state value order, +and then attribute N+1 bits to lower rows, and N bits to higher rows, +following the process described below (using an example): + +__Example__ : +Presuming an `Accuracy_Log` of 7, +let's imagine a symbol with a Probability of 5: +it receives 5 rows, corresponding to 5 state values between `0` and `127`. + +In this example, the first state value happens to be `1` (after unspecified previous symbols). +The next 4 states are then determined using above modular arithmetic rule, +which specifies to add `64+16+3 = 83` modulo `128` to jump to next position, +producing the following series: `1`, `84`, `39`, `122`, `77` (modular arithmetic). +(note: the next symbol will then start at `32`). + +These state values are then sorted in natural order, +resulting in the following series: `1`, `39`, `77`, `84`, `122`. + +The next power of 2 after 5 is 8. +Therefore, the probability space will be divided into 8 equal parts. +Since the probability space is `1<<7 = 128` large, each share is `128/8 = 16` large. + +In order to reach 8 shares, the `8-5 = 3` lowest states will count "double", +doubling their shares (32 in width), hence requiring one more bit. + +Baseline is assigned starting from the lowest state using fewer bits, +continuing in natural state order, looping back at the beginning. +Each state takes its allocated range from Baseline, sized by its `Number_of_Bits`. + +| state order | 0 | 1 | 2 | 3 | 4 | +| ---------------- | ----- | ----- | ------ | ---- | ------ | +| state value | 1 | 39 | 77 | 84 | 122 | +| width | 32 | 32 | 32 | 16 | 16 | +| `Number_of_Bits` | 5 | 5 | 5 | 4 | 4 | +| allocation order | 3 | 4 | 5 | 1 | 2 | +| `Baseline` | 32 | 64 | 96 | 0 | 16 | +| range | 32-63 | 64-95 | 96-127 | 0-15 | 16-31 | + +During decoding, the next state value is determined by using current state value as row number, +then reading the required `Number_of_Bits` from the bitstream, and adding the specified `Baseline`. + +Note: +as a trivial example, it follows that, for a symbol with a Probability of `1`, +`Baseline` is necessarily `0`, and `Number_of_Bits` is necessarily `Accuracy_Log`. + +See [Appendix A] to see the outcome of this process applied to the default distributions. + +[Appendix A]: #appendix-a---decoding-tables-for-predefined-codes + + +Huffman Coding +-------------- +Zstandard Huffman-coded streams are read backwards, +similar to the FSE bitstreams. +Therefore, to find the start of the bitstream, it is required to +know the offset of the last byte of the Huffman-coded stream. + +After writing the last bit containing information, the compressor +writes a single `1`-bit and then fills the byte with 0-7 `0` bits of +padding. The last byte of the compressed bitstream cannot be `0` for +that reason. + +When decompressing, the last byte containing the padding is the first +byte to read. The decompressor needs to skip 0-7 initial `0`-bits and +the first `1`-bit it occurs. Afterwards, the useful part of the bitstream +begins. + +The bitstream contains Huffman-coded symbols in __little-endian__ order, +with the codes defined by the method below. + +### Huffman Tree Description + +Prefix coding represents symbols from an a priori known alphabet +by bit sequences (codewords), one codeword for each symbol, +in a manner such that different symbols may be represented +by bit sequences of different lengths, +but a parser can always parse an encoded string +unambiguously symbol-by-symbol. + +Given an alphabet with known symbol frequencies, +the Huffman algorithm allows the construction of an optimal prefix code +using the fewest bits of any possible prefix codes for that alphabet. + +Prefix code must not exceed a maximum code length. +More bits improve accuracy but cost more header size, +and require more memory or more complex decoding operations. +This specification limits maximum code length to 11 bits. + +#### Representation + +All literal symbols from zero (included) to last present one (excluded) +are represented by `Weight` with values from `0` to `Max_Number_of_Bits`. +Transformation from `Weight` to `Number_of_Bits` follows this formula : +``` +Number_of_Bits = Weight ? (Max_Number_of_Bits + 1 - Weight) : 0 +``` +When a literal symbol is not present, it receives a `Weight` of 0. +The least frequent symbol receives a `Weight` of 1. +If no literal has a `Weight` of 1, then the data is considered corrupted. +If there are not at least two literals with non-zero `Weight`, then the data +is considered corrupted. +The most frequent symbol receives a `Weight` anywhere between 1 and 11 (max). +The last symbol's `Weight` is deduced from previously retrieved Weights, +by completing to the nearest power of 2. It's necessarily non 0. +If it's not possible to reach a clean power of 2 with a single `Weight` value, +the Huffman Tree Description is considered invalid. +This final power of 2 gives `Max_Number_of_Bits`, the depth of the current tree. +`Max_Number_of_Bits` must be <= 11, +otherwise the representation is considered corrupted. + +__Example__ : +Let's presume the following Huffman tree must be described : + +| literal symbol | A | B | C | D | E | F | +| ---------------- | --- | --- | --- | --- | --- | --- | +| `Number_of_Bits` | 1 | 2 | 3 | 0 | 4 | 4 | + +The tree depth is 4, since its longest elements uses 4 bits +(longest elements are the ones with smallest frequency). + +All symbols will now receive a `Weight` instead of `Number_of_Bits`. +Weight formula is : +``` +Weight = Number_of_Bits ? (Max_Number_of_Bits + 1 - Number_of_Bits) : 0 +``` +It gives the following series of Weights : + +| literal symbol | A | B | C | D | E | F | +| -------------- | --- | --- | --- | --- | --- | --- | +| `Weight` | 4 | 3 | 2 | 0 | 1 | 1 | + +This list will be sent to the decoder, with the following modifications: + +- `F` will not be listed, because it can be determined from previous symbols +- nor will symbols above `F` as they are all 0 +- on the other hand, all symbols before `A`, starting with `\0`, will be listed, with a Weight of 0. + +The decoder will do the inverse operation : +having collected weights of literal symbols from `A` to `E`, +it knows the last literal, `F`, is present with a non-zero `Weight`. +The `Weight` of `F` can be determined by advancing to the next power of 2. +The sum of `2^(Weight-1)` (excluding 0's) is : +`8 + 4 + 2 + 0 + 1 = 15`. +Nearest larger power of 2 value is 16. +Therefore, `Max_Number_of_Bits = log2(16) = 4` and `Weight[F] = log_2(16 - 15) + 1 = 1`. + +#### Huffman Tree header + +This is a single byte value (0-255), +which describes how the series of weights is encoded. + +- if `headerByte` < 128 : + the series of weights is compressed using FSE (see below). + The length of the FSE-compressed series is equal to `headerByte` (0-127). + +- if `headerByte` >= 128 : + + the series of weights uses a direct representation, + where each `Weight` is encoded directly as a 4 bits field (0-15). + + They are encoded forward, 2 weights to a byte, + first weight taking the top four bits and second one taking the bottom four. + * e.g. the following operations could be used to read the weights: + `Weight[0] = (Byte[0] >> 4), Weight[1] = (Byte[0] & 0xf)`, etc. + + The full representation occupies `Ceiling(Number_of_Weights/2)` bytes, + meaning it uses only full bytes even if `Number_of_Weights` is odd. + + `Number_of_Weights = headerByte - 127`. + * Note that maximum `Number_of_Weights` is 255-127 = 128, + therefore, only up to 128 `Weight` can be encoded using direct representation. + * Since the last non-zero `Weight` is _not_ encoded, + this scheme is compatible with alphabet sizes of up to 129 symbols, + hence including literal symbol 128. + * If any literal symbol > 128 has a non-zero `Weight`, + direct representation is not possible. + In such case, it's necessary to use FSE compression. + + +#### Finite State Entropy (FSE) compression of Huffman weights + +In this case, the series of Huffman weights is compressed using FSE compression. +It's a single bitstream with 2 interleaved states, +sharing a single distribution table. + +To decode an FSE bitstream, it is necessary to know its compressed size. +Compressed size is provided by `headerByte`. +It's also necessary to know its _maximum possible_ decompressed size, +which is `255`, since literal symbols span from `0` to `255`, +and last symbol's `Weight` is not represented. + +An FSE bitstream starts by a header, describing probabilities distribution. +It will create a Decoding Table. +For a list of Huffman weights, the maximum accuracy log is 6 bits. +For more description see the [FSE header description](#fse-table-description) + +The Huffman header compression uses 2 states, +which share the same FSE distribution table. +The first state (`State1`) encodes the even indexed symbols, +and the second (`State2`) encodes the odd indexed symbols. +`State1` is initialized first, and then `State2`, and they take turns +decoding a single symbol and updating their state. +For more details on these FSE operations, see the [FSE section](#fse). + +The number of symbols to decode is determined +by tracking bitStream overflow condition: +If updating state after decoding a symbol would require more bits than +remain in the stream, it is assumed that extra bits are 0. Then, +symbols for each of the final states are decoded and the process is complete. + +If this process would produce more weights than the maximum number of decoded +weights (255), then the data is considered corrupted. + +If either of the 2 initial states are absent or truncated, then the data is +considered corrupted. Consequently, it is not possible to encode fewer than +2 weights using this mode. + +#### Conversion from weights to Huffman prefix codes + +All present symbols shall now have a `Weight` value. +It is possible to transform weights into `Number_of_Bits`, using this formula: +``` +Number_of_Bits = (Weight>0) ? Max_Number_of_Bits + 1 - Weight : 0 +``` +In order to determine which prefix code is assigned to each Symbol, +Symbols are first sorted by `Weight`, then by natural sequential order. +Symbols with a `Weight` of zero are removed. +Then, starting from lowest `Weight` (hence highest `Number_of_Bits`), +prefix codes are assigned in ascending order. + +__Example__ : +Let's assume the following list of weights has been decoded: + +| Literal | A | B | C | D | E | F | +| -------- | --- | --- | --- | --- | --- | --- | +| `Weight` | 4 | 3 | 2 | 0 | 1 | 1 | + +Sorted by weight and then natural sequential order, +it gives the following prefix codes distribution: + +| Literal | D | E | F | C | B | A | +| ---------------- | --- | ---- | ---- | ---- | ---- | ---- | +| `Weight` | 0 | 1 | 1 | 2 | 3 | 4 | +| `Number_of_Bits` | 0 | 4 | 4 | 3 | 2 | 1 | +| prefix code | N/A | 0000 | 0001 | 001 | 01 | 1 | +| ascending order | N/A | 0000 | 0001 | 001x | 01xx | 1xxx | + +### Huffman-coded Streams + +Given a Huffman decoding table, +it's possible to decode a Huffman-coded stream. + +Each bitstream must be read _backward_, +that is starting from the end down to the beginning. +Therefore it's necessary to know the size of each bitstream. + +It's also necessary to know exactly which _bit_ is the last one. +This is detected by a final bit flag : +the highest bit of latest byte is a final-bit-flag. +Consequently, a last byte of `0` is not possible. +And the final-bit-flag itself is not part of the useful bitstream. +Hence, the last byte contains between 0 and 7 useful bits. + +Starting from the end, +it's possible to read the bitstream in a __little-endian__ fashion, +keeping track of already used bits. Since the bitstream is encoded in reverse +order, starting from the end read symbols in forward order. + +For example, if the literal sequence `ABEF` was encoded using above prefix code, +it would be encoded (in reverse order) as: + +|Symbol | F | E | B | A | Padding | +|--------|------|------|----|---|---------| +|Encoding|`0000`|`0001`|`01`|`1`| `00001` | + +Resulting in following 2-bytes bitstream : +``` +00010000 00001101 +``` + +Here is an alternative representation with the symbol codes separated by underscore: +``` +0001_0000 00001_1_01 +``` + +Reading highest `Max_Number_of_Bits` bits, +it's possible to compare extracted value to decoding table, +determining the symbol to decode and number of bits to discard. + +The process continues up to reading the required number of symbols per stream. +If a bitstream is not entirely and exactly consumed, +hence reaching exactly its beginning position with _all_ bits consumed, +the decoding process is considered faulty. + + +Dictionary Format +----------------- + +Zstandard is compatible with "raw content" dictionaries, +free of any format restriction, except that they must be at least 8 bytes. +These dictionaries function as if they were just the `Content` part +of a formatted dictionary. + +But dictionaries created by `zstd --train` follow a format, described here. + +__Pre-requisites__ : a dictionary has a size, + defined either by a buffer limit, or a file size. + +| `Magic_Number` | `Dictionary_ID` | `Entropy_Tables` | `Content` | +| -------------- | --------------- | ---------------- | --------- | + +__`Magic_Number`__ : 4 bytes ID, value 0xEC30A437, __little-endian__ format + +__`Dictionary_ID`__ : 4 bytes, stored in __little-endian__ format. + `Dictionary_ID` can be any value, except 0 (which means no `Dictionary_ID`). + It's used by decoders to check if they use the correct dictionary. + +_Reserved ranges :_ +If the dictionary is going to be distributed in a public environment, +the following ranges of `Dictionary_ID` are reserved for some future registrar +and shall not be used : + + - low range : <= 32767 + - high range : >= (2^31) + +Outside of these ranges, any value of `Dictionary_ID` +which is both `>= 32768` and `< (1<<31)` can be used freely, +even in public environment. + + +__`Entropy_Tables`__ : follow the same format as tables in [compressed blocks]. + See the relevant [FSE](#fse-table-description) + and [Huffman](#huffman-tree-description) sections for how to decode these tables. + They are stored in following order : + Huffman tables for literals, FSE table for offsets, + FSE table for match lengths, and FSE table for literals lengths. + These tables populate the Repeat Stats literals mode and + Repeat distribution mode for sequence decoding. + It's finally followed by 3 offset values, populating recent offsets (instead of using `{1,4,8}`), + stored in order, 4-bytes __little-endian__ each, for a total of 12 bytes. + Each recent offset must have a value <= dictionary content size, and cannot equal 0. + +__`Content`__ : The rest of the dictionary is its content. + The content act as a "past" in front of data to compress or decompress, + so it can be referenced in sequence commands. + As long as the amount of data decoded from this frame is less than or + equal to `Window_Size`, sequence commands may specify offsets longer + than the total length of decoded output so far to reference back to the + dictionary, even parts of the dictionary with offsets larger than `Window_Size`. + After the total output has surpassed `Window_Size` however, + this is no longer allowed and the dictionary is no longer accessible. + +[compressed blocks]: #the-format-of-compressed_block + +If a dictionary is provided by an external source, +it should be loaded with great care, its content considered untrusted. + + + +Appendix A - Decoding tables for predefined codes +------------------------------------------------- + +This appendix contains FSE decoding tables +for the predefined literal length, match length, and offset codes. +The tables have been constructed using the algorithm as given above in chapter +"from normalized distribution to decoding tables". +The tables here can be used as examples +to crosscheck that an implementation build its decoding tables correctly. + +#### Literal Length Code: + +| State | Symbol | Number_Of_Bits | Base | +| ----- | ------ | -------------- | ---- | +| 0 | 0 | 4 | 0 | +| 1 | 0 | 4 | 16 | +| 2 | 1 | 5 | 32 | +| 3 | 3 | 5 | 0 | +| 4 | 4 | 5 | 0 | +| 5 | 6 | 5 | 0 | +| 6 | 7 | 5 | 0 | +| 7 | 9 | 5 | 0 | +| 8 | 10 | 5 | 0 | +| 9 | 12 | 5 | 0 | +| 10 | 14 | 6 | 0 | +| 11 | 16 | 5 | 0 | +| 12 | 18 | 5 | 0 | +| 13 | 19 | 5 | 0 | +| 14 | 21 | 5 | 0 | +| 15 | 22 | 5 | 0 | +| 16 | 24 | 5 | 0 | +| 17 | 25 | 5 | 32 | +| 18 | 26 | 5 | 0 | +| 19 | 27 | 6 | 0 | +| 20 | 29 | 6 | 0 | +| 21 | 31 | 6 | 0 | +| 22 | 0 | 4 | 32 | +| 23 | 1 | 4 | 0 | +| 24 | 2 | 5 | 0 | +| 25 | 4 | 5 | 32 | +| 26 | 5 | 5 | 0 | +| 27 | 7 | 5 | 32 | +| 28 | 8 | 5 | 0 | +| 29 | 10 | 5 | 32 | +| 30 | 11 | 5 | 0 | +| 31 | 13 | 6 | 0 | +| 32 | 16 | 5 | 32 | +| 33 | 17 | 5 | 0 | +| 34 | 19 | 5 | 32 | +| 35 | 20 | 5 | 0 | +| 36 | 22 | 5 | 32 | +| 37 | 23 | 5 | 0 | +| 38 | 25 | 4 | 0 | +| 39 | 25 | 4 | 16 | +| 40 | 26 | 5 | 32 | +| 41 | 28 | 6 | 0 | +| 42 | 30 | 6 | 0 | +| 43 | 0 | 4 | 48 | +| 44 | 1 | 4 | 16 | +| 45 | 2 | 5 | 32 | +| 46 | 3 | 5 | 32 | +| 47 | 5 | 5 | 32 | +| 48 | 6 | 5 | 32 | +| 49 | 8 | 5 | 32 | +| 50 | 9 | 5 | 32 | +| 51 | 11 | 5 | 32 | +| 52 | 12 | 5 | 32 | +| 53 | 15 | 6 | 0 | +| 54 | 17 | 5 | 32 | +| 55 | 18 | 5 | 32 | +| 56 | 20 | 5 | 32 | +| 57 | 21 | 5 | 32 | +| 58 | 23 | 5 | 32 | +| 59 | 24 | 5 | 32 | +| 60 | 35 | 6 | 0 | +| 61 | 34 | 6 | 0 | +| 62 | 33 | 6 | 0 | +| 63 | 32 | 6 | 0 | + +#### Match Length Code: + +| State | Symbol | Number_Of_Bits | Base | +| ----- | ------ | -------------- | ---- | +| 0 | 0 | 6 | 0 | +| 1 | 1 | 4 | 0 | +| 2 | 2 | 5 | 32 | +| 3 | 3 | 5 | 0 | +| 4 | 5 | 5 | 0 | +| 5 | 6 | 5 | 0 | +| 6 | 8 | 5 | 0 | +| 7 | 10 | 6 | 0 | +| 8 | 13 | 6 | 0 | +| 9 | 16 | 6 | 0 | +| 10 | 19 | 6 | 0 | +| 11 | 22 | 6 | 0 | +| 12 | 25 | 6 | 0 | +| 13 | 28 | 6 | 0 | +| 14 | 31 | 6 | 0 | +| 15 | 33 | 6 | 0 | +| 16 | 35 | 6 | 0 | +| 17 | 37 | 6 | 0 | +| 18 | 39 | 6 | 0 | +| 19 | 41 | 6 | 0 | +| 20 | 43 | 6 | 0 | +| 21 | 45 | 6 | 0 | +| 22 | 1 | 4 | 16 | +| 23 | 2 | 4 | 0 | +| 24 | 3 | 5 | 32 | +| 25 | 4 | 5 | 0 | +| 26 | 6 | 5 | 32 | +| 27 | 7 | 5 | 0 | +| 28 | 9 | 6 | 0 | +| 29 | 12 | 6 | 0 | +| 30 | 15 | 6 | 0 | +| 31 | 18 | 6 | 0 | +| 32 | 21 | 6 | 0 | +| 33 | 24 | 6 | 0 | +| 34 | 27 | 6 | 0 | +| 35 | 30 | 6 | 0 | +| 36 | 32 | 6 | 0 | +| 37 | 34 | 6 | 0 | +| 38 | 36 | 6 | 0 | +| 39 | 38 | 6 | 0 | +| 40 | 40 | 6 | 0 | +| 41 | 42 | 6 | 0 | +| 42 | 44 | 6 | 0 | +| 43 | 1 | 4 | 32 | +| 44 | 1 | 4 | 48 | +| 45 | 2 | 4 | 16 | +| 46 | 4 | 5 | 32 | +| 47 | 5 | 5 | 32 | +| 48 | 7 | 5 | 32 | +| 49 | 8 | 5 | 32 | +| 50 | 11 | 6 | 0 | +| 51 | 14 | 6 | 0 | +| 52 | 17 | 6 | 0 | +| 53 | 20 | 6 | 0 | +| 54 | 23 | 6 | 0 | +| 55 | 26 | 6 | 0 | +| 56 | 29 | 6 | 0 | +| 57 | 52 | 6 | 0 | +| 58 | 51 | 6 | 0 | +| 59 | 50 | 6 | 0 | +| 60 | 49 | 6 | 0 | +| 61 | 48 | 6 | 0 | +| 62 | 47 | 6 | 0 | +| 63 | 46 | 6 | 0 | + +#### Offset Code: + +| State | Symbol | Number_Of_Bits | Base | +| ----- | ------ | -------------- | ---- | +| 0 | 0 | 5 | 0 | +| 1 | 6 | 4 | 0 | +| 2 | 9 | 5 | 0 | +| 3 | 15 | 5 | 0 | +| 4 | 21 | 5 | 0 | +| 5 | 3 | 5 | 0 | +| 6 | 7 | 4 | 0 | +| 7 | 12 | 5 | 0 | +| 8 | 18 | 5 | 0 | +| 9 | 23 | 5 | 0 | +| 10 | 5 | 5 | 0 | +| 11 | 8 | 4 | 0 | +| 12 | 14 | 5 | 0 | +| 13 | 20 | 5 | 0 | +| 14 | 2 | 5 | 0 | +| 15 | 7 | 4 | 16 | +| 16 | 11 | 5 | 0 | +| 17 | 17 | 5 | 0 | +| 18 | 22 | 5 | 0 | +| 19 | 4 | 5 | 0 | +| 20 | 8 | 4 | 16 | +| 21 | 13 | 5 | 0 | +| 22 | 19 | 5 | 0 | +| 23 | 1 | 5 | 0 | +| 24 | 6 | 4 | 16 | +| 25 | 10 | 5 | 0 | +| 26 | 16 | 5 | 0 | +| 27 | 28 | 5 | 0 | +| 28 | 27 | 5 | 0 | +| 29 | 26 | 5 | 0 | +| 30 | 25 | 5 | 0 | +| 31 | 24 | 5 | 0 | + + + +Appendix B - Resources for implementers +------------------------------------------------- + +An open source reference implementation is available on : +https://github.com/facebook/zstd + +The project contains a frame generator, called [decodeCorpus], +which can be used by any 3rd-party implementation +to verify that a tested decoder is compliant with the specification. + +[decodeCorpus]: https://github.com/facebook/zstd/tree/v1.3.4/tests#decodecorpus---tool-to-generate-zstandard-frames-for-decoder-testing + +`decodeCorpus` generates random valid frames. +A compliant decoder should be able to decode them all, +or at least provide a meaningful error code explaining for which reason it cannot +(memory limit restrictions for example). + + +Version changes +--------------- +- 0.4.3 : clarifications for Huffman prefix code assignment example +- 0.4.2 : refactor FSE table construction process, inspired by Donald Pian +- 0.4.1 : clarifications on a few error scenarios, by Eric Lasota +- 0.4.0 : fixed imprecise behavior for nbSeq==0, detected by Igor Pavlov +- 0.3.9 : clarifications for Huffman-compressed literal sizes. +- 0.3.8 : clarifications for Huffman Blocks and Huffman Tree descriptions. +- 0.3.7 : clarifications for Repeat_Offsets, matching RFC8878 +- 0.3.6 : clarifications for Dictionary_ID +- 0.3.5 : clarifications for Block_Maximum_Size +- 0.3.4 : clarifications for FSE decoding table +- 0.3.3 : clarifications for field Block_Size +- 0.3.2 : remove additional block size restriction on compressed blocks +- 0.3.1 : minor clarification regarding offset history update rules +- 0.3.0 : minor edits to match RFC8478 +- 0.2.9 : clarifications for huffman weights direct representation, by Ulrich Kunitz +- 0.2.8 : clarifications for IETF RFC discuss +- 0.2.7 : clarifications from IETF RFC review, by Vijay Gurbani and Nick Terrell +- 0.2.6 : fixed an error in huffman example, by Ulrich Kunitz +- 0.2.5 : minor typos and clarifications +- 0.2.4 : section restructuring, by Sean Purcell +- 0.2.3 : clarified several details, by Sean Purcell +- 0.2.2 : added predefined codes, by Johannes Rudolph +- 0.2.1 : clarify field names, by Przemyslaw Skibinski +- 0.2.0 : numerous format adjustments for zstd v0.8+ +- 0.1.2 : limit Huffman tree depth to 11 bits +- 0.1.1 : reserved dictID ranges +- 0.1.0 : initial release diff --git a/cpp/third_party/zstd-1.5.7/doc/zstd_manual.html b/cpp/third_party/zstd-1.5.7/doc/zstd_manual.html new file mode 100644 index 000000000..485d5eafb --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/doc/zstd_manual.html @@ -0,0 +1,2237 @@ + + + +zstd 1.5.7 Manual + + +

zstd 1.5.7 Manual

+Note: the content of this file has been automatically generated by parsing "zstd.h" +
+

Contents

+
    +
  1. Introduction
  2. +
  3. Version
  4. +
  5. Simple Core API
  6. +
  7. Explicit context
  8. +
  9. Advanced compression API (Requires v1.4.0+)
  10. +
  11. Advanced decompression API (Requires v1.4.0+)
  12. +
  13. Streaming
  14. +
  15. Streaming compression - HowTo
  16. +
  17. Streaming decompression - HowTo
  18. +
  19. Simple dictionary API
  20. +
  21. Bulk processing dictionary API
  22. +
  23. Dictionary helper functions
  24. +
  25. Advanced dictionary and prefix API (Requires v1.4.0+)
  26. +
  27. experimental API (static linking only)
  28. +
  29. Frame header and size functions
  30. +
  31. Memory management
  32. +
  33. Advanced compression functions
  34. +
  35. Advanced decompression functions
  36. +
  37. Advanced streaming functions
  38. +
  39. Buffer-less and synchronous inner streaming functions (DEPRECATED)
  40. +
  41. Buffer-less streaming compression (synchronous mode)
  42. +
  43. Buffer-less streaming decompression (synchronous mode)
  44. +
  45. Block level API (DEPRECATED)
  46. +
+
+

Introduction

+  zstd, short for Zstandard, is a fast lossless compression algorithm, targeting
+  real-time compression scenarios at zlib-level and better compression ratios.
+  The zstd compression library provides in-memory compression and decompression
+  functions.
+
+  The library supports regular compression levels from 1 up to ZSTD_maxCLevel(),
+  which is currently 22. Levels >= 20, labeled `--ultra`, should be used with
+  caution, as they require more memory. The library also offers negative
+  compression levels, which extend the range of speed vs. ratio preferences.
+  The lower the level, the faster the speed (at the cost of compression).
+
+  Compression can be done in:
+    - a single step (described as Simple API)
+    - a single step, reusing a context (described as Explicit context)
+    - unbounded multiple steps (described as Streaming compression)
+
+  The compression ratio achievable on small data can be highly improved using
+  a dictionary. Dictionary compression can be performed in:
+    - a single step (described as Simple dictionary API)
+    - a single step, reusing a dictionary (described as Bulk-processing
+      dictionary API)
+
+  Advanced experimental functions can be accessed using
+  `#define ZSTD_STATIC_LINKING_ONLY` before including zstd.h.
+
+  Advanced experimental APIs should never be used with a dynamically-linked
+  library. They are not "stable"; their definitions or signatures may change in
+  the future. Only static linking is allowed.
+
+ +

Version


+
+
unsigned ZSTD_versionNumber(void);
+

Return runtime library version, the value is (MAJOR*100*100 + MINOR*100 + RELEASE). +


+ +
const char* ZSTD_versionString(void);
+

Return runtime library version, like "1.4.5". Requires v1.3.0+. +


+ +

Simple Core API


+
+
size_t ZSTD_compress( void* dst, size_t dstCapacity,
+                const void* src, size_t srcSize,
+                      int compressionLevel);
+

Compresses `src` content as a single zstd compressed frame into already allocated `dst`. + NOTE: Providing `dstCapacity >= ZSTD_compressBound(srcSize)` guarantees that zstd will have + enough space to successfully compress the data. + @return : compressed size written into `dst` (<= `dstCapacity), + or an error code if it fails (which can be tested using ZSTD_isError()). +


+ +
size_t ZSTD_decompress( void* dst, size_t dstCapacity,
+                  const void* src, size_t compressedSize);
+

`compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames. + Multiple compressed frames can be decompressed at once with this method. + The result will be the concatenation of all decompressed frames, back to back. + `dstCapacity` is an upper bound of originalSize to regenerate. + First frame's decompressed size can be extracted using ZSTD_getFrameContentSize(). + If maximum upper bound isn't known, prefer using streaming mode to decompress data. + @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), + or an errorCode if it fails (which can be tested using ZSTD_isError()). +


+ +

Decompression helper functions


+
#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
+#define ZSTD_CONTENTSIZE_ERROR   (0ULL - 2)
+unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
+

`src` should point to the start of a ZSTD encoded frame. + `srcSize` must be at least as large as the frame header. + hint : any size >= `ZSTD_frameHeaderSize_max` is large enough. + @return : - decompressed size of `src` frame content, if known + - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined + - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) + note 1 : a 0 return value means the frame is valid but "empty". + note 2 : decompressed size is an optional field, it may not be present (typically in streaming mode). + When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. + In which case, it's necessary to use streaming mode to decompress data. + Optionally, application can rely on some implicit limit, + as ZSTD_decompress() only needs an upper bound of decompressed size. + (For example, data could be necessarily cut into blocks <= 16 KB). + note 3 : decompressed size is always present when compression is completed using single-pass functions, + such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict(). + note 4 : decompressed size can be very large (64-bits value), + potentially larger than what local system can handle as a single memory segment. + In which case, it's necessary to use streaming mode to decompress data. + note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified. + Always ensure return value fits within application's authorized limits. + Each application can set its own limits. + note 6 : This function replaces ZSTD_getDecompressedSize() +


+ +
ZSTD_DEPRECATED("Replaced by ZSTD_getFrameContentSize")
+ZSTDLIB_API
+unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
+

NOTE: This function is now obsolete, in favor of ZSTD_getFrameContentSize(). + Both functions work the same way, but ZSTD_getDecompressedSize() blends + "empty", "unknown" and "error" results to the same return value (0), + while ZSTD_getFrameContentSize() gives them separate return values. + @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. +


+ +
size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);
+

`src` should point to the start of a ZSTD frame or skippable frame. + `srcSize` must be >= first frame size + @return : the compressed size of the first frame starting at `src`, + suitable to pass as `srcSize` to `ZSTD_decompress` or similar, + or an error code if input is invalid +


+ +

Compression helper functions


+
#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00ULL : 0xFF00FF00U)
+#define ZSTD_COMPRESSBOUND(srcSize)   (((size_t)(srcSize) >= ZSTD_MAX_INPUT_SIZE) ? 0 : (srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0))  /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */
+size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */
+

maximum compressed size in worst case single-pass scenario. + When invoking `ZSTD_compress()`, or any other one-pass compression function, + it's recommended to provide @dstCapacity >= ZSTD_compressBound(srcSize) + as it eliminates one potential failure scenario, + aka not enough room in dst buffer to write the compressed frame. + Note : ZSTD_compressBound() itself can fail, if @srcSize >= ZSTD_MAX_INPUT_SIZE . + In which case, ZSTD_compressBound() will return an error code + which can be tested using ZSTD_isError(). + + ZSTD_COMPRESSBOUND() : + same as ZSTD_compressBound(), but as a macro. + It can be used to produce constants, which can be useful for static allocation, + for example to size a static array on stack. + Will produce constant value 0 if srcSize is too large. + +


+ +

Error helper functions

#include "zstd_errors.h" /* list of errors */
+/* ZSTD_isError() :
+ * Most ZSTD_* functions returning a size_t value can be tested for error,
+ * using ZSTD_isError().
+ * @return 1 if error, 0 otherwise
+ */
+unsigned     ZSTD_isError(size_t result);      /*!< tells if a `size_t` function result is an error code */
+ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); /* convert a result into an error code, which can be compared to error enum list */
+const char*  ZSTD_getErrorName(size_t result); /*!< provides readable string from a function result */
+int          ZSTD_minCLevel(void);             /*!< minimum negative compression level allowed, requires v1.4.0+ */
+int          ZSTD_maxCLevel(void);             /*!< maximum compression level available */
+int          ZSTD_defaultCLevel(void);         /*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */
+

+

Explicit context


+
+

Compression context

  When compressing many times,
+  it is recommended to allocate a compression context just once,
+  and reuse it for each successive compression operation.
+  This will make the workload easier for system's memory.
+  Note : re-using context is just a speed / resource optimization.
+         It doesn't change the compression ratio, which remains identical.
+  Note 2: For parallel execution in multi-threaded environments,
+         use one different context per thread .
+ 
+
typedef struct ZSTD_CCtx_s ZSTD_CCtx;
+ZSTD_CCtx* ZSTD_createCCtx(void);
+size_t     ZSTD_freeCCtx(ZSTD_CCtx* cctx);  /* compatible with NULL pointer */
+

+
size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
+                         void* dst, size_t dstCapacity,
+                   const void* src, size_t srcSize,
+                         int compressionLevel);
+

Same as ZSTD_compress(), using an explicit ZSTD_CCtx. + Important : in order to mirror `ZSTD_compress()` behavior, + this function compresses at the requested compression level, + __ignoring any other advanced parameter__ . + If any advanced parameter was set using the advanced API, + they will all be reset. Only @compressionLevel remains. + +


+ +

Decompression context

  When decompressing many times,
+  it is recommended to allocate a context only once,
+  and reuse it for each successive compression operation.
+  This will make workload friendlier for system's memory.
+  Use one context per thread for parallel execution. 
+
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
+ZSTD_DCtx* ZSTD_createDCtx(void);
+size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);  /* accept NULL pointer */
+

+
size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx,
+                           void* dst, size_t dstCapacity,
+                     const void* src, size_t srcSize);
+

Same as ZSTD_decompress(), + requires an allocated ZSTD_DCtx. + Compatible with sticky parameters (see below). + +


+ +

Advanced compression API (Requires v1.4.0+)


+
+
typedef enum { ZSTD_fast=1,
+               ZSTD_dfast=2,
+               ZSTD_greedy=3,
+               ZSTD_lazy=4,
+               ZSTD_lazy2=5,
+               ZSTD_btlazy2=6,
+               ZSTD_btopt=7,
+               ZSTD_btultra=8,
+               ZSTD_btultra2=9
+               /* note : new strategies _might_ be added in the future.
+                         Only the order (from fast to strong) is guaranteed */
+} ZSTD_strategy;
+

+
typedef enum {
+
+    /* compression parameters
+     * Note: When compressing with a ZSTD_CDict these parameters are superseded
+     * by the parameters used to construct the ZSTD_CDict.
+     * See ZSTD_CCtx_refCDict() for more info (superseded-by-cdict). */
+    ZSTD_c_compressionLevel=100, /* Set compression parameters according to pre-defined cLevel table.
+                              * Note that exact compression parameters are dynamically determined,
+                              * depending on both compression level and srcSize (when known).
+                              * Default level is ZSTD_CLEVEL_DEFAULT==3.
+                              * Special: value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT.
+                              * Note 1 : it's possible to pass a negative compression level.
+                              * Note 2 : setting a level does not automatically set all other compression parameters
+                              *   to default. Setting this will however eventually dynamically impact the compression
+                              *   parameters which have not been manually set. The manually set
+                              *   ones will 'stick'. */
+    /* Advanced compression parameters :
+     * It's possible to pin down compression parameters to some specific values.
+     * In which case, these values are no longer dynamically selected by the compressor */
+    ZSTD_c_windowLog=101,    /* Maximum allowed back-reference distance, expressed as power of 2.
+                              * This will set a memory budget for streaming decompression,
+                              * with larger values requiring more memory
+                              * and typically compressing more.
+                              * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
+                              * Special: value 0 means "use default windowLog".
+                              * Note: Using a windowLog greater than ZSTD_WINDOWLOG_LIMIT_DEFAULT
+                              *       requires explicitly allowing such size at streaming decompression stage. */
+    ZSTD_c_hashLog=102,      /* Size of the initial probe table, as a power of 2.
+                              * Resulting memory usage is (1 << (hashLog+2)).
+                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.
+                              * Larger tables improve compression ratio of strategies <= dFast,
+                              * and improve speed of strategies > dFast.
+                              * Special: value 0 means "use default hashLog". */
+    ZSTD_c_chainLog=103,     /* Size of the multi-probe search table, as a power of 2.
+                              * Resulting memory usage is (1 << (chainLog+2)).
+                              * Must be clamped between ZSTD_CHAINLOG_MIN and ZSTD_CHAINLOG_MAX.
+                              * Larger tables result in better and slower compression.
+                              * This parameter is useless for "fast" strategy.
+                              * It's still useful when using "dfast" strategy,
+                              * in which case it defines a secondary probe table.
+                              * Special: value 0 means "use default chainLog". */
+    ZSTD_c_searchLog=104,    /* Number of search attempts, as a power of 2.
+                              * More attempts result in better and slower compression.
+                              * This parameter is useless for "fast" and "dFast" strategies.
+                              * Special: value 0 means "use default searchLog". */
+    ZSTD_c_minMatch=105,     /* Minimum size of searched matches.
+                              * Note that Zstandard can still find matches of smaller size,
+                              * it just tweaks its search algorithm to look for this size and larger.
+                              * Larger values increase compression and decompression speed, but decrease ratio.
+                              * Must be clamped between ZSTD_MINMATCH_MIN and ZSTD_MINMATCH_MAX.
+                              * Note that currently, for all strategies < btopt, effective minimum is 4.
+                              *                    , for all strategies > fast, effective maximum is 6.
+                              * Special: value 0 means "use default minMatchLength". */
+    ZSTD_c_targetLength=106, /* Impact of this field depends on strategy.
+                              * For strategies btopt, btultra & btultra2:
+                              *     Length of Match considered "good enough" to stop search.
+                              *     Larger values make compression stronger, and slower.
+                              * For strategy fast:
+                              *     Distance between match sampling.
+                              *     Larger values make compression faster, and weaker.
+                              * Special: value 0 means "use default targetLength". */
+    ZSTD_c_strategy=107,     /* See ZSTD_strategy enum definition.
+                              * The higher the value of selected strategy, the more complex it is,
+                              * resulting in stronger and slower compression.
+                              * Special: value 0 means "use default strategy". */
+
+    ZSTD_c_targetCBlockSize=130, /* v1.5.6+
+                                  * Attempts to fit compressed block size into approximately targetCBlockSize.
+                                  * Bound by ZSTD_TARGETCBLOCKSIZE_MIN and ZSTD_TARGETCBLOCKSIZE_MAX.
+                                  * Note that it's not a guarantee, just a convergence target (default:0).
+                                  * No target when targetCBlockSize == 0.
+                                  * This is helpful in low bandwidth streaming environments to improve end-to-end latency,
+                                  * when a client can make use of partial documents (a prominent example being Chrome).
+                                  * Note: this parameter is stable since v1.5.6.
+                                  * It was present as an experimental parameter in earlier versions,
+                                  * but it's not recommended using it with earlier library versions
+                                  * due to massive performance regressions.
+                                  */
+    /* LDM mode parameters */
+    ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching.
+                                     * This parameter is designed to improve compression ratio
+                                     * for large inputs, by finding large matches at long distance.
+                                     * It increases memory usage and window size.
+                                     * Note: enabling this parameter increases default ZSTD_c_windowLog to 128 MB
+                                     * except when expressly set to a different value.
+                                     * Note: will be enabled by default if ZSTD_c_windowLog >= 128 MB and
+                                     * compression strategy >= ZSTD_btopt (== compression level 16+) */
+    ZSTD_c_ldmHashLog=161,   /* Size of the table for long distance matching, as a power of 2.
+                              * Larger values increase memory usage and compression ratio,
+                              * but decrease compression speed.
+                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX
+                              * default: windowlog - 7.
+                              * Special: value 0 means "automatically determine hashlog". */
+    ZSTD_c_ldmMinMatch=162,  /* Minimum match size for long distance matcher.
+                              * Larger/too small values usually decrease compression ratio.
+                              * Must be clamped between ZSTD_LDM_MINMATCH_MIN and ZSTD_LDM_MINMATCH_MAX.
+                              * Special: value 0 means "use default value" (default: 64). */
+    ZSTD_c_ldmBucketSizeLog=163, /* Log size of each bucket in the LDM hash table for collision resolution.
+                              * Larger values improve collision resolution but decrease compression speed.
+                              * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX.
+                              * Special: value 0 means "use default value" (default: 3). */
+    ZSTD_c_ldmHashRateLog=164, /* Frequency of inserting/looking up entries into the LDM hash table.
+                              * Must be clamped between 0 and (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN).
+                              * Default is MAX(0, (windowLog - ldmHashLog)), optimizing hash table usage.
+                              * Larger values improve compression speed.
+                              * Deviating far from default value will likely result in a compression ratio decrease.
+                              * Special: value 0 means "automatically determine hashRateLog". */
+
+    /* frame parameters */
+    ZSTD_c_contentSizeFlag=200, /* Content size will be written into frame header _whenever known_ (default:1)
+                              * Content size must be known at the beginning of compression.
+                              * This is automatically the case when using ZSTD_compress2(),
+                              * For streaming scenarios, content size must be provided with ZSTD_CCtx_setPledgedSrcSize() */
+    ZSTD_c_checksumFlag=201, /* A 32-bits checksum of content is written at end of frame (default:0) */
+    ZSTD_c_dictIDFlag=202,   /* When applicable, dictionary's ID is written into frame header (default:1) */
+
+    /* multi-threading parameters */
+    /* These parameters are only active if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD).
+     * Otherwise, trying to set any other value than default (0) will be a no-op and return an error.
+     * In a situation where it's unknown if the linked library supports multi-threading or not,
+     * setting ZSTD_c_nbWorkers to any value >= 1 and consulting the return value provides a quick way to check this property.
+     */
+    ZSTD_c_nbWorkers=400,    /* Select how many threads will be spawned to compress in parallel.
+                              * When nbWorkers >= 1, triggers asynchronous mode when invoking ZSTD_compressStream*() :
+                              * ZSTD_compressStream*() consumes input and flush output if possible, but immediately gives back control to caller,
+                              * while compression is performed in parallel, within worker thread(s).
+                              * (note : a strong exception to this rule is when first invocation of ZSTD_compressStream2() sets ZSTD_e_end :
+                              *  in which case, ZSTD_compressStream2() delegates to ZSTD_compress2(), which is always a blocking call).
+                              * More workers improve speed, but also increase memory usage.
+                              * Default value is `0`, aka "single-threaded mode" : no worker is spawned,
+                              * compression is performed inside Caller's thread, and all invocations are blocking */
+    ZSTD_c_jobSize=401,      /* Size of a compression job. This value is enforced only when nbWorkers >= 1.
+                              * Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads.
+                              * 0 means default, which is dynamically determined based on compression parameters.
+                              * Job size must be a minimum of overlap size, or ZSTDMT_JOBSIZE_MIN (= 512 KB), whichever is largest.
+                              * The minimum size is automatically and transparently enforced. */
+    ZSTD_c_overlapLog=402,   /* Control the overlap size, as a fraction of window size.
+                              * The overlap size is an amount of data reloaded from previous job at the beginning of a new job.
+                              * It helps preserve compression ratio, while each job is compressed in parallel.
+                              * This value is enforced only when nbWorkers >= 1.
+                              * Larger values increase compression ratio, but decrease speed.
+                              * Possible values range from 0 to 9 :
+                              * - 0 means "default" : value will be determined by the library, depending on strategy
+                              * - 1 means "no overlap"
+                              * - 9 means "full overlap", using a full window size.
+                              * Each intermediate rank increases/decreases load size by a factor 2 :
+                              * 9: full window;  8: w/2;  7: w/4;  6: w/8;  5:w/16;  4: w/32;  3:w/64;  2:w/128;  1:no overlap;  0:default
+                              * default value varies between 6 and 9, depending on strategy */
+
+    /* note : additional experimental parameters are also available
+     * within the experimental section of the API.
+     * At the time of this writing, they include :
+     * ZSTD_c_rsyncable
+     * ZSTD_c_format
+     * ZSTD_c_forceMaxWindow
+     * ZSTD_c_forceAttachDict
+     * ZSTD_c_literalCompressionMode
+     * ZSTD_c_srcSizeHint
+     * ZSTD_c_enableDedicatedDictSearch
+     * ZSTD_c_stableInBuffer
+     * ZSTD_c_stableOutBuffer
+     * ZSTD_c_blockDelimiters
+     * ZSTD_c_validateSequences
+     * ZSTD_c_blockSplitterLevel
+     * ZSTD_c_splitAfterSequences
+     * ZSTD_c_useRowMatchFinder
+     * ZSTD_c_prefetchCDictTables
+     * ZSTD_c_enableSeqProducerFallback
+     * ZSTD_c_maxBlockSize
+     * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
+     * note : never ever use experimentalParam? names directly;
+     *        also, the enums values themselves are unstable and can still change.
+     */
+     ZSTD_c_experimentalParam1=500,
+     ZSTD_c_experimentalParam2=10,
+     ZSTD_c_experimentalParam3=1000,
+     ZSTD_c_experimentalParam4=1001,
+     ZSTD_c_experimentalParam5=1002,
+     /* was ZSTD_c_experimentalParam6=1003; is now ZSTD_c_targetCBlockSize */
+     ZSTD_c_experimentalParam7=1004,
+     ZSTD_c_experimentalParam8=1005,
+     ZSTD_c_experimentalParam9=1006,
+     ZSTD_c_experimentalParam10=1007,
+     ZSTD_c_experimentalParam11=1008,
+     ZSTD_c_experimentalParam12=1009,
+     ZSTD_c_experimentalParam13=1010,
+     ZSTD_c_experimentalParam14=1011,
+     ZSTD_c_experimentalParam15=1012,
+     ZSTD_c_experimentalParam16=1013,
+     ZSTD_c_experimentalParam17=1014,
+     ZSTD_c_experimentalParam18=1015,
+     ZSTD_c_experimentalParam19=1016,
+     ZSTD_c_experimentalParam20=1017
+} ZSTD_cParameter;
+

+
typedef struct {
+    size_t error;
+    int lowerBound;
+    int upperBound;
+} ZSTD_bounds;
+

+
ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter cParam);
+

All parameters must belong to an interval with lower and upper bounds, + otherwise they will either trigger an error or be automatically clamped. + @return : a structure, ZSTD_bounds, which contains + - an error status field, which must be tested using ZSTD_isError() + - lower and upper bounds, both inclusive + +


+ +
size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value);
+

Set one compression parameter, selected by enum ZSTD_cParameter. + All parameters have valid bounds. Bounds can be queried using ZSTD_cParam_getBounds(). + Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter). + Setting a parameter is generally only possible during frame initialization (before starting compression). + Exception : when using multi-threading mode (nbWorkers >= 1), + the following parameters can be updated _during_ compression (within same frame): + => compressionLevel, hashLog, chainLog, searchLog, minMatch, targetLength and strategy. + new parameters will be active for next job only (after a flush()). + @return : an error code (which can be tested using ZSTD_isError()). + +


+ +
size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
+

Total input data size to be compressed as a single frame. + Value will be written in frame header, unless if explicitly forbidden using ZSTD_c_contentSizeFlag. + This value will also be controlled at end of frame, and trigger an error if not respected. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Note 1 : pledgedSrcSize==0 actually means zero, aka an empty frame. + In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. + ZSTD_CONTENTSIZE_UNKNOWN is default value for any new frame. + Note 2 : pledgedSrcSize is only valid once, for the next frame. + It's discarded at the end of the frame, and replaced by ZSTD_CONTENTSIZE_UNKNOWN. + Note 3 : Whenever all input data is provided and consumed in a single round, + for example with ZSTD_compress2(), + or invoking immediately ZSTD_compressStream2(,,,ZSTD_e_end), + this value is automatically overridden by srcSize instead. + +


+ +
typedef enum {
+    ZSTD_reset_session_only = 1,
+    ZSTD_reset_parameters = 2,
+    ZSTD_reset_session_and_parameters = 3
+} ZSTD_ResetDirective;
+

+
size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset);
+

There are 2 different things that can be reset, independently or jointly : + - The session : will stop compressing current frame, and make CCtx ready to start a new one. + Useful after an error, or to interrupt any ongoing compression. + Any internal data not yet flushed is cancelled. + Compression parameters and dictionary remain unchanged. + They will be used to compress next frame. + Resetting session never fails. + - The parameters : changes all parameters back to "default". + This also removes any reference to any dictionary or external sequence producer. + Parameters can only be changed between 2 sessions (i.e. no compression is currently ongoing) + otherwise the reset fails, and function returns an error value (which can be tested using ZSTD_isError()) + - Both : similar to resetting the session, followed by resetting parameters. + +


+ +
size_t ZSTD_compress2( ZSTD_CCtx* cctx,
+                       void* dst, size_t dstCapacity,
+                 const void* src, size_t srcSize);
+

Behave the same as ZSTD_compressCCtx(), but compression parameters are set using the advanced API. + (note that this entry point doesn't even expose a compression level parameter). + ZSTD_compress2() always starts a new frame. + Should cctx hold data from a previously unfinished frame, everything about it is forgotten. + - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*() + - The function is always blocking, returns when compression is completed. + NOTE: Providing `dstCapacity >= ZSTD_compressBound(srcSize)` guarantees that zstd will have + enough space to successfully compress the data, though it is possible it fails for other reasons. + @return : compressed size written into `dst` (<= `dstCapacity), + or an error code if it fails (which can be tested using ZSTD_isError()). + +


+ +

Advanced decompression API (Requires v1.4.0+)


+
+
typedef enum {
+
+    ZSTD_d_windowLogMax=100, /* Select a size limit (in power of 2) beyond which
+                              * the streaming API will refuse to allocate memory buffer
+                              * in order to protect the host from unreasonable memory requirements.
+                              * This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode.
+                              * By default, a decompression context accepts window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT).
+                              * Special: value 0 means "use default maximum windowLog". */
+
+    /* note : additional experimental parameters are also available
+     * within the experimental section of the API.
+     * At the time of this writing, they include :
+     * ZSTD_d_format
+     * ZSTD_d_stableOutBuffer
+     * ZSTD_d_forceIgnoreChecksum
+     * ZSTD_d_refMultipleDDicts
+     * ZSTD_d_disableHuffmanAssembly
+     * ZSTD_d_maxBlockSize
+     * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
+     * note : never ever use experimentalParam? names directly
+     */
+     ZSTD_d_experimentalParam1=1000,
+     ZSTD_d_experimentalParam2=1001,
+     ZSTD_d_experimentalParam3=1002,
+     ZSTD_d_experimentalParam4=1003,
+     ZSTD_d_experimentalParam5=1004,
+     ZSTD_d_experimentalParam6=1005
+
+} ZSTD_dParameter;
+

+
ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam);
+

All parameters must belong to an interval with lower and upper bounds, + otherwise they will either trigger an error or be automatically clamped. + @return : a structure, ZSTD_bounds, which contains + - an error status field, which must be tested using ZSTD_isError() + - both lower and upper bounds, inclusive + +


+ +
size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int value);
+

Set one compression parameter, selected by enum ZSTD_dParameter. + All parameters have valid bounds. Bounds can be queried using ZSTD_dParam_getBounds(). + Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter). + Setting a parameter is only possible during frame initialization (before starting decompression). + @return : 0, or an error code (which can be tested using ZSTD_isError()). + +


+ +
size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset);
+

Return a DCtx to clean state. + Session and parameters can be reset jointly or separately. + Parameters can only be reset when no active frame is being decompressed. + @return : 0, or an error code, which can be tested with ZSTD_isError() + +


+ +

Streaming


+
+
typedef struct ZSTD_inBuffer_s {
+  const void* src;    /**< start of input buffer */
+  size_t size;        /**< size of input buffer */
+  size_t pos;         /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_inBuffer;
+

+
typedef struct ZSTD_outBuffer_s {
+  void*  dst;         /**< start of output buffer */
+  size_t size;        /**< size of output buffer */
+  size_t pos;         /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_outBuffer;
+

+

Streaming compression - HowTo

+  A ZSTD_CStream object is required to track streaming operation.
+  Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
+  ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
+  It is recommended to reuse ZSTD_CStream since it will play nicer with system's memory, by re-using already allocated memory.
+
+  For parallel execution, use one separate ZSTD_CStream per thread.
+
+  note : since v1.3.0, ZSTD_CStream and ZSTD_CCtx are the same thing.
+
+  Parameters are sticky : when starting a new compression on the same context,
+  it will reuse the same sticky parameters as previous compression session.
+  When in doubt, it's recommended to fully initialize the context before usage.
+  Use ZSTD_CCtx_reset() to reset the context and ZSTD_CCtx_setParameter(),
+  ZSTD_CCtx_setPledgedSrcSize(), or ZSTD_CCtx_loadDictionary() and friends to
+  set more specific parameters, the pledged source size, or load a dictionary.
+
+  Use ZSTD_compressStream2() with ZSTD_e_continue as many times as necessary to
+  consume input stream. The function will automatically update both `pos`
+  fields within `input` and `output`.
+  Note that the function may not consume the entire input, for example, because
+  the output buffer is already full, in which case `input.pos < input.size`.
+  The caller must check if input has been entirely consumed.
+  If not, the caller must make some room to receive more compressed data,
+  and then present again remaining input data.
+  note: ZSTD_e_continue is guaranteed to make some forward progress when called,
+        but doesn't guarantee maximal forward progress. This is especially relevant
+        when compressing with multiple threads. The call won't block if it can
+        consume some input, but if it can't it will wait for some, but not all,
+        output to be flushed.
+ @return : provides a minimum amount of data remaining to be flushed from internal buffers
+           or an error code, which can be tested using ZSTD_isError().
+
+  At any moment, it's possible to flush whatever data might remain stuck within internal buffer,
+  using ZSTD_compressStream2() with ZSTD_e_flush. `output->pos` will be updated.
+  Note that, if `output->size` is too small, a single invocation with ZSTD_e_flush might not be enough (return code > 0).
+  In which case, make some room to receive more compressed data, and call again ZSTD_compressStream2() with ZSTD_e_flush.
+  You must continue calling ZSTD_compressStream2() with ZSTD_e_flush until it returns 0, at which point you can change the
+  operation.
+  note: ZSTD_e_flush will flush as much output as possible, meaning when compressing with multiple threads, it will
+        block until the flush is complete or the output buffer is full.
+  @return : 0 if internal buffers are entirely flushed,
+            >0 if some data still present within internal buffer (the value is minimal estimation of remaining size),
+            or an error code, which can be tested using ZSTD_isError().
+
+  Calling ZSTD_compressStream2() with ZSTD_e_end instructs to finish a frame.
+  It will perform a flush and write frame epilogue.
+  The epilogue is required for decoders to consider a frame completed.
+  flush operation is the same, and follows same rules as calling ZSTD_compressStream2() with ZSTD_e_flush.
+  You must continue calling ZSTD_compressStream2() with ZSTD_e_end until it returns 0, at which point you are free to
+  start a new frame.
+  note: ZSTD_e_end will flush as much output as possible, meaning when compressing with multiple threads, it will
+        block until the flush is complete or the output buffer is full.
+  @return : 0 if frame fully completed and fully flushed,
+            >0 if some data still present within internal buffer (the value is minimal estimation of remaining size),
+            or an error code, which can be tested using ZSTD_isError().
+
+ 
+
+ +
typedef ZSTD_CCtx ZSTD_CStream;  /**< CCtx and CStream are now effectively same object (>= v1.3.0) */
+

+

ZSTD_CStream management functions

ZSTD_CStream* ZSTD_createCStream(void);
+size_t ZSTD_freeCStream(ZSTD_CStream* zcs);  /* accept NULL pointer */
+

+

Streaming compression functions

typedef enum {
+    ZSTD_e_continue=0, /* collect more data, encoder decides when to output compressed result, for optimal compression ratio */
+    ZSTD_e_flush=1,    /* flush any data provided so far,
+                        * it creates (at least) one new block, that can be decoded immediately on reception;
+                        * frame will continue: any future data can still reference previously compressed data, improving compression.
+                        * note : multithreaded compression will block to flush as much output as possible. */
+    ZSTD_e_end=2       /* flush any remaining data _and_ close current frame.
+                        * note that frame is only closed after compressed data is fully flushed (return value == 0).
+                        * After that point, any additional data starts a new frame.
+                        * note : each frame is independent (does not reference any content from previous frame).
+                        : note : multithreaded compression will block to flush as much output as possible. */
+} ZSTD_EndDirective;
+

+
size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
+                             ZSTD_outBuffer* output,
+                             ZSTD_inBuffer* input,
+                             ZSTD_EndDirective endOp);
+

Behaves about the same as ZSTD_compressStream, with additional control on end directive. + - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*() + - Compression parameters cannot be changed once compression is started (save a list of exceptions in multi-threading mode) + - output->pos must be <= dstCapacity, input->pos must be <= srcSize + - output->pos and input->pos will be updated. They are guaranteed to remain below their respective limit. + - endOp must be a valid directive + - When nbWorkers==0 (default), function is blocking : it completes its job before returning to caller. + - When nbWorkers>=1, function is non-blocking : it copies a portion of input, distributes jobs to internal worker threads, flush to output whatever is available, + and then immediately returns, just indicating that there is some data remaining to be flushed. + The function nonetheless guarantees forward progress : it will return only after it reads or write at least 1+ byte. + - Exception : if the first call requests a ZSTD_e_end directive and provides enough dstCapacity, the function delegates to ZSTD_compress2() which is always blocking. + - @return provides a minimum amount of data remaining to be flushed from internal buffers + or an error code, which can be tested using ZSTD_isError(). + if @return != 0, flush is not fully completed, there is still some data left within internal buffers. + This is useful for ZSTD_e_flush, since in this case more flushes are necessary to empty all buffers. + For ZSTD_e_end, @return == 0 when internal buffers are fully flushed and frame is completed. + - after a ZSTD_e_end directive, if internal buffer is not fully flushed (@return != 0), + only ZSTD_e_end or ZSTD_e_flush operations are allowed. + Before starting a new compression job, or changing compression parameters, + it is required to fully flush internal buffers. + - note: if an operation ends with an error, it may leave @cctx in an undefined state. + Therefore, it's UB to invoke ZSTD_compressStream2() of ZSTD_compressStream() on such a state. + In order to be re-employed after an error, a state must be reset, + which can be done explicitly (ZSTD_CCtx_reset()), + or is sometimes implied by methods starting a new compression job (ZSTD_initCStream(), ZSTD_compressCCtx()) + +


+ +
size_t ZSTD_CStreamInSize(void);    /**< recommended size for input buffer */
+

+
size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block. */
+

+
size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
+/*!
+ * Alternative for ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue).
+ * NOTE: The return value is different. ZSTD_compressStream() returns a hint for
+ * the next read size (if non-zero and not an error). ZSTD_compressStream2()
+ * returns the minimum nb of bytes left to flush (if non-zero and not an error).
+ */
+size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+/*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_flush). */
+size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+/*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_end). */
+size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+

+ ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any) + ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel); + + Note that ZSTD_initCStream() clears any previously set dictionary. Use the new API + to compress with a dictionary. + +


+ +

Streaming decompression - HowTo

+  A ZSTD_DStream object is required to track streaming operations.
+  Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
+  ZSTD_DStream objects can be re-employed multiple times.
+
+  Use ZSTD_initDStream() to start a new decompression operation.
+ @return : recommended first input size
+  Alternatively, use advanced API to set specific properties.
+
+  Use ZSTD_decompressStream() repetitively to consume your input.
+  The function will update both `pos` fields.
+  If `input.pos < input.size`, some input has not been consumed.
+  It's up to the caller to present again remaining data.
+
+  The function tries to flush all data decoded immediately, respecting output buffer size.
+  If `output.pos < output.size`, decoder has flushed everything it could.
+
+  However, when `output.pos == output.size`, it's more difficult to know.
+  If @return > 0, the frame is not complete, meaning
+  either there is still some data left to flush within internal buffers,
+  or there is more input to read to complete the frame (or both).
+  In which case, call ZSTD_decompressStream() again to flush whatever remains in the buffer.
+  Note : with no additional input provided, amount of data flushed is necessarily <= ZSTD_BLOCKSIZE_MAX.
+ @return : 0 when a frame is completely decoded and fully flushed,
+        or an error code, which can be tested using ZSTD_isError(),
+        or any other value > 0, which means there is still some decoding or flushing to do to complete current frame :
+                                the return value is a suggested next input size (just a hint for better latency)
+                                that will never request more than the remaining content of the compressed frame.
+ 
+
+ +
typedef ZSTD_DCtx ZSTD_DStream;  /**< DCtx and DStream are now effectively same object (>= v1.3.0) */
+

+

ZSTD_DStream management functions

ZSTD_DStream* ZSTD_createDStream(void);
+size_t ZSTD_freeDStream(ZSTD_DStream* zds);  /* accept NULL pointer */
+

+

Streaming decompression functions


+
size_t ZSTD_initDStream(ZSTD_DStream* zds);
+

Initialize/reset DStream state for new decompression operation. + Call before new decompression operation using same DStream. + + Note : This function is redundant with the advanced API and equivalent to: + ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); + ZSTD_DCtx_refDDict(zds, NULL); + +


+ +
size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+

Streaming decompression function. + Call repetitively to consume full input updating it as necessary. + Function will update both input and output `pos` fields exposing current state via these fields: + - `input.pos < input.size`, some input remaining and caller should provide remaining input + on the next call. + - `output.pos < output.size`, decoder flushed internal output buffer. + - `output.pos == output.size`, unflushed data potentially present in the internal buffers, + check ZSTD_decompressStream() @return value, + if > 0, invoke it again to flush remaining data to output. + Note : with no additional input, amount of data flushed <= ZSTD_BLOCKSIZE_MAX. + + @return : 0 when a frame is completely decoded and fully flushed, + or an error code, which can be tested using ZSTD_isError(), + or any other value > 0, which means there is some decoding or flushing to do to complete current frame. + + Note: when an operation returns with an error code, the @zds state may be left in undefined state. + It's UB to invoke `ZSTD_decompressStream()` on such a state. + In order to re-use such a state, it must be first reset, + which can be done explicitly (`ZSTD_DCtx_reset()`), + or is implied for operations starting some new decompression job (`ZSTD_initDStream`, `ZSTD_decompressDCtx()`, `ZSTD_decompress_usingDict()`) + +


+ +
size_t ZSTD_DStreamInSize(void);    /*!< recommended size for input buffer */
+

+
size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
+

+

Simple dictionary API


+
+
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
+                               void* dst, size_t dstCapacity,
+                         const void* src, size_t srcSize,
+                         const void* dict,size_t dictSize,
+                               int compressionLevel);
+

Compression at an explicit compression level using a Dictionary. + A dictionary can be any arbitrary data segment (also called a prefix), + or a buffer with specified information (see zdict.h). + Note : This function loads the dictionary, resulting in significant startup delay. + It's intended for a dictionary used only once. + Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used. +


+ +
size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
+                                 void* dst, size_t dstCapacity,
+                           const void* src, size_t srcSize,
+                           const void* dict,size_t dictSize);
+

Decompression using a known Dictionary. + Dictionary must be identical to the one used during compression. + Note : This function loads the dictionary, resulting in significant startup delay. + It's intended for a dictionary used only once. + Note : When `dict == NULL || dictSize < 8` no dictionary is used. +


+ +

Bulk processing dictionary API


+
+
ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,
+                             int compressionLevel);
+

When compressing multiple messages or blocks using the same dictionary, + it's recommended to digest the dictionary only once, since it's a costly operation. + ZSTD_createCDict() will create a state from digesting a dictionary. + The resulting state can be used for future compression operations with very limited startup cost. + ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only. + @dictBuffer can be released after ZSTD_CDict creation, because its content is copied within CDict. + Note 1 : Consider experimental function `ZSTD_createCDict_byReference()` if you prefer to not duplicate @dictBuffer content. + Note 2 : A ZSTD_CDict can be created from an empty @dictBuffer, + in which case the only thing that it transports is the @compressionLevel. + This can be useful in a pipeline featuring ZSTD_compress_usingCDict() exclusively, + expecting a ZSTD_CDict parameter with any data, including those without a known dictionary. +


+ +
size_t      ZSTD_freeCDict(ZSTD_CDict* CDict);
+

Function frees memory allocated by ZSTD_createCDict(). + If a NULL pointer is passed, no operation is performed. +


+ +
size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
+                                void* dst, size_t dstCapacity,
+                          const void* src, size_t srcSize,
+                          const ZSTD_CDict* cdict);
+

Compression using a digested Dictionary. + Recommended when same dictionary is used multiple times. + Note : compression level is _decided at dictionary creation time_, + and frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) +


+ +
ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize);
+

Create a digested dictionary, ready to start decompression operation without startup delay. + dictBuffer can be released after DDict creation, as its content is copied inside DDict. +


+ +
size_t      ZSTD_freeDDict(ZSTD_DDict* ddict);
+

Function frees memory allocated with ZSTD_createDDict() + If a NULL pointer is passed, no operation is performed. +


+ +
size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
+                                  void* dst, size_t dstCapacity,
+                            const void* src, size_t srcSize,
+                            const ZSTD_DDict* ddict);
+

Decompression using a digested Dictionary. + Recommended when same dictionary is used multiple times. +


+ +

Dictionary helper functions


+
+
unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
+

Provides the dictID stored within dictionary. + if @return == 0, the dictionary is not conformant with Zstandard specification. + It can still be loaded, but as a content-only dictionary. +


+ +
unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict);
+

Provides the dictID of the dictionary loaded into `cdict`. + If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + Non-conformant dictionaries can still be loaded, but as content-only dictionaries. +


+ +
unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
+

Provides the dictID of the dictionary loaded into `ddict`. + If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + Non-conformant dictionaries can still be loaded, but as content-only dictionaries. +


+ +
unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
+

Provides the dictID required to decompressed the frame stored within `src`. + If @return == 0, the dictID could not be decoded. + This could for one of the following reasons : + - The frame does not require a dictionary to be decoded (most common case). + - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden piece of information. + Note : this use case also happens when using a non-conformant dictionary. + - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + - This is not a Zstandard frame. + When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. +


+ +

Advanced dictionary and prefix API (Requires v1.4.0+)

+ This API allows dictionaries to be used with ZSTD_compress2(),
+ ZSTD_compressStream2(), and ZSTD_decompressDCtx().
+ Dictionaries are sticky, they remain valid when same context is reused,
+ they only reset when the context is reset
+ with ZSTD_reset_parameters or ZSTD_reset_session_and_parameters.
+ In contrast, Prefixes are single-use.
+
+ +
size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+

Create an internal CDict from `dict` buffer. + Decompression will have to use same dictionary. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special: Loading a NULL (or 0-size) dictionary invalidates previous dictionary, + meaning "return to no-dictionary mode". + Note 1 : Dictionary is sticky, it will be used for all future compressed frames, + until parameters are reset, a new dictionary is loaded, or the dictionary + is explicitly invalidated by loading a NULL dictionary. + Note 2 : Loading a dictionary involves building tables. + It's also a CPU consuming operation, with non-negligible impact on latency. + Tables are dependent on compression parameters, and for this reason, + compression parameters can no longer be changed after loading a dictionary. + Note 3 :`dict` content will be copied internally. + Use experimental ZSTD_CCtx_loadDictionary_byReference() to reference content instead. + In such a case, dictionary buffer must outlive its users. + Note 4 : Use ZSTD_CCtx_loadDictionary_advanced() + to precisely select how dictionary content must be interpreted. + Note 5 : This method does not benefit from LDM (long distance mode). + If you want to employ LDM on some large dictionary content, + prefer employing ZSTD_CCtx_refPrefix() described below. + +


+ +
size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
+

Reference a prepared dictionary, to be used for all future compressed frames. + Note that compression parameters are enforced from within CDict, + and supersede any compression parameter previously set within CCtx. + The parameters ignored are labelled as "superseded-by-cdict" in the ZSTD_cParameter enum docs. + The ignored parameters will be used again if the CCtx is returned to no-dictionary mode. + The dictionary will remain valid for future compressed frames using same CCtx. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special : Referencing a NULL CDict means "return to no-dictionary mode". + Note 1 : Currently, only one dictionary can be managed. + Referencing a new dictionary effectively "discards" any previous one. + Note 2 : CDict is just referenced, its lifetime must outlive its usage within CCtx. +


+ +
size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx,
+                     const void* prefix, size_t prefixSize);
+

Reference a prefix (single-usage dictionary) for next compressed frame. + A prefix is **only used once**. Tables are discarded at end of frame (ZSTD_e_end). + Decompression will need same prefix to properly regenerate data. + Compressing with a prefix is similar in outcome as performing a diff and compressing it, + but performs much faster, especially during decompression (compression speed is tunable with compression level). + This method is compatible with LDM (long distance mode). + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary + Note 1 : Prefix buffer is referenced. It **must** outlive compression. + Its content must remain unmodified during compression. + Note 2 : If the intention is to diff some large src data blob with some prior version of itself, + ensure that the window size is large enough to contain the entire source. + See ZSTD_c_windowLog. + Note 3 : Referencing a prefix involves building tables, which are dependent on compression parameters. + It's a CPU consuming operation, with non-negligible impact on latency. + If there is a need to use the same prefix multiple times, consider loadDictionary instead. + Note 4 : By default, the prefix is interpreted as raw content (ZSTD_dct_rawContent). + Use experimental ZSTD_CCtx_refPrefix_advanced() to alter dictionary interpretation. +


+ +
size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
+

Create an internal DDict from dict buffer, to be used to decompress all future frames. + The dictionary remains valid for all future frames, until explicitly invalidated, or + a new dictionary is loaded. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, + meaning "return to no-dictionary mode". + Note 1 : Loading a dictionary involves building tables, + which has a non-negligible impact on CPU usage and latency. + It's recommended to "load once, use many times", to amortize the cost + Note 2 :`dict` content will be copied internally, so `dict` can be released after loading. + Use ZSTD_DCtx_loadDictionary_byReference() to reference dictionary content instead. + Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to take control of + how dictionary content is loaded and interpreted. + +


+ +
size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
+

Reference a prepared dictionary, to be used to decompress next frames. + The dictionary remains active for decompression of future frames using same DCtx. + + If called with ZSTD_d_refMultipleDDicts enabled, repeated calls of this function + will store the DDict references in a table, and the DDict used for decompression + will be determined at decompression time, as per the dict ID in the frame. + The memory for the table is allocated on the first call to refDDict, and can be + freed with ZSTD_freeDCtx(). + + If called with ZSTD_d_refMultipleDDicts disabled (the default), only one dictionary + will be managed, and referencing a dictionary effectively "discards" any previous one. + + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special: referencing a NULL DDict means "return to no-dictionary mode". + Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx. + +


+ +
size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx,
+                     const void* prefix, size_t prefixSize);
+

Reference a prefix (single-usage dictionary) to decompress next frame. + This is the reverse operation of ZSTD_CCtx_refPrefix(), + and must use the same prefix as the one used during compression. + Prefix is **only used once**. Reference is discarded at end of frame. + End of frame is reached when ZSTD_decompressStream() returns 0. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary + Note 2 : Prefix buffer is referenced. It **must** outlive decompression. + Prefix buffer must remain unmodified up to the end of frame, + reached when ZSTD_decompressStream() returns 0. + Note 3 : By default, the prefix is treated as raw content (ZSTD_dct_rawContent). + Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode (Experimental section) + Note 4 : Referencing a raw content prefix has almost no cpu nor memory cost. + A full dictionary is more costly, as it requires building tables. + +


+ +
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
+size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
+size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
+size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
+size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
+size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
+

These functions give the _current_ memory usage of selected object. + Note that object memory usage can evolve (increase or decrease) over time. +


+ +

experimental API (static linking only)

+ The following symbols and constants
+ are not planned to join "stable API" status in the near future.
+ They can still change in future versions.
+ Some of them are planned to remain in the static_only section indefinitely.
+ Some of them might be removed in the future (especially when redundant with existing stable functions)
+ 
+
+ +
typedef struct {
+    unsigned int offset;      /* The offset of the match. (NOT the same as the offset code)
+                               * If offset == 0 and matchLength == 0, this sequence represents the last
+                               * literals in the block of litLength size.
+                               */
+
+    unsigned int litLength;   /* Literal length of the sequence. */
+    unsigned int matchLength; /* Match length of the sequence. */
+
+                              /* Note: Users of this API may provide a sequence with matchLength == litLength == offset == 0.
+                               * In this case, we will treat the sequence as a marker for a block boundary.
+                               */
+
+    unsigned int rep;         /* Represents which repeat offset is represented by the field 'offset'.
+                               * Ranges from [0, 3].
+                               *
+                               * Repeat offsets are essentially previous offsets from previous sequences sorted in
+                               * recency order. For more detail, see doc/zstd_compression_format.md
+                               *
+                               * If rep == 0, then 'offset' does not contain a repeat offset.
+                               * If rep > 0:
+                               *  If litLength != 0:
+                               *      rep == 1 --> offset == repeat_offset_1
+                               *      rep == 2 --> offset == repeat_offset_2
+                               *      rep == 3 --> offset == repeat_offset_3
+                               *  If litLength == 0:
+                               *      rep == 1 --> offset == repeat_offset_2
+                               *      rep == 2 --> offset == repeat_offset_3
+                               *      rep == 3 --> offset == repeat_offset_1 - 1
+                               *
+                               * Note: This field is optional. ZSTD_generateSequences() will calculate the value of
+                               * 'rep', but repeat offsets do not necessarily need to be calculated from an external
+                               * sequence provider perspective. For example, ZSTD_compressSequences() does not
+                               * use this 'rep' field at all (as of now).
+                               */
+} ZSTD_Sequence;
+

+
typedef struct {
+    unsigned windowLog;       /**< largest match distance : larger == more compression, more memory needed during decompression */
+    unsigned chainLog;        /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
+    unsigned hashLog;         /**< dispatch table : larger == faster, more memory */
+    unsigned searchLog;       /**< nb of searches : larger == more compression, slower */
+    unsigned minMatch;        /**< match length searched : larger == faster decompression, sometimes less compression */
+    unsigned targetLength;    /**< acceptable match size for optimal parser (only) : larger == more compression, slower */
+    ZSTD_strategy strategy;   /**< see ZSTD_strategy definition above */
+} ZSTD_compressionParameters;
+

+
typedef struct {
+    int contentSizeFlag; /**< 1: content size will be in frame header (when known) */
+    int checksumFlag;    /**< 1: generate a 32-bits checksum using XXH64 algorithm at end of frame, for error detection */
+    int noDictIDFlag;    /**< 1: no dictID will be saved into frame header (dictID is only useful for dictionary compression) */
+} ZSTD_frameParameters;
+

+
typedef struct {
+    ZSTD_compressionParameters cParams;
+    ZSTD_frameParameters fParams;
+} ZSTD_parameters;
+

+
typedef enum {
+    ZSTD_dct_auto = 0,       /* dictionary is "full" when starting with ZSTD_MAGIC_DICTIONARY, otherwise it is "rawContent" */
+    ZSTD_dct_rawContent = 1, /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */
+    ZSTD_dct_fullDict = 2    /* refuses to load a dictionary if it does not respect Zstandard's specification, starting with ZSTD_MAGIC_DICTIONARY */
+} ZSTD_dictContentType_e;
+

+
typedef enum {
+    ZSTD_dlm_byCopy = 0,  /**< Copy dictionary content internally */
+    ZSTD_dlm_byRef = 1    /**< Reference dictionary content -- the dictionary buffer must outlive its users. */
+} ZSTD_dictLoadMethod_e;
+

+
typedef enum {
+    ZSTD_f_zstd1 = 0,           /* zstd frame format, specified in zstd_compression_format.md (default) */
+    ZSTD_f_zstd1_magicless = 1  /* Variant of zstd frame format, without initial 4-bytes magic number.
+                                 * Useful to save 4 bytes per generated frame.
+                                 * Decoder cannot recognise automatically this format, requiring this instruction. */
+} ZSTD_format_e;
+

+
typedef enum {
+    /* Note: this enum controls ZSTD_d_forceIgnoreChecksum */
+    ZSTD_d_validateChecksum = 0,
+    ZSTD_d_ignoreChecksum = 1
+} ZSTD_forceIgnoreChecksum_e;
+

+
typedef enum {
+    /* Note: this enum controls ZSTD_d_refMultipleDDicts */
+    ZSTD_rmd_refSingleDDict = 0,
+    ZSTD_rmd_refMultipleDDicts = 1
+} ZSTD_refMultipleDDicts_e;
+

+
typedef enum {
+    /* Note: this enum and the behavior it controls are effectively internal
+     * implementation details of the compressor. They are expected to continue
+     * to evolve and should be considered only in the context of extremely
+     * advanced performance tuning.
+     *
+     * Zstd currently supports the use of a CDict in three ways:
+     *
+     * - The contents of the CDict can be copied into the working context. This
+     *   means that the compression can search both the dictionary and input
+     *   while operating on a single set of internal tables. This makes
+     *   the compression faster per-byte of input. However, the initial copy of
+     *   the CDict's tables incurs a fixed cost at the beginning of the
+     *   compression. For small compressions (< 8 KB), that copy can dominate
+     *   the cost of the compression.
+     *
+     * - The CDict's tables can be used in-place. In this model, compression is
+     *   slower per input byte, because the compressor has to search two sets of
+     *   tables. However, this model incurs no start-up cost (as long as the
+     *   working context's tables can be reused). For small inputs, this can be
+     *   faster than copying the CDict's tables.
+     *
+     * - The CDict's tables are not used at all, and instead we use the working
+     *   context alone to reload the dictionary and use params based on the source
+     *   size. See ZSTD_compress_insertDictionary() and ZSTD_compress_usingDict().
+     *   This method is effective when the dictionary sizes are very small relative
+     *   to the input size, and the input size is fairly large to begin with.
+     *
+     * Zstd has a simple internal heuristic that selects which strategy to use
+     * at the beginning of a compression. However, if experimentation shows that
+     * Zstd is making poor choices, it is possible to override that choice with
+     * this enum.
+     */
+    ZSTD_dictDefaultAttach = 0, /* Use the default heuristic. */
+    ZSTD_dictForceAttach   = 1, /* Never copy the dictionary. */
+    ZSTD_dictForceCopy     = 2, /* Always copy the dictionary. */
+    ZSTD_dictForceLoad     = 3  /* Always reload the dictionary */
+} ZSTD_dictAttachPref_e;
+

+
typedef enum {
+  ZSTD_lcm_auto = 0,          /**< Automatically determine the compression mode based on the compression level.
+                               *   Negative compression levels will be uncompressed, and positive compression
+                               *   levels will be compressed. */
+  ZSTD_lcm_huffman = 1,       /**< Always attempt Huffman compression. Uncompressed literals will still be
+                               *   emitted if Huffman compression is not profitable. */
+  ZSTD_lcm_uncompressed = 2   /**< Always emit uncompressed literals. */
+} ZSTD_literalCompressionMode_e;
+

+
typedef enum {
+  /* Note: This enum controls features which are conditionally beneficial.
+   * Zstd can take a decision on whether or not to enable the feature (ZSTD_ps_auto),
+   * but setting the switch to ZSTD_ps_enable or ZSTD_ps_disable force enable/disable the feature.
+   */
+  ZSTD_ps_auto = 0,         /* Let the library automatically determine whether the feature shall be enabled */
+  ZSTD_ps_enable = 1,       /* Force-enable the feature */
+  ZSTD_ps_disable = 2       /* Do not use the feature */
+} ZSTD_ParamSwitch_e;
+

+

Frame header and size functions


+
+
ZSTDLIB_STATIC_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
+

`src` should point to the start of a series of ZSTD encoded and/or skippable frames + `srcSize` must be the _exact_ size of this series + (i.e. there should be a frame boundary at `src + srcSize`) + @return : - decompressed size of all data in all successive frames + - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN + - if an error occurred: ZSTD_CONTENTSIZE_ERROR + + note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. + When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. + In which case, it's necessary to use streaming mode to decompress data. + note 2 : decompressed size is always present when compression is done with ZSTD_compress() + note 3 : decompressed size can be very large (64-bits value), + potentially larger than what local system can handle as a single memory segment. + In which case, it's necessary to use streaming mode to decompress data. + note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. + Always ensure result fits within application's authorized limits. + Each application can set its own limits. + note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to + read each contained frame header. This is fast as most of the data is skipped, + however it does mean that all frame data must be present and valid. +


+ +
ZSTDLIB_STATIC_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize);
+

`src` should point to the start of a series of ZSTD encoded and/or skippable frames + `srcSize` must be the _exact_ size of this series + (i.e. there should be a frame boundary at `src + srcSize`) + @return : - upper-bound for the decompressed size of all data in all successive frames + - if an error occurred: ZSTD_CONTENTSIZE_ERROR + + note 1 : an error can occur if `src` contains an invalid or incorrectly formatted frame. + note 2 : the upper-bound is exact when the decompressed size field is available in every ZSTD encoded frame of `src`. + in this case, `ZSTD_findDecompressedSize` and `ZSTD_decompressBound` return the same value. + note 3 : when the decompressed size field isn't available, the upper-bound for that frame is calculated by: + upper-bound = # blocks * min(128 KB, Window_Size) + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);
+

srcSize must be >= ZSTD_FRAMEHEADERSIZE_PREFIX. + @return : size of the Frame Header, + or an error code (if srcSize is too small) +


+ +
typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_FrameType_e;
+

+
typedef struct {
+    unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */
+    unsigned long long windowSize;       /* can be very large, up to <= frameContentSize */
+    unsigned blockSizeMax;
+    ZSTD_FrameType_e frameType;          /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */
+    unsigned headerSize;
+    unsigned dictID;
+    unsigned checksumFlag;
+    unsigned _reserved1;
+    unsigned _reserved2;
+} ZSTD_frameHeader;
+

+
ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input */
+/*! ZSTD_getFrameHeader_advanced() :
+ *  same as ZSTD_getFrameHeader(),
+ *  with added capability to select a format (like ZSTD_f_zstd1_magicless) */
+ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format);
+

decode Frame Header, or requires larger `srcSize`. + @return : 0, `zfhPtr` is correctly filled, + >0, `srcSize` is too small, value is wanted `srcSize` amount, + or an error code, which can be tested using ZSTD_isError() +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_decompressionMargin(const void* src, size_t srcSize);
+

Zstd supports in-place decompression, where the input and output buffers overlap. + In this case, the output buffer must be at least (Margin + Output_Size) bytes large, + and the input buffer must be at the end of the output buffer. + + _______________________ Output Buffer ________________________ + | | + | ____ Input Buffer ____| + | | | + v v v + |---------------------------------------|-----------|----------| + ^ ^ ^ + |___________________ Output_Size ___________________|_ Margin _| + + NOTE: See also ZSTD_DECOMPRESSION_MARGIN(). + NOTE: This applies only to single-pass decompression through ZSTD_decompress() or + ZSTD_decompressDCtx(). + NOTE: This function supports multi-frame input. + + @param src The compressed frame(s) + @param srcSize The size of the compressed frame(s) + @returns The decompression margin or an error that can be checked with ZSTD_isError(). + +


+ +
#define ZSTD_DECOMPRESSION_MARGIN(originalSize, blockSize) ((size_t)(                                              \
+        ZSTD_FRAMEHEADERSIZE_MAX                                                              /* Frame header */ + \
+        4                                                                                         /* checksum */ + \
+        ((originalSize) == 0 ? 0 : 3 * (((originalSize) + (blockSize) - 1) / blockSize)) /* 3 bytes per block */ + \
+        (blockSize)                                                                    /* One block of margin */   \
+    ))
+

Similar to ZSTD_decompressionMargin(), but instead of computing the margin from + the compressed frame, compute it from the original size and the blockSizeLog. + See ZSTD_decompressionMargin() for details. + + WARNING: This macro does not support multi-frame input, the input must be a single + zstd frame. If you need that support use the function, or implement it yourself. + + @param originalSize The original uncompressed size of the data. + @param blockSize The block size == MIN(windowSize, ZSTD_BLOCKSIZE_MAX). + Unless you explicitly set the windowLog smaller than + ZSTD_BLOCKSIZELOG_MAX you can just use ZSTD_BLOCKSIZE_MAX. + +


+ +
typedef enum {
+  ZSTD_sf_noBlockDelimiters = 0,         /* ZSTD_Sequence[] has no block delimiters, just sequences */
+  ZSTD_sf_explicitBlockDelimiters = 1    /* ZSTD_Sequence[] contains explicit block delimiters */
+} ZSTD_SequenceFormat_e;
+

+
ZSTDLIB_STATIC_API size_t ZSTD_sequenceBound(size_t srcSize);
+

`srcSize` : size of the input buffer + @return : upper-bound for the number of sequences that can be generated + from a buffer of srcSize bytes + + note : returns number of sequences - to get bytes, multiply by sizeof(ZSTD_Sequence). + +


+ +
ZSTD_DEPRECATED("For debugging only, will be replaced by ZSTD_extractSequences()")
+ZSTDLIB_STATIC_API size_t
+ZSTD_generateSequences(ZSTD_CCtx* zc,
+           ZSTD_Sequence* outSeqs, size_t outSeqsCapacity,
+           const void* src, size_t srcSize);
+

WARNING: This function is meant for debugging and informational purposes ONLY! + Its implementation is flawed, and it will be deleted in a future version. + It is not guaranteed to succeed, as there are several cases where it will give + up and fail. You should NOT use this function in production code. + + This function is deprecated, and will be removed in a future version. + + Generate sequences using ZSTD_compress2(), given a source buffer. + + @param zc The compression context to be used for ZSTD_compress2(). Set any + compression parameters you need on this context. + @param outSeqs The output sequences buffer of size @p outSeqsSize + @param outSeqsCapacity The size of the output sequences buffer. + ZSTD_sequenceBound(srcSize) is an upper bound on the number + of sequences that can be generated. + @param src The source buffer to generate sequences from of size @p srcSize. + @param srcSize The size of the source buffer. + + Each block will end with a dummy sequence + with offset == 0, matchLength == 0, and litLength == length of last literals. + litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0) + simply acts as a block delimiter. + + @returns The number of sequences generated, necessarily less than + ZSTD_sequenceBound(srcSize), or an error code that can be checked + with ZSTD_isError(). + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize);
+

Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals + by merging them into the literals of the next sequence. + + As such, the final generated result has no explicit representation of block boundaries, + and the final last literals segment is not represented in the sequences. + + The output of this function can be fed into ZSTD_compressSequences() with CCtx + setting of ZSTD_c_blockDelimiters as ZSTD_sf_noBlockDelimiters + @return : number of sequences left after merging + +


+ +
ZSTDLIB_STATIC_API size_t
+ZSTD_compressSequences(ZSTD_CCtx* cctx,
+           void* dst, size_t dstCapacity,
+     const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
+     const void* src, size_t srcSize);
+

Compress an array of ZSTD_Sequence, associated with @src buffer, into dst. + @src contains the entire input (not just the literals). + If @srcSize > sum(sequence.length), the remaining bytes are considered all literals + If a dictionary is included, then the cctx should reference the dict (see: ZSTD_CCtx_refCDict(), ZSTD_CCtx_loadDictionary(), etc.). + The entire source is compressed into a single frame. + + The compression behavior changes based on cctx params. In particular: + If ZSTD_c_blockDelimiters == ZSTD_sf_noBlockDelimiters, the array of ZSTD_Sequence is expected to contain + no block delimiters (defined in ZSTD_Sequence). Block boundaries are roughly determined based on + the block size derived from the cctx, and sequences may be split. This is the default setting. + + If ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, the array of ZSTD_Sequence is expected to contain + valid block delimiters (defined in ZSTD_Sequence). Behavior is undefined if no block delimiters are provided. + + When ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, it's possible to decide generating repcodes + using the advanced parameter ZSTD_c_repcodeResolution. Repcodes will improve compression ratio, though the benefit + can vary greatly depending on Sequences. On the other hand, repcode resolution is an expensive operation. + By default, it's disabled at low (<10) compression levels, and enabled above the threshold (>=10). + ZSTD_c_repcodeResolution makes it possible to directly manage this processing in either direction. + + If ZSTD_c_validateSequences == 0, this function blindly accepts the Sequences provided. Invalid Sequences cause undefined + behavior. If ZSTD_c_validateSequences == 1, then the function will detect invalid Sequences (see doc/zstd_compression_format.md for + specifics regarding offset/matchlength requirements) and then bail out and return an error. + + In addition to the two adjustable experimental params, there are other important cctx params. + - ZSTD_c_minMatch MUST be set as less than or equal to the smallest match generated by the match finder. It has a minimum value of ZSTD_MINMATCH_MIN. + - ZSTD_c_compressionLevel accordingly adjusts the strength of the entropy coder, as it would in typical compression. + - ZSTD_c_windowLog affects offset validation: this function will return an error at higher debug levels if a provided offset + is larger than what the spec allows for a given window log and dictionary (if present). See: doc/zstd_compression_format.md + + Note: Repcodes are, as of now, always re-calculated within this function, ZSTD_Sequence.rep is effectively unused. + Dev Note: Once ability to ingest repcodes become available, the explicit block delims mode must respect those repcodes exactly, + and cannot emit an RLE block that disagrees with the repcode history. + @return : final compressed size, or a ZSTD error code. + +


+ +
ZSTDLIB_STATIC_API size_t
+ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
+                      void* dst, size_t dstCapacity,
+                const ZSTD_Sequence* inSeqs, size_t nbSequences,
+                const void* literals, size_t litSize, size_t litCapacity,
+                size_t decompressedSize);
+

This is a variant of ZSTD_compressSequences() which, + instead of receiving (src,srcSize) as input parameter, receives (literals,litSize), + aka all the literals, already extracted and laid out into a single continuous buffer. + This can be useful if the process generating the sequences also happens to generate the buffer of literals, + thus skipping an extraction + caching stage. + It's a speed optimization, useful when the right conditions are met, + but it also features the following limitations: + - Only supports explicit delimiter mode + - Currently does not support Sequences validation (so input Sequences are trusted) + - Not compatible with frame checksum, which must be disabled + - If any block is incompressible, will fail and return an error + - @litSize must be == sum of all @.litLength fields in @inSeqs. Any discrepancy will generate an error. + - the buffer @literals must have a size @litCapacity which is larger than @litSize by at least 8 bytes. + - @decompressedSize must be correct, and correspond to the sum of all Sequences. Any discrepancy will generate an error. + @return : final compressed size, or a ZSTD error code. + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
+                                const void* src, size_t srcSize, unsigned magicVariant);
+

Generates a zstd skippable frame containing data given by src, and writes it to dst buffer. + + Skippable frames begin with a 4-byte magic number. There are 16 possible choices of magic number, + ranging from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15. + As such, the parameter magicVariant controls the exact skippable frame magic number variant used, so + the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant. + + Returns an error if destination buffer is not large enough, if the source size is not representable + with a 4-byte unsigned int, or if the parameter magicVariant is greater than 15 (and therefore invalid). + + @return : number of bytes written or a ZSTD error. + +


+ +
size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
+                                const void* src, size_t srcSize);
+

Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer. + + The parameter magicVariant will receive the magicVariant that was supplied when the frame was written, + i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested + in the magicVariant. + + Returns an error if destination buffer is not large enough, or if the frame is not skippable. + + @return : number of bytes written or a ZSTD error. + +


+ +
unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size);
+

Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + +


+ +

Memory management


+
+
ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int maxCompressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDCtxSize(void);
+

These functions make it possible to estimate memory usage + of a future {D,C}Ctx, before its creation. + This is useful in combination with ZSTD_initStatic(), + which makes it possible to employ a static buffer for ZSTD_CCtx* state. + + ZSTD_estimateCCtxSize() will provide a memory budget large enough + to compress data of any size using one-shot compression ZSTD_compressCCtx() or ZSTD_compress2() + associated with any compression level up to max specified one. + The estimate will assume the input may be arbitrarily large, + which is the worst case. + + Note that the size estimation is specific for one-shot compression, + it is not valid for streaming (see ZSTD_estimateCStreamSize*()) + nor other potential ways of using a ZSTD_CCtx* state. + + When srcSize can be bound by a known and rather "small" value, + this knowledge can be used to provide a tighter budget estimation + because the ZSTD_CCtx* state will need less memory for small inputs. + This tighter estimation can be provided by employing more advanced functions + ZSTD_estimateCCtxSize_usingCParams(), which can be used in tandem with ZSTD_getCParams(), + and ZSTD_estimateCCtxSize_usingCCtxParams(), which can be used in tandem with ZSTD_CCtxParams_setParameter(). + Both can be used to estimate memory using custom compression parameters and arbitrary srcSize limits. + + Note : only single-threaded compression is supported. + ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize(int maxCompressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize(size_t maxWindowSize);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
+

ZSTD_estimateCStreamSize() will provide a memory budget large enough for streaming compression + using any compression level up to the max specified one. + It will also consider src size to be arbitrarily "large", which is a worst case scenario. + If srcSize is known to always be small, ZSTD_estimateCStreamSize_usingCParams() can provide a tighter estimation. + ZSTD_estimateCStreamSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. + ZSTD_estimateCStreamSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParams_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_c_nbWorkers is >= 1. + Note : CStream size estimation is only correct for single-threaded compression. + ZSTD_estimateCStreamSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. + Note 2 : ZSTD_estimateCStreamSize* functions are not compatible with the Block-Level Sequence Producer API at this time. + Size estimates assume that no external sequence producer is registered. + + ZSTD_DStream memory budget depends on frame's window Size. + This information can be passed manually, using ZSTD_estimateDStreamSize, + or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame(); + Any frame requesting a window size larger than max specified one will be rejected. + Note : if streaming is init with function ZSTD_init?Stream_usingDict(), + an internal ?Dict will be created, which additional size is not estimated here. + In this case, get total size by adding ZSTD_estimate?DictSize + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod);
+

ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict(). + ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced(). + Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller. + +


+ +
ZSTDLIB_STATIC_API ZSTD_CCtx*    ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize);
+ZSTDLIB_STATIC_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticCCtx() */
+

Initialize an object using a pre-allocated fixed-size buffer. + workspace: The memory area to emplace the object into. + Provided pointer *must be 8-bytes aligned*. + Buffer must outlive object. + workspaceSize: Use ZSTD_estimate*Size() to determine + how large workspace must be to support target scenario. + @return : pointer to object (same address as workspace, just different type), + or NULL if error (size too small, incorrect alignment, etc.) + Note : zstd will never resize nor malloc() when using a static buffer. + If the object requires more memory than available, + zstd will just error out (typically ZSTD_error_memory_allocation). + Note 2 : there is no corresponding "free" function. + Since workspace is allocated externally, it must be freed externally too. + Note 3 : cParams : use ZSTD_getCParams() to convert a compression level + into its associated cParams. + Limitation 1 : currently not compatible with internal dictionary creation, triggered by + ZSTD_CCtx_loadDictionary(), ZSTD_initCStream_usingDict() or ZSTD_initDStream_usingDict(). + Limitation 2 : static cctx currently not compatible with multi-threading. + Limitation 3 : static dctx is incompatible with legacy support. + +


+ +
ZSTDLIB_STATIC_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticDCtx() */
+

+
typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
+typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
+typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
+static
+#ifdef __GNUC__
+__attribute__((__unused__))
+#endif
+

These prototypes make it possible to pass your own allocation/free functions. + ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below. + All allocation/free operations will be completed using these custom variants instead of regular ones. + +


+ +
ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL };  /**< this constant defers to stdlib's functions */
+

+
typedef struct POOL_ctx_s ZSTD_threadPool;
+ZSTDLIB_STATIC_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads);
+ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool);  /* accept NULL pointer */
+ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool);
+

These prototypes make it possible to share a thread pool among multiple compression contexts. + This can limit resources for applications with multiple threads where each one uses + a threaded compression mode (via ZSTD_c_nbWorkers parameter). + ZSTD_createThreadPool creates a new thread pool with a given number of threads. + Note that the lifetime of such pool must exist while being used. + ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value + to use an internal thread pool). + ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer. + +


+ +

Advanced compression functions


+
+
ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
+

Create a digested dictionary for compression + Dictionary content is just referenced, not duplicated. + As a consequence, `dictBuffer` **must** outlive CDict, + and its content must remain unmodified throughout the lifetime of CDict. + note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef +


+ +
ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+

@return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. + `estimatedSrcSize` value is optional, select 0 if not known +


+ +
ZSTDLIB_STATIC_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+

same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. + All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
+

Ensure param values remain within authorized range. + @return 0 on success, or an error code (can be checked with ZSTD_isError()) +


+ +
ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
+

optimize params for a given `srcSize` and `dictSize`. + `srcSize` can be unknown, in which case use ZSTD_CONTENTSIZE_UNKNOWN. + `dictSize` must be `0` when there is no dictionary. + cPar can be invalid : all parameters will be clamped within valid range in the @return struct. + This function never fails (wide contract) +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams);
+

Set all parameters provided within @p cparams into the working @p cctx. + Note : if modifying parameters during compression (MT mode only), + note that changes to the .windowLog parameter will be ignored. + @return 0 on success, or an error code (can be checked with ZSTD_isError()). + On failure, no parameters are updated. + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams);
+

Set all parameters provided within @p fparams into the working @p cctx. + @return 0 on success, or an error code (can be checked with ZSTD_isError()). + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params);
+

Set all parameters provided within @p params into the working @p cctx. + @return 0 on success, or an error code (can be checked with ZSTD_isError()). + +


+ +
ZSTD_DEPRECATED("use ZSTD_compress2")
+ZSTDLIB_STATIC_API
+size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx,
+                  void* dst, size_t dstCapacity,
+            const void* src, size_t srcSize,
+            const void* dict,size_t dictSize,
+                  ZSTD_parameters params);
+

Note : this function is now DEPRECATED. + It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters. + This prototype will generate compilation warnings. +


+ +
ZSTD_DEPRECATED("use ZSTD_compress2 with ZSTD_CCtx_loadDictionary")
+ZSTDLIB_STATIC_API
+size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
+                                  void* dst, size_t dstCapacity,
+                            const void* src, size_t srcSize,
+                            const ZSTD_CDict* cdict,
+                                  ZSTD_frameParameters fParams);
+

Note : this function is now DEPRECATED. + It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters. + This prototype will generate compilation warnings. +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+

Same as ZSTD_CCtx_loadDictionary(), but dictionary content is referenced, instead of being copied into CCtx. + It saves some memory, but also requires that `dict` outlives its usage within `cctx` +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);
+

Same as ZSTD_CCtx_loadDictionary(), but gives finer control over + how to load the dictionary (by copy ? by reference ?) + and how to interpret it (automatic ? force raw mode ? full mode only ?) +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);
+

Same as ZSTD_CCtx_refPrefix(), but gives finer control over + how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
+

Get the requested compression parameter value, selected by enum ZSTD_cParameter, + and store it into int* value. + @return : 0, or an error code (which can be tested with ZSTD_isError()). + +


+ +
ZSTDLIB_STATIC_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
+ZSTDLIB_STATIC_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);  /* accept NULL pointer */
+

Quick howto : + - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure + - ZSTD_CCtxParams_setParameter() : Push parameters one by one into + an existing ZSTD_CCtx_params structure. + This is similar to + ZSTD_CCtx_setParameter(). + - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to + an existing CCtx. + These parameters will be applied to + all subsequent frames. + - ZSTD_compressStream2() : Do compression using the CCtx. + - ZSTD_freeCCtxParams() : Free the memory, accept NULL pointer. + + This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams() + for static allocation of CCtx for single-threaded compression. + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params);
+

Reset params to default values. + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel);
+

Initializes the compression parameters of cctxParams according to + compression level. All other parameters are reset to their default values. + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
+

Initializes the compression and frame parameters of cctxParams according to + params. All other parameters are reset to their default values. + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value);
+

Similar to ZSTD_CCtx_setParameter. + Set one compression parameter, selected by enum ZSTD_cParameter. + Parameters must be applied to a ZSTD_CCtx using + ZSTD_CCtx_setParametersUsingCCtxParams(). + @result : a code representing success or failure (which can be tested with + ZSTD_isError()). + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);
+

Similar to ZSTD_CCtx_getParameter. + Get the requested value of one compression parameter, selected by enum ZSTD_cParameter. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParametersUsingCCtxParams(
+        ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
+

Apply a set of ZSTD_CCtx_params to the compression context. + This can be done even after compression is started, + if nbWorkers==0, this will have no impact until a new compression is started. + if nbWorkers>=1, new parameters will be picked up at next job, + with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated). + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_compressStream2_simpleArgs (
+                ZSTD_CCtx* cctx,
+                void* dst, size_t dstCapacity, size_t* dstPos,
+          const void* src, size_t srcSize, size_t* srcPos,
+                ZSTD_EndDirective endOp);
+

Same as ZSTD_compressStream2(), + but using only integral types as arguments. + This variant might be helpful for binders from dynamic languages + which have troubles handling structures containing memory pointers. + +


+ +

Advanced decompression functions


+
+
ZSTDLIB_STATIC_API unsigned ZSTD_isFrame(const void* buffer, size_t size);
+

Tells if the content of `buffer` starts with a valid Frame Identifier. + Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + Note 3 : Skippable Frame Identifiers are considered valid. +


+ +
ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
+

Create a digested dictionary, ready to start decompression operation without startup delay. + Dictionary content is referenced, and therefore stays in dictBuffer. + It is important that dictBuffer outlives DDict, + it must remain read accessible throughout the lifetime of DDict +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
+

Same as ZSTD_DCtx_loadDictionary(), + but references `dict` content instead of copying it into `dctx`. + This saves memory if `dict` remains around., + However, it's imperative that `dict` remains accessible (and unmodified) while being used, so it must outlive decompression. +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);
+

Same as ZSTD_DCtx_loadDictionary(), + but gives direct control over + how to load the dictionary (by copy ? by reference ?) + and how to interpret it (automatic ? force raw mode ? full mode only ?). +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);
+

Same as ZSTD_DCtx_refPrefix(), but gives finer control over + how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize);
+

Refuses allocating internal buffers for frames requiring a window size larger than provided limit. + This protects a decoder context from reserving too much memory for itself (potential attack scenario). + This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode. + By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + @return : 0, or an error code (which can be tested using ZSTD_isError()). + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value);
+

Get the requested decompression parameter value, selected by enum ZSTD_dParameter, + and store it into int* value. + @return : 0, or an error code (which can be tested with ZSTD_isError()). + +


+ +
ZSTD_DEPRECATED("use ZSTD_DCtx_setParameter() instead")
+ZSTDLIB_STATIC_API
+size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
+

This function is REDUNDANT. Prefer ZSTD_DCtx_setParameter(). + Instruct the decoder context about what kind of data to decode next. + This instruction is mandatory to decode data without a fully-formed header, + such ZSTD_f_zstd1_magicless for example. + @return : 0, or an error code (which can be tested using ZSTD_isError()). +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_decompressStream_simpleArgs (
+                ZSTD_DCtx* dctx,
+                void* dst, size_t dstCapacity, size_t* dstPos,
+          const void* src, size_t srcSize, size_t* srcPos);
+

Same as ZSTD_decompressStream(), + but using only integral types as arguments. + This can be helpful for binders from dynamic languages + which have troubles handling structures containing memory pointers. + +


+ +

Advanced streaming functions

  Warning : most of these functions are now redundant with the Advanced API.
+  Once Advanced API reaches "stable" status,
+  redundant functions will be deprecated, and then at some point removed.
+
+ +

Advanced Streaming compression functions


+
ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API
+size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs,
+             int compressionLevel,
+             unsigned long long pledgedSrcSize);
+

This function is DEPRECATED, and equivalent to: + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any) + ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel); + ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); + + pledgedSrcSize must be correct. If it is not known at init time, use + ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs, + "0" also disables frame content size field. It may be enabled in the future. + This prototype will generate compilation warnings. + +


+ +
ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API
+size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs,
+         const void* dict, size_t dictSize,
+               int compressionLevel);
+

This function is DEPRECATED, and is equivalent to: + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel); + ZSTD_CCtx_loadDictionary(zcs, dict, dictSize); + + Creates of an internal CDict (incompatible with static CCtx), except if + dict == NULL or dictSize < 8, in which case no dict is used. + Note: dict is loaded with ZSTD_dct_auto (treated as a full zstd dictionary if + it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy. + This prototype will generate compilation warnings. + +


+ +
ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API
+size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
+        const void* dict, size_t dictSize,
+              ZSTD_parameters params,
+              unsigned long long pledgedSrcSize);
+

This function is DEPRECATED, and is equivalent to: + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + ZSTD_CCtx_setParams(zcs, params); + ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); + ZSTD_CCtx_loadDictionary(zcs, dict, dictSize); + + dict is loaded with ZSTD_dct_auto and ZSTD_dlm_byCopy. + pledgedSrcSize must be correct. + If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. + This prototype will generate compilation warnings. + +


+ +
ZSTD_DEPRECATED("use ZSTD_CCtx_reset and ZSTD_CCtx_refCDict, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API
+size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);
+

This function is DEPRECATED, and equivalent to: + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + ZSTD_CCtx_refCDict(zcs, cdict); + + note : cdict will just be referenced, and must outlive compression session + This prototype will generate compilation warnings. + +


+ +
ZSTD_DEPRECATED("use ZSTD_CCtx_reset and ZSTD_CCtx_refCDict, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API
+size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
+                   const ZSTD_CDict* cdict,
+                         ZSTD_frameParameters fParams,
+                         unsigned long long pledgedSrcSize);
+

This function is DEPRECATED, and is equivalent to: + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + ZSTD_CCtx_setFParams(zcs, fParams); + ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); + ZSTD_CCtx_refCDict(zcs, cdict); + + same as ZSTD_initCStream_usingCDict(), with control over frame parameters. + pledgedSrcSize must be correct. If srcSize is not known at init time, use + value ZSTD_CONTENTSIZE_UNKNOWN. + This prototype will generate compilation warnings. + +


+ +
ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API
+size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
+

This function is DEPRECATED, and is equivalent to: + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); + Note: ZSTD_resetCStream() interprets pledgedSrcSize == 0 as ZSTD_CONTENTSIZE_UNKNOWN, but + ZSTD_CCtx_setPledgedSrcSize() does not do the same, so ZSTD_CONTENTSIZE_UNKNOWN must be + explicitly specified. + + start a new frame, using same parameters from previous frame. + This is typically useful to skip dictionary loading stage, since it will reuse it in-place. + Note that zcs must be init at least once before using ZSTD_resetCStream(). + If pledgedSrcSize is not known at reset time, use macro ZSTD_CONTENTSIZE_UNKNOWN. + If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end. + For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs, + but it will change to mean "empty" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead. + @return : 0, or an error code (which can be tested using ZSTD_isError()) + This prototype will generate compilation warnings. + +


+ +
typedef struct {
+    unsigned long long ingested;   /* nb input bytes read and buffered */
+    unsigned long long consumed;   /* nb input bytes actually compressed */
+    unsigned long long produced;   /* nb of compressed bytes generated and buffered */
+    unsigned long long flushed;    /* nb of compressed bytes flushed : not provided; can be tracked from caller side */
+    unsigned currentJobID;         /* MT only : latest started job nb */
+    unsigned nbActiveWorkers;      /* MT only : nb of workers actively compressing at probe time */
+} ZSTD_frameProgression;
+

+
ZSTDLIB_STATIC_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);
+

Tell how many bytes are ready to be flushed immediately. + Useful for multithreading scenarios (nbWorkers >= 1). + Probe the oldest active job, defined as oldest job not yet entirely flushed, + and check its output buffer. + @return : amount of data stored in oldest job and ready to be flushed immediately. + if @return == 0, it means either : + + there is no active job (could be checked with ZSTD_frameProgression()), or + + oldest job is still actively compressing data, + but everything it has produced has also been flushed so far, + therefore flush speed is limited by production speed of oldest job + irrespective of the speed of concurrent (and newer) jobs. + +


+ +

Advanced Streaming decompression functions


+
ZSTD_DEPRECATED("use ZSTD_DCtx_reset + ZSTD_DCtx_loadDictionary, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
+

+ ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); + ZSTD_DCtx_loadDictionary(zds, dict, dictSize); + + note: no dictionary will be used if dict == NULL or dictSize < 8 + +


+ +
ZSTD_DEPRECATED("use ZSTD_DCtx_reset + ZSTD_DCtx_refDDict, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);
+

+ ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); + ZSTD_DCtx_refDDict(zds, ddict); + + note : ddict is referenced, it must outlive decompression session + +


+ +
ZSTD_DEPRECATED("use ZSTD_DCtx_reset, see zstd.h for detailed instructions")
+ZSTDLIB_STATIC_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
+

+ ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); + + reuse decompression parameters from previous init; saves dictionary loading + +


+ +
ZSTDLIB_STATIC_API void
+ZSTD_registerSequenceProducer(
+  ZSTD_CCtx* cctx,
+  void* sequenceProducerState,
+  ZSTD_sequenceProducer_F sequenceProducer
+);
+

Instruct zstd to use a block-level external sequence producer function. + + The sequenceProducerState must be initialized by the caller, and the caller is + responsible for managing its lifetime. This parameter is sticky across + compressions. It will remain set until the user explicitly resets compression + parameters. + + Sequence producer registration is considered to be an "advanced parameter", + part of the "advanced API". This means it will only have an effect on compression + APIs which respect advanced parameters, such as compress2() and compressStream2(). + Older compression APIs such as compressCCtx(), which predate the introduction of + "advanced parameters", will ignore any external sequence producer setting. + + The sequence producer can be "cleared" by registering a NULL function pointer. This + removes all limitations described above in the "LIMITATIONS" section of the API docs. + + The user is strongly encouraged to read the full API documentation (above) before + calling this function. +


+ +
ZSTDLIB_STATIC_API void
+ZSTD_CCtxParams_registerSequenceProducer(
+  ZSTD_CCtx_params* params,
+  void* sequenceProducerState,
+  ZSTD_sequenceProducer_F sequenceProducer
+);
+

Same as ZSTD_registerSequenceProducer(), but operates on ZSTD_CCtx_params. + This is used for accurate size estimation with ZSTD_estimateCCtxSize_usingCCtxParams(), + which is needed when creating a ZSTD_CCtx with ZSTD_initStaticCCtx(). + + If you are using the external sequence producer API in a scenario where ZSTD_initStaticCCtx() + is required, then this function is for you. Otherwise, you probably don't need it. + + See tests/zstreamtest.c for example usage. +


+ +

Buffer-less and synchronous inner streaming functions (DEPRECATED)

+  This API is deprecated, and will be removed in a future version.
+  It allows streaming (de)compression with user allocated buffers.
+  However, it is hard to use, and not as well tested as the rest of
+  our API.
+
+  Please use the normal streaming API instead: ZSTD_compressStream2,
+  and ZSTD_decompressStream.
+  If there is functionality that you need, but it doesn't provide,
+  please open an issue on our GitHub.
+ 
+
+ +

Buffer-less streaming compression (synchronous mode)

+  A ZSTD_CCtx object is required to track streaming operations.
+  Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
+  ZSTD_CCtx object can be reused multiple times within successive compression operations.
+
+  Start by initializing a context.
+  Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression.
+
+  Then, consume your input using ZSTD_compressContinue().
+  There are some important considerations to keep in mind when using this advanced function :
+  - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only.
+  - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks.
+  - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
+    Worst case evaluation is provided by ZSTD_compressBound().
+    ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
+  - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).
+    It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)
+  - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
+    In which case, it will "discard" the relevant memory section from its history.
+
+  Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
+  It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame.
+  Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders.
+
+  `ZSTD_CCtx` object can be reused (ZSTD_compressBegin()) to compress again.
+
+ +

Buffer-less streaming compression functions

ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
+ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
+ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */
+

+
size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**<  note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */
+

+
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */
+

+

Buffer-less streaming decompression (synchronous mode)

+  A ZSTD_DCtx object is required to track streaming operations.
+  Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
+  A ZSTD_DCtx object can be reused multiple times.
+
+  First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader().
+  Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough.
+  Data fragment must be large enough to ensure successful decoding.
+ `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough.
+  result  : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled.
+           >0 : `srcSize` is too small, please provide at least result bytes on next attempt.
+           errorCode, which can be tested using ZSTD_isError().
+
+  It fills a ZSTD_FrameHeader structure with important information to correctly decode the frame,
+  such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`).
+  Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information.
+  As a consequence, check that values remain within valid application range.
+  For example, do not allocate memory blindly, check that `windowSize` is within expectation.
+  Each application can set its own limits, depending on local restrictions.
+  For extended interoperability, it is recommended to support `windowSize` of at least 8 MB.
+
+  ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes.
+  ZSTD_decompressContinue() is very sensitive to contiguity,
+  if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
+  or that previous contiguous segment is large enough to properly handle maximum back-reference distance.
+  There are multiple ways to guarantee this condition.
+
+  The most memory efficient way is to use a round buffer of sufficient size.
+  Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(),
+  which can return an error code if required value is too large for current system (in 32-bits mode).
+  In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one,
+  up to the moment there is not enough room left in the buffer to guarantee decoding another full block,
+  which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`.
+  At which point, decoding can resume from the beginning of the buffer.
+  Note that already decoded data stored in the buffer should be flushed before being overwritten.
+
+  There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory.
+
+  Finally, if you control the compression process, you can also ignore all buffer size rules,
+  as long as the encoder and decoder progress in "lock-step",
+  aka use exactly the same buffer sizes, break contiguity at the same place, etc.
+
+  Once buffers are setup, start decompression, with ZSTD_decompressBegin().
+  If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict().
+
+  Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
+  ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
+  ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
+
+  result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
+  It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item.
+  It can also be an error code, which can be tested with ZSTD_isError().
+
+  A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
+  Context can then be reset to start a new decompression.
+
+  Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
+  This information is not required to properly decode a frame.
+
+  == Special case : skippable frames 
+
+  Skippable frames allow integration of user-defined data into a flow of concatenated frames.
+  Skippable frames will be ignored (skipped) by decompressor.
+  The format of skippable frames is as follows :
+  a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
+  b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
+  c) Frame Content - any content (User Data) of length equal to Frame Size
+  For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame.
+  For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content.
+
+ +

Buffer-less streaming decompression functions


+
ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize);  /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */
+

+
typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
+

+

Block level API (DEPRECATED)


+
+

You can get the frame header down to 2 bytes by setting: + - ZSTD_c_format = ZSTD_f_zstd1_magicless + - ZSTD_c_contentSizeFlag = 0 + - ZSTD_c_checksumFlag = 0 + - ZSTD_c_dictIDFlag = 0 + + This API is not as well tested as our normal API, so we recommend not using it. + We will be removing it in a future version. If the normal API doesn't provide + the functionality you need, please open a GitHub issue. + + Block functions produce and decode raw zstd blocks, without frame metadata. + Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes). + But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes. + + A few rules to respect : + - Compressing and decompressing require a context structure + + Use ZSTD_createCCtx() and ZSTD_createDCtx() + - It is necessary to init context before starting + + compression : any ZSTD_compressBegin*() variant, including with dictionary + + decompression : any ZSTD_decompressBegin*() variant, including with dictionary + - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB + + If input is larger than a block size, it's necessary to split input data into multiple blocks + + For inputs larger than a single block, consider using regular ZSTD_compress() instead. + Frame metadata is not that costly, and quickly becomes negligible as source size grows larger than a block. + - When a block is considered not compressible enough, ZSTD_compressBlock() result will be 0 (zero) ! + ===> In which case, nothing is produced into `dst` ! + + User __must__ test for such outcome and deal directly with uncompressed data + + A block cannot be declared incompressible if ZSTD_compressBlock() return value was != 0. + Doing so would mess up with statistics history, leading to potential data corruption. + + ZSTD_decompressBlock() _doesn't accept uncompressed data as input_ !! + + In case of multiple successive blocks, should some of them be uncompressed, + decoder must be informed of their existence in order to follow proper history. + Use ZSTD_insertBlock() for such a case. +


+ +

Raw zstd block functions

ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize   (const ZSTD_CCtx* cctx);
+ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_insertBlock    (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */
+

+ + diff --git a/cpp/third_party/zstd-1.5.7/examples/.gitignore b/cpp/third_party/zstd-1.5.7/examples/.gitignore new file mode 100644 index 000000000..d682cae38 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/.gitignore @@ -0,0 +1,15 @@ +#build +simple_compression +simple_decompression +multiple_simple_compression +dictionary_compression +dictionary_decompression +streaming_compression +streaming_decompression +multiple_streaming_compression +streaming_memory_usage + +#test artefact +tmp* +test* +*.zst diff --git a/cpp/third_party/zstd-1.5.7/examples/Makefile b/cpp/third_party/zstd-1.5.7/examples/Makefile new file mode 100644 index 000000000..31f52d357 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/Makefile @@ -0,0 +1,93 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ + +LIBDIR =../lib +CPPFLAGS += -I$(LIBDIR) +LIB = $(LIBDIR)/libzstd.a + + +.PHONY: default +default: all + +.PHONY: all +all: simple_compression simple_decompression \ + multiple_simple_compression\ + dictionary_compression dictionary_decompression \ + streaming_compression streaming_decompression \ + multiple_streaming_compression streaming_memory_usage + +$(LIB) : + $(MAKE) -C $(LIBDIR) libzstd.a + +simple_compression.o: common.h +simple_compression : $(LIB) + +simple_decompression.o: common.h +simple_decompression : $(LIB) + +multiple_simple_compression.o: common.h +multiple_simple_compression : $(LIB) + +dictionary_compression.o: common.h +dictionary_compression : $(LIB) + +dictionary_decompression.o: common.h +dictionary_decompression : $(LIB) + +streaming_compression.o: common.h +streaming_compression : $(LIB) + +multiple_streaming_compression.o: common.h +multiple_streaming_compression : $(LIB) + +streaming_decompression.o: common.h +streaming_decompression : $(LIB) + +streaming_memory_usage.o: common.h +streaming_memory_usage : $(LIB) + + +.PHONY:clean +clean: + @$(RM) core *.o tmp* result* *.zst \ + simple_compression simple_decompression \ + multiple_simple_compression \ + dictionary_compression dictionary_decompression \ + streaming_compression streaming_decompression \ + multiple_streaming_compression streaming_memory_usage + @echo Cleaning completed + +.PHONY:test +test: all + cp README.md tmp + cp Makefile tmp2 + @echo -- Simple compression tests + ./simple_compression tmp + ./simple_decompression tmp.zst + ./multiple_simple_compression *.c + ./streaming_decompression tmp.zst > /dev/null + @echo -- Streaming memory usage + ./streaming_memory_usage + @echo -- Streaming compression tests + ./streaming_compression tmp + ./streaming_decompression tmp.zst > /dev/null + @echo -- Edge cases detection + ! ./streaming_decompression tmp # invalid input, must fail + ! ./simple_decompression tmp # invalid input, must fail + touch tmpNull # create 0-size file + ./simple_compression tmpNull + ./simple_decompression tmpNull.zst # 0-size frame : must work + @echo -- Multiple streaming tests + ./multiple_streaming_compression *.c + @echo -- Dictionary compression tests + ./dictionary_compression tmp2 tmp README.md + ./dictionary_decompression tmp2.zst tmp.zst README.md + $(RM) tmp* *.zst + @echo tests completed diff --git a/cpp/third_party/zstd-1.5.7/examples/README.md b/cpp/third_party/zstd-1.5.7/examples/README.md new file mode 100644 index 000000000..0bff7ac19 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/README.md @@ -0,0 +1,46 @@ +Zstandard library : usage examples +================================== + +- [Simple compression](simple_compression.c) : + Compress a single file. + Introduces usage of : `ZSTD_compress()` + +- [Simple decompression](simple_decompression.c) : + Decompress a single file. + Only compatible with simple compression. + Result remains in memory. + Introduces usage of : `ZSTD_decompress()` + +- [Multiple simple compression](multiple_simple_compression.c) : + Compress multiple files (in simple mode) in a single command line. + Demonstrates memory preservation technique that + minimizes malloc()/free() calls by re-using existing resources. + Introduces usage of : `ZSTD_compressCCtx()` + +- [Streaming memory usage](streaming_memory_usage.c) : + Provides amount of memory used by streaming context. + Introduces usage of : `ZSTD_sizeof_CStream()` + +- [Streaming compression](streaming_compression.c) : + Compress a single file. + Introduces usage of : `ZSTD_compressStream()` + +- [Multiple Streaming compression](multiple_streaming_compression.c) : + Compress multiple files (in streaming mode) in a single command line. + Introduces memory usage preservation technique, + reducing impact of malloc()/free() and memset() by re-using existing resources. + +- [Streaming decompression](streaming_decompression.c) : + Decompress a single file compressed by zstd. + Compatible with both simple and streaming compression. + Result is sent to stdout. + Introduces usage of : `ZSTD_decompressStream()` + +- [Dictionary compression](dictionary_compression.c) : + Compress multiple files using the same dictionary. + Introduces usage of : `ZSTD_createCDict()` and `ZSTD_compress_usingCDict()` + +- [Dictionary decompression](dictionary_decompression.c) : + Decompress multiple files using the same dictionary. + Result remains in memory. + Introduces usage of : `ZSTD_createDDict()` and `ZSTD_decompress_usingDDict()` diff --git a/cpp/third_party/zstd-1.5.7/examples/common.h b/cpp/third_party/zstd-1.5.7/examples/common.h new file mode 100644 index 000000000..4873e877a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/common.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* + * This header file has common utility functions used in examples. + */ +#ifndef COMMON_H +#define COMMON_H + +#include // malloc, free, exit +#include // fprintf, perror, fopen, etc. +#include // strerror +#include // errno +#include // stat +#include + + +/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ +#if defined(__GNUC__) +# define UNUSED_ATTR __attribute__((unused)) +#else +# define UNUSED_ATTR +#endif + +#define HEADER_FUNCTION static UNUSED_ATTR + + +/* + * Define the returned error code from utility functions. + */ +typedef enum { + ERROR_fsize = 1, + ERROR_fopen = 2, + ERROR_fclose = 3, + ERROR_fread = 4, + ERROR_fwrite = 5, + ERROR_loadFile = 6, + ERROR_saveFile = 7, + ERROR_malloc = 8, + ERROR_largeFile = 9, +} COMMON_ErrorCode; + +/*! CHECK + * Check that the condition holds. If it doesn't print a message and die. + */ +#define CHECK(cond, ...) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, \ + "%s:%d CHECK(%s) failed: ", \ + __FILE__, \ + __LINE__, \ + #cond); \ + fprintf(stderr, "" __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + exit(1); \ + } \ + } while (0) + +/*! CHECK_ZSTD + * Check the zstd error code and die if an error occurred after printing a + * message. + */ +#define CHECK_ZSTD(fn) \ + do { \ + size_t const err = (fn); \ + CHECK(!ZSTD_isError(err), "%s", ZSTD_getErrorName(err)); \ + } while (0) + +/*! fsize_orDie() : + * Get the size of a given file path. + * + * @return The size of a given file path. + */ +HEADER_FUNCTION size_t fsize_orDie(const char *filename) +{ + struct stat st; + if (stat(filename, &st) != 0) { + /* error */ + perror(filename); + exit(ERROR_fsize); + } + + off_t const fileSize = st.st_size; + size_t const size = (size_t)fileSize; + /* 1. fileSize should be non-negative, + * 2. if off_t -> size_t type conversion results in discrepancy, + * the file size is too large for type size_t. + */ + if ((fileSize < 0) || (fileSize != (off_t)size)) { + fprintf(stderr, "%s : filesize too large \n", filename); + exit(ERROR_largeFile); + } + return size; +} + +/*! fopen_orDie() : + * Open a file using given file path and open option. + * + * @return If successful this function will return a FILE pointer to an + * opened file otherwise it sends an error to stderr and exits. + */ +HEADER_FUNCTION FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(ERROR_fopen); +} + +/*! fclose_orDie() : + * Close an opened file using given FILE pointer. + */ +HEADER_FUNCTION void fclose_orDie(FILE* file) +{ + if (!fclose(file)) { return; }; + /* error */ + perror("fclose"); + exit(ERROR_fclose); +} + +/*! fread_orDie() : + * + * Read sizeToRead bytes from a given file, storing them at the + * location given by buffer. + * + * @return The number of bytes read. + */ +HEADER_FUNCTION size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(ERROR_fread); +} + +/*! fwrite_orDie() : + * + * Write sizeToWrite bytes to a file pointed to by file, obtaining + * them from a location given by buffer. + * + * Note: This function will send an error to stderr and exit if it + * cannot write data to the given file pointer. + * + * @return The number of bytes written. + */ +HEADER_FUNCTION size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(ERROR_fwrite); +} + +/*! malloc_orDie() : + * Allocate memory. + * + * @return If successful this function returns a pointer to allo- + * cated memory. If there is an error, this function will send that + * error to stderr and exit. + */ +HEADER_FUNCTION void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc"); + exit(ERROR_malloc); +} + +/*! loadFile_orDie() : + * load file into buffer (memory). + * + * Note: This function will send an error to stderr and exit if it + * cannot read data from the given file path. + * + * @return If successful this function will load file into buffer and + * return file size, otherwise it will printout an error to stderr and exit. + */ +HEADER_FUNCTION size_t loadFile_orDie(const char* fileName, void* buffer, size_t bufferSize) +{ + size_t const fileSize = fsize_orDie(fileName); + CHECK(fileSize <= bufferSize, "File too large!"); + + FILE* const inFile = fopen_orDie(fileName, "rb"); + size_t const readSize = fread(buffer, 1, fileSize, inFile); + if (readSize != (size_t)fileSize) { + fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno)); + exit(ERROR_fread); + } + fclose(inFile); /* can't fail, read only */ + return fileSize; +} + +/*! mallocAndLoadFile_orDie() : + * allocate memory buffer and then load file into it. + * + * Note: This function will send an error to stderr and exit if memory allocation + * fails or it cannot read data from the given file path. + * + * @return If successful this function will return buffer and bufferSize(=fileSize), + * otherwise it will printout an error to stderr and exit. + */ +HEADER_FUNCTION void* mallocAndLoadFile_orDie(const char* fileName, size_t* bufferSize) +{ + size_t const fileSize = fsize_orDie(fileName); + *bufferSize = fileSize; + void* const buffer = malloc_orDie(*bufferSize); + loadFile_orDie(fileName, buffer, *bufferSize); + return buffer; +} + +/*! saveFile_orDie() : + * + * Save buffSize bytes to a given file path, obtaining them from a location pointed + * to by buff. + * + * Note: This function will send an error to stderr and exit if it + * cannot write to a given file. + */ +HEADER_FUNCTION void saveFile_orDie(const char* fileName, const void* buff, size_t buffSize) +{ + FILE* const oFile = fopen_orDie(fileName, "wb"); + size_t const wSize = fwrite(buff, 1, buffSize, oFile); + if (wSize != (size_t)buffSize) { + fprintf(stderr, "fwrite: %s : %s \n", fileName, strerror(errno)); + exit(ERROR_fwrite); + } + if (fclose(oFile)) { + perror(fileName); + exit(ERROR_fclose); + } +} + +#endif diff --git a/cpp/third_party/zstd-1.5.7/examples/dictionary_compression.c b/cpp/third_party/zstd-1.5.7/examples/dictionary_compression.c new file mode 100644 index 000000000..83edc1cad --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/dictionary_compression.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +**/ + +/* This example deals with Dictionary compression, + * its counterpart is `examples/dictionary_decompression.c` . + * These examples presume that a dictionary already exists. + * The main method to create a dictionary is `zstd --train`, + * look at the CLI documentation for details. + * Another possible method is to employ dictionary training API, + * published in `lib/zdict.h` . +**/ + +#include // printf +#include // free +#include // memset, strcat +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + +/* createDict() : +** `dictFileName` is supposed already created using `zstd --train` */ +static ZSTD_CDict* createCDict_orDie(const char* dictFileName, int cLevel) +{ + size_t dictSize; + printf("loading dictionary %s \n", dictFileName); + void* const dictBuffer = mallocAndLoadFile_orDie(dictFileName, &dictSize); + ZSTD_CDict* const cdict = ZSTD_createCDict(dictBuffer, dictSize, cLevel); + CHECK(cdict != NULL, "ZSTD_createCDict() failed!"); + free(dictBuffer); + return cdict; +} + + +static void compress(const char* fname, const char* oname, const ZSTD_CDict* cdict) +{ + size_t fSize; + void* const fBuff = mallocAndLoadFile_orDie(fname, &fSize); + size_t const cBuffSize = ZSTD_compressBound(fSize); + void* const cBuff = malloc_orDie(cBuffSize); + + /* Compress using the dictionary. + * This function writes the dictionary id, and content size into the header. + * But, it doesn't use a checksum. You can control these options using the + * advanced API: ZSTD_CCtx_setParameter(), ZSTD_CCtx_refCDict(), + * and ZSTD_compress2(). + */ + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + CHECK(cctx != NULL, "ZSTD_createCCtx() failed!"); + size_t const cSize = ZSTD_compress_usingCDict(cctx, cBuff, cBuffSize, fBuff, fSize, cdict); + CHECK_ZSTD(cSize); + + saveFile_orDie(oname, cBuff, cSize); + + /* success */ + printf("%25s : %6u -> %7u - %s \n", fname, (unsigned)fSize, (unsigned)cSize, oname); + + ZSTD_freeCCtx(cctx); /* never fails */ + free(fBuff); + free(cBuff); +} + + +static char* createOutFilename_orDie(const char* filename) +{ + size_t const inL = strlen(filename); + size_t const outL = inL + 5; + void* outSpace = malloc_orDie(outL); + memset(outSpace, 0, outL); + strcat(outSpace, filename); + strcat(outSpace, ".zst"); + return (char*)outSpace; +} + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + int const cLevel = 3; + + if (argc<3) { + fprintf(stderr, "wrong arguments\n"); + fprintf(stderr, "usage:\n"); + fprintf(stderr, "%s [FILES] dictionary\n", exeName); + return 1; + } + + /* load dictionary only once */ + const char* const dictName = argv[argc-1]; + ZSTD_CDict* const dictPtr = createCDict_orDie(dictName, cLevel); + + int u; + for (u=1; u // printf +#include // free +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + +/* createDict() : + `dictFileName` is supposed to have been created using `zstd --train` */ +static ZSTD_DDict* createDict_orDie(const char* dictFileName) +{ + size_t dictSize; + printf("loading dictionary %s \n", dictFileName); + void* const dictBuffer = mallocAndLoadFile_orDie(dictFileName, &dictSize); + ZSTD_DDict* const ddict = ZSTD_createDDict(dictBuffer, dictSize); + CHECK(ddict != NULL, "ZSTD_createDDict() failed!"); + free(dictBuffer); + return ddict; +} + +static void decompress(const char* fname, const ZSTD_DDict* ddict) +{ + size_t cSize; + void* const cBuff = mallocAndLoadFile_orDie(fname, &cSize); + /* Read the content size from the frame header. For simplicity we require + * that it is always present. By default, zstd will write the content size + * in the header when it is known. If you can't guarantee that the frame + * content size is always written into the header, either use streaming + * decompression, or ZSTD_decompressBound(). + */ + unsigned long long const rSize = ZSTD_getFrameContentSize(cBuff, cSize); + CHECK(rSize != ZSTD_CONTENTSIZE_ERROR, "%s: not compressed by zstd!", fname); + CHECK(rSize != ZSTD_CONTENTSIZE_UNKNOWN, "%s: original size unknown!", fname); + void* const rBuff = malloc_orDie((size_t)rSize); + + /* Check that the dictionary ID matches. + * If a non-zstd dictionary is used, then both will be zero. + * By default zstd always writes the dictionary ID into the frame. + * Zstd will check if there is a dictionary ID mismatch as well. + */ + unsigned const expectedDictID = ZSTD_getDictID_fromDDict(ddict); + unsigned const actualDictID = ZSTD_getDictID_fromFrame(cBuff, cSize); + CHECK(actualDictID == expectedDictID, + "DictID mismatch: expected %u got %u", + expectedDictID, + actualDictID); + + /* Decompress using the dictionary. + * If you need to control the decompression parameters, then use the + * advanced API: ZSTD_DCtx_setParameter(), ZSTD_DCtx_refDDict(), and + * ZSTD_decompressDCtx(). + */ + ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + CHECK(dctx != NULL, "ZSTD_createDCtx() failed!"); + size_t const dSize = ZSTD_decompress_usingDDict(dctx, rBuff, rSize, cBuff, cSize, ddict); + CHECK_ZSTD(dSize); + /* When zstd knows the content size, it will error if it doesn't match. */ + CHECK(dSize == rSize, "Impossible because zstd will check this condition!"); + + /* success */ + printf("%25s : %6u -> %7u \n", fname, (unsigned)cSize, (unsigned)rSize); + + ZSTD_freeDCtx(dctx); + free(rBuff); + free(cBuff); +} + + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc<3) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s [FILES] dictionary\n", exeName); + return 1; + } + + /* load dictionary only once */ + const char* const dictName = argv[argc-1]; + ZSTD_DDict* const dictPtr = createDict_orDie(dictName); + + int u; + for (u=1; u // printf +#include // free +#include // memcpy, strlen +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + +typedef struct { + void* fBuffer; + void* cBuffer; + size_t fBufferSize; + size_t cBufferSize; + ZSTD_CCtx* cctx; +} resources; + +/* + * allocate memory for buffers big enough to compress all files + * as well as memory for output file name (ofn) + */ +static resources createResources_orDie(int argc, const char** argv, char **ofn, size_t* ofnBufferLen) +{ + size_t maxFilenameLength=0; + size_t maxFileSize = 0; + + int argNb; + for (argNb = 1; argNb < argc; argNb++) { + const char* const filename = argv[argNb]; + size_t const filenameLength = strlen(filename); + size_t const fileSize = fsize_orDie(filename); + + if (filenameLength > maxFilenameLength) maxFilenameLength = filenameLength; + if (fileSize > maxFileSize) maxFileSize = fileSize; + } + + resources ress; + ress.fBufferSize = maxFileSize; + ress.cBufferSize = ZSTD_compressBound(maxFileSize); + + *ofnBufferLen = maxFilenameLength + 5; + *ofn = (char*)malloc_orDie(*ofnBufferLen); + ress.fBuffer = malloc_orDie(ress.fBufferSize); + ress.cBuffer = malloc_orDie(ress.cBufferSize); + ress.cctx = ZSTD_createCCtx(); + CHECK(ress.cctx != NULL, "ZSTD_createCCtx() failed!"); + return ress; +} + +static void freeResources(resources ress, char *outFilename) +{ + free(ress.fBuffer); + free(ress.cBuffer); + ZSTD_freeCCtx(ress.cctx); /* never fails */ + free(outFilename); +} + +/* compress with pre-allocated context (ZSTD_CCtx) and input/output buffers*/ +static void compressFile_orDie(resources ress, const char* fname, const char* oname) +{ + size_t fSize = loadFile_orDie(fname, ress.fBuffer, ress.fBufferSize); + + /* Compress using the context. + * If you need more control over parameters, use the advanced API: + * ZSTD_CCtx_setParameter(), and ZSTD_compress2(). + */ + size_t const cSize = ZSTD_compressCCtx(ress.cctx, ress.cBuffer, ress.cBufferSize, ress.fBuffer, fSize, 1); + CHECK_ZSTD(cSize); + + saveFile_orDie(oname, ress.cBuffer, cSize); + + /* success */ + printf("%25s : %6u -> %7u - %s \n", fname, (unsigned)fSize, (unsigned)cSize, oname); +} + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc<2) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s FILE(s)\n", exeName); + return 1; + } + + /* memory allocation for outFilename and resources */ + char* outFilename; + size_t outFilenameBufferLen; + resources const ress = createResources_orDie(argc, argv, &outFilename, &outFilenameBufferLen); + + /* compress files with shared context, input and output buffers */ + int argNb; + for (argNb = 1; argNb < argc; argNb++) { + const char* const inFilename = argv[argNb]; + size_t const inFilenameLen = strlen(inFilename); + CHECK(inFilenameLen + 5 <= outFilenameBufferLen, "File name too long!"); + memcpy(outFilename, inFilename, inFilenameLen); + memcpy(outFilename+inFilenameLen, ".zst", 5); + compressFile_orDie(ress, inFilename, outFilename); + } + + /* free memory */ + freeResources(ress,outFilename); + + printf("compressed %i files \n", argc-1); + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/examples/multiple_streaming_compression.c b/cpp/third_party/zstd-1.5.7/examples/multiple_streaming_compression.c new file mode 100644 index 000000000..b12ad03dc --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/multiple_streaming_compression.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* The objective of this example is to show of to compress multiple successive files +* while preserving memory management. +* All structures and buffers will be created only once, +* and shared across all compression operations */ + +#include // printf +#include // free +#include // memset, strcat +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + +typedef struct { + void* buffIn; + void* buffOut; + size_t buffInSize; + size_t buffOutSize; + ZSTD_CCtx* cctx; +} resources; + +static resources createResources_orDie(int cLevel) +{ + resources ress; + ress.buffInSize = ZSTD_CStreamInSize(); /* can always read one full block */ + ress.buffOutSize= ZSTD_CStreamOutSize(); /* can always flush a full block */ + ress.buffIn = malloc_orDie(ress.buffInSize); + ress.buffOut= malloc_orDie(ress.buffOutSize); + ress.cctx = ZSTD_createCCtx(); + CHECK(ress.cctx != NULL, "ZSTD_createCCtx() failed!"); + + /* Set any compression parameters you want here. + * They will persist for every compression operation. + * Here we set the compression level, and enable the checksum. + */ + CHECK_ZSTD( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_compressionLevel, cLevel) ); + CHECK_ZSTD( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_checksumFlag, 1) ); + return ress; +} + +static void freeResources(resources ress) +{ + ZSTD_freeCCtx(ress.cctx); + free(ress.buffIn); + free(ress.buffOut); +} + +static void compressFile_orDie(resources ress, const char* fname, const char* outName) +{ + // Open the input and output files. + FILE* const fin = fopen_orDie(fname, "rb"); + FILE* const fout = fopen_orDie(outName, "wb"); + + /* Reset the context to a clean state to start a new compression operation. + * The parameters are sticky, so we keep the compression level and extra + * parameters that we set in createResources_orDie(). + */ + CHECK_ZSTD( ZSTD_CCtx_reset(ress.cctx, ZSTD_reset_session_only) ); + + size_t const toRead = ress.buffInSize; + size_t read; + while ( (read = fread_orDie(ress.buffIn, toRead, fin)) ) { + /* This loop is the same as streaming_compression.c. + * See that file for detailed comments. + */ + int const lastChunk = (read < toRead); + ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue; + + ZSTD_inBuffer input = { ress.buffIn, read, 0 }; + int finished; + do { + ZSTD_outBuffer output = { ress.buffOut, ress.buffOutSize, 0 }; + size_t const remaining = ZSTD_compressStream2(ress.cctx, &output, &input, mode); + CHECK_ZSTD(remaining); + fwrite_orDie(ress.buffOut, output.pos, fout); + finished = lastChunk ? (remaining == 0) : (input.pos == input.size); + } while (!finished); + CHECK(input.pos == input.size, + "Impossible: zstd only returns 0 when the input is completely consumed!"); + } + + fclose_orDie(fout); + fclose_orDie(fin); +} + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc<2) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s FILE(s)\n", exeName); + return 1; + } + + int const cLevel = 7; + resources const ress = createResources_orDie(cLevel); + void* ofnBuffer = NULL; + size_t ofnbSize = 0; + + int argNb; + for (argNb = 1; argNb < argc; argNb++) { + const char* const ifn = argv[argNb]; + size_t const ifnSize = strlen(ifn); + size_t const ofnSize = ifnSize + 5; + if (ofnbSize <= ofnSize) { + ofnbSize = ofnSize + 16; + free(ofnBuffer); + ofnBuffer = malloc_orDie(ofnbSize); + } + memset(ofnBuffer, 0, ofnSize); + strcat(ofnBuffer, ifn); + strcat(ofnBuffer, ".zst"); + compressFile_orDie(ress, ifn, ofnBuffer); + } + + freeResources(ress); + free(ofnBuffer); + + printf("compressed %i files \n", argc-1); + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/examples/simple_compression.c b/cpp/third_party/zstd-1.5.7/examples/simple_compression.c new file mode 100644 index 000000000..7c880725f --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/simple_compression.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include // printf +#include // free +#include // strlen, strcat, memset +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + +static void compress_orDie(const char* fname, const char* oname) +{ + size_t fSize; + void* const fBuff = mallocAndLoadFile_orDie(fname, &fSize); + size_t const cBuffSize = ZSTD_compressBound(fSize); + void* const cBuff = malloc_orDie(cBuffSize); + + /* Compress. + * If you are doing many compressions, you may want to reuse the context. + * See the multiple_simple_compression.c example. + */ + size_t const cSize = ZSTD_compress(cBuff, cBuffSize, fBuff, fSize, 1); + CHECK_ZSTD(cSize); + + saveFile_orDie(oname, cBuff, cSize); + + /* success */ + printf("%25s : %6u -> %7u - %s \n", fname, (unsigned)fSize, (unsigned)cSize, oname); + + free(fBuff); + free(cBuff); +} + +static char* createOutFilename_orDie(const char* filename) +{ + size_t const inL = strlen(filename); + size_t const outL = inL + 5; + void* const outSpace = malloc_orDie(outL); + memset(outSpace, 0, outL); + strcat(outSpace, filename); + strcat(outSpace, ".zst"); + return (char*)outSpace; +} + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc!=2) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s FILE\n", exeName); + return 1; + } + + const char* const inFilename = argv[1]; + + char* const outFilename = createOutFilename_orDie(inFilename); + compress_orDie(inFilename, outFilename); + free(outFilename); + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/examples/simple_decompression.c b/cpp/third_party/zstd-1.5.7/examples/simple_decompression.c new file mode 100644 index 000000000..f499156f6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/simple_decompression.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include // printf +#include // free +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + +static void decompress(const char* fname) +{ + size_t cSize; + void* const cBuff = mallocAndLoadFile_orDie(fname, &cSize); + /* Read the content size from the frame header. For simplicity we require + * that it is always present. By default, zstd will write the content size + * in the header when it is known. If you can't guarantee that the frame + * content size is always written into the header, either use streaming + * decompression, or ZSTD_decompressBound(). + */ + unsigned long long const rSize = ZSTD_getFrameContentSize(cBuff, cSize); + CHECK(rSize != ZSTD_CONTENTSIZE_ERROR, "%s: not compressed by zstd!", fname); + CHECK(rSize != ZSTD_CONTENTSIZE_UNKNOWN, "%s: original size unknown!", fname); + + void* const rBuff = malloc_orDie((size_t)rSize); + + /* Decompress. + * If you are doing many decompressions, you may want to reuse the context + * and use ZSTD_decompressDCtx(). If you want to set advanced parameters, + * use ZSTD_DCtx_setParameter(). + */ + size_t const dSize = ZSTD_decompress(rBuff, rSize, cBuff, cSize); + CHECK_ZSTD(dSize); + /* When zstd knows the content size, it will error if it doesn't match. */ + CHECK(dSize == rSize, "Impossible because zstd will check this condition!"); + + /* success */ + printf("%25s : %6u -> %7u \n", fname, (unsigned)cSize, (unsigned)rSize); + + free(rBuff); + free(cBuff); +} + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc!=2) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s FILE\n", exeName); + return 1; + } + + decompress(argv[1]); + + printf("%s correctly decoded (in memory). \n", argv[1]); + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/examples/streaming_compression.c b/cpp/third_party/zstd-1.5.7/examples/streaming_compression.c new file mode 100644 index 000000000..063aa82a2 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/streaming_compression.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#include // printf +#include // free +#include // memset, strcat, strlen +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + +static void compressFile_orDie(const char* fname, const char* outName, int cLevel, + int nbThreads) +{ + fprintf (stderr, "Starting compression of %s with level %d, using %d threads\n", + fname, cLevel, nbThreads); + + /* Open the input and output files. */ + FILE* const fin = fopen_orDie(fname, "rb"); + FILE* const fout = fopen_orDie(outName, "wb"); + /* Create the input and output buffers. + * They may be any size, but we recommend using these functions to size them. + * Performance will only suffer significantly for very tiny buffers. + */ + size_t const buffInSize = ZSTD_CStreamInSize(); + void* const buffIn = malloc_orDie(buffInSize); + size_t const buffOutSize = ZSTD_CStreamOutSize(); + void* const buffOut = malloc_orDie(buffOutSize); + + /* Create the context. */ + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + CHECK(cctx != NULL, "ZSTD_createCCtx() failed!"); + + /* Set any parameters you want. + * Here we set the compression level, and enable the checksum. + */ + CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, cLevel) ); + CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1) ); + if (nbThreads > 1) { + size_t const r = ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, nbThreads); + if (ZSTD_isError(r)) { + fprintf (stderr, "Note: the linked libzstd library doesn't support multithreading. " + "Reverting to single-thread mode. \n"); + } + } + + /* This loop read from the input file, compresses that entire chunk, + * and writes all output produced to the output file. + */ + size_t const toRead = buffInSize; + for (;;) { + size_t read = fread_orDie(buffIn, toRead, fin); + /* Select the flush mode. + * If the read may not be finished (read == toRead) we use + * ZSTD_e_continue. If this is the last chunk, we use ZSTD_e_end. + * Zstd optimizes the case where the first flush mode is ZSTD_e_end, + * since it knows it is compressing the entire source in one pass. + */ + int const lastChunk = (read < toRead); + ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue; + /* Set the input buffer to what we just read. + * We compress until the input buffer is empty, each time flushing the + * output. + */ + ZSTD_inBuffer input = { buffIn, read, 0 }; + int finished; + do { + /* Compress into the output buffer and write all of the output to + * the file so we can reuse the buffer next iteration. + */ + ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; + size_t const remaining = ZSTD_compressStream2(cctx, &output , &input, mode); + CHECK_ZSTD(remaining); + fwrite_orDie(buffOut, output.pos, fout); + /* If we're on the last chunk we're finished when zstd returns 0, + * which means its consumed all the input AND finished the frame. + * Otherwise, we're finished when we've consumed all the input. + */ + finished = lastChunk ? (remaining == 0) : (input.pos == input.size); + } while (!finished); + CHECK(input.pos == input.size, + "Impossible: zstd only returns 0 when the input is completely consumed!"); + + if (lastChunk) { + break; + } + } + + ZSTD_freeCCtx(cctx); + fclose_orDie(fout); + fclose_orDie(fin); + free(buffIn); + free(buffOut); +} + + +static char* createOutFilename_orDie(const char* filename) +{ + size_t const inL = strlen(filename); + size_t const outL = inL + 5; + void* const outSpace = malloc_orDie(outL); + memset(outSpace, 0, outL); + strcat(outSpace, filename); + strcat(outSpace, ".zst"); + return (char*)outSpace; +} + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc < 2) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s FILE [LEVEL] [THREADS]\n", exeName); + return 1; + } + + int cLevel = 1; + int nbThreads = 1; + + if (argc >= 3) { + cLevel = atoi (argv[2]); + CHECK(cLevel != 0, "can't parse LEVEL!"); + } + + if (argc >= 4) { + nbThreads = atoi (argv[3]); + CHECK(nbThreads != 0, "can't parse THREADS!"); + } + + const char* const inFilename = argv[1]; + + char* const outFilename = createOutFilename_orDie(inFilename); + compressFile_orDie(inFilename, outFilename, cLevel, nbThreads); + + free(outFilename); /* not strictly required, since program execution stops there, + * but some static analyzer may complain otherwise */ + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/examples/streaming_compression_thread_pool.c b/cpp/third_party/zstd-1.5.7/examples/streaming_compression_thread_pool.c new file mode 100644 index 000000000..a1a024129 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/streaming_compression_thread_pool.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) Martin Liska, SUSE, Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#include // printf +#include // free +#include // memset, strcat, strlen +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() +#include + +typedef struct compress_args +{ + const char *fname; + char *outName; + int cLevel; +#if defined(ZSTD_STATIC_LINKING_ONLY) + ZSTD_threadPool *pool; +#endif +} compress_args_t; + +static void *compressFile_orDie(void *data) +{ + const int nbThreads = 16; + + compress_args_t *args = (compress_args_t *)data; + fprintf (stderr, "Starting compression of %s with level %d, using %d threads\n", args->fname, args->cLevel, nbThreads); + /* Open the input and output files. */ + FILE* const fin = fopen_orDie(args->fname, "rb"); + FILE* const fout = fopen_orDie(args->outName, "wb"); + /* Create the input and output buffers. + * They may be any size, but we recommend using these functions to size them. + * Performance will only suffer significantly for very tiny buffers. + */ + size_t const buffInSize = ZSTD_CStreamInSize(); + void* const buffIn = malloc_orDie(buffInSize); + size_t const buffOutSize = ZSTD_CStreamOutSize(); + void* const buffOut = malloc_orDie(buffOutSize); + + /* Create the context. */ + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + CHECK(cctx != NULL, "ZSTD_createCCtx() failed!"); + +#if defined(ZSTD_STATIC_LINKING_ONLY) + size_t r = ZSTD_CCtx_refThreadPool(cctx, args->pool); + CHECK(r == 0, "ZSTD_CCtx_refThreadPool failed!"); +#endif + + /* Set any parameters you want. + * Here we set the compression level, and enable the checksum. + */ + CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, args->cLevel) ); + CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1) ); + ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, nbThreads); + + /* This loop reads from the input file, compresses that entire chunk, + * and writes all output produced to the output file. + */ + size_t const toRead = buffInSize; + for (;;) { + size_t read = fread_orDie(buffIn, toRead, fin); + /* Select the flush mode. + * If the read may not be finished (read == toRead) we use + * ZSTD_e_continue. If this is the last chunk, we use ZSTD_e_end. + * Zstd optimizes the case where the first flush mode is ZSTD_e_end, + * since it knows it is compressing the entire source in one pass. + */ + int const lastChunk = (read < toRead); + ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue; + /* Set the input buffer to what we just read. + * We compress until the input buffer is empty, each time flushing the + * output. + */ + ZSTD_inBuffer input = { buffIn, read, 0 }; + int finished; + do { + /* Compress into the output buffer and write all of the output to + * the file so we can reuse the buffer next iteration. + */ + ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; + size_t const remaining = ZSTD_compressStream2(cctx, &output , &input, mode); + CHECK_ZSTD(remaining); + fwrite_orDie(buffOut, output.pos, fout); + /* If we're on the last chunk we're finished when zstd returns 0, + * which means its consumed all the input AND finished the frame. + * Otherwise, we're finished when we've consumed all the input. + */ + finished = lastChunk ? (remaining == 0) : (input.pos == input.size); + } while (!finished); + CHECK(input.pos == input.size, + "Impossible: zstd only returns 0 when the input is completely consumed!"); + + if (lastChunk) { + break; + } + } + + fprintf (stderr, "Finishing compression of %s\n", args->outName); + + ZSTD_freeCCtx(cctx); + fclose_orDie(fout); + fclose_orDie(fin); + free(buffIn); + free(buffOut); + free(args->outName); + + return NULL; +} + + +static char* createOutFilename_orDie(const char* filename) +{ + size_t const inL = strlen(filename); + size_t const outL = inL + 5; + void* const outSpace = malloc_orDie(outL); + memset(outSpace, 0, outL); + strcat(outSpace, filename); + strcat(outSpace, ".zst"); + return (char*)outSpace; +} + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc<=3) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s POOL_SIZE LEVEL FILES\n", exeName); + return 1; + } + + int pool_size = atoi (argv[1]); + CHECK(pool_size != 0, "can't parse POOL_SIZE!"); + + int level = atoi (argv[2]); + CHECK(level != 0, "can't parse LEVEL!"); + + argc -= 3; + argv += 3; + +#if defined(ZSTD_STATIC_LINKING_ONLY) + ZSTD_threadPool *pool = ZSTD_createThreadPool (pool_size); + CHECK(pool != NULL, "ZSTD_createThreadPool() failed!"); + fprintf (stderr, "Using shared thread pool of size %d\n", pool_size); +#else + fprintf (stderr, "All threads use its own thread pool\n"); +#endif + + pthread_t *threads = malloc_orDie(argc * sizeof(pthread_t)); + compress_args_t *args = malloc_orDie(argc * sizeof(compress_args_t)); + + for (unsigned i = 0; i < argc; i++) + { + args[i].fname = argv[i]; + args[i].outName = createOutFilename_orDie(args[i].fname); + args[i].cLevel = level; +#if defined(ZSTD_STATIC_LINKING_ONLY) + args[i].pool = pool; +#endif + + pthread_create (&threads[i], NULL, compressFile_orDie, &args[i]); + } + + for (unsigned i = 0; i < argc; i++) + pthread_join (threads[i], NULL); + +#if defined(ZSTD_STATIC_LINKING_ONLY) + ZSTD_freeThreadPool (pool); +#endif + + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/examples/streaming_decompression.c b/cpp/third_party/zstd-1.5.7/examples/streaming_decompression.c new file mode 100644 index 000000000..95fa11227 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/streaming_decompression.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#include // fprintf +#include // free +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + +static void decompressFile_orDie(const char* fname) +{ + FILE* const fin = fopen_orDie(fname, "rb"); + size_t const buffInSize = ZSTD_DStreamInSize(); + void* const buffIn = malloc_orDie(buffInSize); + FILE* const fout = stdout; + size_t const buffOutSize = ZSTD_DStreamOutSize(); /* Guarantee to successfully flush at least one complete compressed block in all circumstances. */ + void* const buffOut = malloc_orDie(buffOutSize); + + ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + CHECK(dctx != NULL, "ZSTD_createDCtx() failed!"); + + /* This loop assumes that the input file is one or more concatenated zstd + * streams. This example won't work if there is trailing non-zstd data at + * the end, but streaming decompression in general handles this case. + * ZSTD_decompressStream() returns 0 exactly when the frame is completed, + * and doesn't consume input after the frame. + */ + size_t const toRead = buffInSize; + size_t read; + size_t lastRet = 0; + int isEmpty = 1; + while ( (read = fread_orDie(buffIn, toRead, fin)) ) { + isEmpty = 0; + ZSTD_inBuffer input = { buffIn, read, 0 }; + /* Given a valid frame, zstd won't consume the last byte of the frame + * until it has flushed all of the decompressed data of the frame. + * Therefore, instead of checking if the return code is 0, we can + * decompress just check if input.pos < input.size. + */ + while (input.pos < input.size) { + ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; + /* The return code is zero if the frame is complete, but there may + * be multiple frames concatenated together. Zstd will automatically + * reset the context when a frame is complete. Still, calling + * ZSTD_DCtx_reset() can be useful to reset the context to a clean + * state, for instance if the last decompression call returned an + * error. + */ + size_t const ret = ZSTD_decompressStream(dctx, &output , &input); + CHECK_ZSTD(ret); + fwrite_orDie(buffOut, output.pos, fout); + lastRet = ret; + } + } + + if (isEmpty) { + fprintf(stderr, "input is empty\n"); + exit(1); + } + + if (lastRet != 0) { + /* The last return value from ZSTD_decompressStream did not end on a + * frame, but we reached the end of the file! We assume this is an + * error, and the input was truncated. + */ + fprintf(stderr, "EOF before end of stream: %zu\n", lastRet); + exit(1); + } + + ZSTD_freeDCtx(dctx); + fclose_orDie(fin); + fclose_orDie(fout); + free(buffIn); + free(buffOut); +} + + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc!=2) { + fprintf(stderr, "wrong arguments\n"); + fprintf(stderr, "usage:\n"); + fprintf(stderr, "%s FILE\n", exeName); + return 1; + } + + const char* const inFilename = argv[1]; + + decompressFile_orDie(inFilename); + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/examples/streaming_memory_usage.c b/cpp/third_party/zstd-1.5.7/examples/streaming_memory_usage.c new file mode 100644 index 000000000..957acb61a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/examples/streaming_memory_usage.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/*=== Tuning parameter ===*/ +#ifndef MAX_TESTED_LEVEL +#define MAX_TESTED_LEVEL 12 +#endif + + +/*=== Dependencies ===*/ +#include // printf +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed +#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() + + +/*=== functions ===*/ + +/*! readU32FromChar() : + @return : unsigned integer value read from input in `char` format + allows and interprets K, KB, KiB, M, MB and MiB suffix. + Will also modify `*stringPtr`, advancing it to position where it stopped reading. + Note : function result can overflow if digit string > MAX_UINT */ +static unsigned readU32FromChar(const char** stringPtr) +{ + unsigned result = 0; + while ((**stringPtr >='0') && (**stringPtr <='9')) + result *= 10, result += **stringPtr - '0', (*stringPtr)++ ; + if ((**stringPtr=='K') || (**stringPtr=='M')) { + result <<= 10; + if (**stringPtr=='M') result <<= 10; + (*stringPtr)++ ; + if (**stringPtr=='i') (*stringPtr)++; + if (**stringPtr=='B') (*stringPtr)++; + } + return result; +} + + +int main(int argc, char const *argv[]) { + + printf("\n Zstandard (v%s) memory usage for streaming : \n\n", ZSTD_versionString()); + + unsigned wLog = 0; + if (argc > 1) { + const char* valStr = argv[1]; + wLog = readU32FromChar(&valStr); + } + + int compressionLevel; + for (compressionLevel = 1; compressionLevel <= MAX_TESTED_LEVEL; compressionLevel++) { +#define INPUT_SIZE 5 +#define COMPRESSED_SIZE 128 + char const dataToCompress[INPUT_SIZE] = "abcde"; + char compressedData[COMPRESSED_SIZE]; + char decompressedData[INPUT_SIZE]; + /* the ZSTD_CCtx_params structure is a way to save parameters and use + * them across multiple contexts. We use them here so we can call the + * function ZSTD_estimateCStreamSize_usingCCtxParams(). + */ + ZSTD_CCtx_params* const cctxParams = ZSTD_createCCtxParams(); + CHECK(cctxParams != NULL, "ZSTD_createCCtxParams() failed!"); + + /* Set the compression level. */ + CHECK_ZSTD( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_compressionLevel, compressionLevel) ); + /* Set the window log. + * The value 0 means use the default window log, which is equivalent to + * not setting it. + */ + CHECK_ZSTD( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_windowLog, wLog) ); + + /* Force the compressor to allocate the maximum memory size for a given + * level by not providing the pledged source size, or calling + * ZSTD_compressStream2() with ZSTD_e_end. + */ + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + CHECK(cctx != NULL, "ZSTD_createCCtx() failed!"); + CHECK_ZSTD( ZSTD_CCtx_setParametersUsingCCtxParams(cctx, cctxParams) ); + size_t compressedSize; + { + ZSTD_inBuffer inBuff = { dataToCompress, sizeof(dataToCompress), 0 }; + ZSTD_outBuffer outBuff = { compressedData, sizeof(compressedData), 0 }; + CHECK_ZSTD( ZSTD_compressStream(cctx, &outBuff, &inBuff) ); + size_t const remaining = ZSTD_endStream(cctx, &outBuff); + CHECK_ZSTD(remaining); + CHECK(remaining == 0, "Frame not flushed!"); + compressedSize = outBuff.pos; + } + + ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + CHECK(dctx != NULL, "ZSTD_createDCtx() failed!"); + /* Set the maximum allowed window log. + * The value 0 means use the default window log, which is equivalent to + * not setting it. + */ + CHECK_ZSTD( ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, wLog) ); + /* forces decompressor to use maximum memory size, since the + * decompressed size is not stored in the frame header. + */ + { ZSTD_inBuffer inBuff = { compressedData, compressedSize, 0 }; + ZSTD_outBuffer outBuff = { decompressedData, sizeof(decompressedData), 0 }; + size_t const remaining = ZSTD_decompressStream(dctx, &outBuff, &inBuff); + CHECK_ZSTD(remaining); + CHECK(remaining == 0, "Frame not complete!"); + CHECK(outBuff.pos == sizeof(dataToCompress), "Bad decompression!"); + } + + size_t const cstreamSize = ZSTD_sizeof_CStream(cctx); + size_t const cstreamEstimatedSize = ZSTD_estimateCStreamSize_usingCCtxParams(cctxParams); + size_t const dstreamSize = ZSTD_sizeof_DStream(dctx); + size_t const dstreamEstimatedSize = ZSTD_estimateDStreamSize_fromFrame(compressedData, compressedSize); + + CHECK(cstreamSize <= cstreamEstimatedSize, "Compression mem (%u) > estimated (%u)", + (unsigned)cstreamSize, (unsigned)cstreamEstimatedSize); + CHECK(dstreamSize <= dstreamEstimatedSize, "Decompression mem (%u) > estimated (%u)", + (unsigned)dstreamSize, (unsigned)dstreamEstimatedSize); + + printf("Level %2i : Compression Mem = %5u KB (estimated : %5u KB) ; Decompression Mem = %4u KB (estimated : %5u KB)\n", + compressionLevel, + (unsigned)(cstreamSize>>10), (unsigned)(cstreamEstimatedSize>>10), + (unsigned)(dstreamSize>>10), (unsigned)(dstreamEstimatedSize>>10)); + + ZSTD_freeDCtx(dctx); + ZSTD_freeCCtx(cctx); + ZSTD_freeCCtxParams(cctxParams); + if (wLog) break; /* single test */ + } + return 0; +} diff --git a/cpp/third_party/zstd-1.5.7/lib/.gitignore b/cpp/third_party/zstd-1.5.7/lib/.gitignore new file mode 100644 index 000000000..4cd50ac61 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/.gitignore @@ -0,0 +1,3 @@ +# make install artefact +libzstd.pc +libzstd-nomt diff --git a/cpp/third_party/zstd-1.5.7/lib/BUCK b/cpp/third_party/zstd-1.5.7/lib/BUCK new file mode 100644 index 000000000..60c6bbb54 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/BUCK @@ -0,0 +1,232 @@ +cxx_library( + name='zstd', + header_namespace='', + exported_headers=['zstd.h'], + visibility=['PUBLIC'], + deps=[ + ':common', + ':compress', + ':decompress', + ':deprecated', + ], +) + +cxx_library( + name='compress', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('compress', 'zstd*.h'), + ]), + srcs=glob(['compress/zstd*.c', 'compress/hist.c']), + deps=[':common'], +) + +cxx_library( + name='decompress', + header_namespace='', + visibility=['PUBLIC'], + headers=subdir_glob([ + ('decompress', '*_impl.h'), + ]), + srcs=glob(['decompress/zstd*.c']), + deps=[ + ':common', + ':legacy', + ], +) + +cxx_library( + name='deprecated', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('deprecated', '*.h'), + ]), + srcs=glob(['deprecated/*.c']), + deps=[':common'], +) + +cxx_library( + name='legacy', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('legacy', '*.h'), + ]), + srcs=glob(['legacy/*.c']), + deps=[':common'], + exported_preprocessor_flags=[ + '-DZSTD_LEGACY_SUPPORT=4', + ], +) + +cxx_library( + name='zdict', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=['zdict.h'], + headers=subdir_glob([ + ('dictBuilder', 'divsufsort.h'), + ('dictBuilder', 'cover.h'), + ]), + srcs=glob(['dictBuilder/*.c']), + deps=[':common'], +) + +cxx_library( + name='compiler', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'compiler.h'), + ]), +) + +cxx_library( + name='cpu', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'cpu.h'), + ]), +) + +cxx_library( + name='bitstream', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'bitstream.h'), + ]), +) + +cxx_library( + name='entropy', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'fse.h'), + ('common', 'huf.h'), + ]), + srcs=[ + 'common/entropy_common.c', + 'common/fse_decompress.c', + 'compress/fse_compress.c', + 'compress/huf_compress.c', + 'decompress/huf_decompress.c', + ], + deps=[ + ':debug', + ':bitstream', + ':compiler', + ':errors', + ':mem', + ], +) + +cxx_library( + name='errors', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=[ + 'zstd_errors.h', + 'common/error_private.h', + ] + srcs=['common/error_private.c'], +) + +cxx_library( + name='mem', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'mem.h'), + ]), +) + +cxx_library( + name='pool', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'pool.h'), + ]), + srcs=['common/pool.c'], + deps=[ + ':threading', + ':zstd_common', + ], +) + +cxx_library( + name='threading', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'threading.h'), + ]), + srcs=['common/threading.c'], + exported_preprocessor_flags=[ + '-DZSTD_MULTITHREAD', + ], + exported_linker_flags=[ + '-pthread', + ], +) + +cxx_library( + name='xxhash', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'xxhash.h'), + ]), + srcs=['common/xxhash.c'], + exported_preprocessor_flags=[ + '-DXXH_NAMESPACE=ZSTD_', + ], +) + +cxx_library( + name='zstd_common', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('', 'zstd.h'), + ('common', 'zstd_internal.h'), + ]), + srcs=['common/zstd_common.c'], + deps=[ + ':compiler', + ':errors', + ':mem', + ], +) + +cxx_library( + name='debug', + header_namespace='', + visibility=['PUBLIC'], + exported_headers=subdir_glob([ + ('common', 'debug.h'), + ]), + srcs=['common/debug.c'], +) + +cxx_library( + name='common', + deps=[ + ':debug', + ':bitstream', + ':compiler', + ':cpu', + ':entropy', + ':errors', + ':mem', + ':pool', + ':threading', + ':xxhash', + ':zstd_common', + ] +) diff --git a/cpp/third_party/zstd-1.5.7/lib/Makefile b/cpp/third_party/zstd-1.5.7/lib/Makefile new file mode 100644 index 000000000..a6a0eb09d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/Makefile @@ -0,0 +1,389 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ + +# default target (when running `make` with no argument) +lib-release: + +# Modules +ZSTD_LIB_COMPRESSION ?= 1 +ZSTD_LIB_DECOMPRESSION ?= 1 +ZSTD_LIB_DICTBUILDER ?= 1 +ZSTD_LIB_DEPRECATED ?= 0 + +# Input variables for libzstd.mk +ifeq ($(ZSTD_LIB_COMPRESSION), 0) + ZSTD_LIB_DICTBUILDER = 0 + ZSTD_LIB_DEPRECATED = 0 +endif + +ifeq ($(ZSTD_LIB_DECOMPRESSION), 0) + ZSTD_LEGACY_SUPPORT = 0 + ZSTD_LIB_DEPRECATED = 0 +endif + +include libzstd.mk + +ZSTD_FILES := $(ZSTD_COMMON_FILES) $(ZSTD_LEGACY_FILES) + +ifneq ($(ZSTD_LIB_COMPRESSION), 0) + ZSTD_FILES += $(ZSTD_COMPRESS_FILES) +endif + +ifneq ($(ZSTD_LIB_DECOMPRESSION), 0) + ZSTD_FILES += $(ZSTD_DECOMPRESS_FILES) +endif + +ifneq ($(ZSTD_LIB_DEPRECATED), 0) + ZSTD_FILES += $(ZSTD_DEPRECATED_FILES) +endif + +ifneq ($(ZSTD_LIB_DICTBUILDER), 0) + ZSTD_FILES += $(ZSTD_DICTBUILDER_FILES) +endif + +ZSTD_LOCAL_SRC := $(notdir $(ZSTD_FILES)) +ZSTD_LOCAL_OBJ0 := $(ZSTD_LOCAL_SRC:.c=.o) +ZSTD_LOCAL_OBJ := $(ZSTD_LOCAL_OBJ0:.S=.o) + +VERSION := $(ZSTD_VERSION) + +# Note: by default, the static library is built single-threaded and dynamic library is built +# multi-threaded. It is possible to force multi or single threaded builds by appending +# -mt or -nomt to the build target (like lib-mt for multi-threaded, lib-nomt for single-threaded). + + +CPPFLAGS_DYNLIB += -DZSTD_MULTITHREAD # dynamic library build defaults to multi-threaded +LDFLAGS_DYNLIB += -pthread +CPPFLAGS_STATICLIB += # static library build defaults to single-threaded + +# pkg-config Libs.private points to LDFLAGS_DYNLIB +PCLIB := $(LDFLAGS_DYNLIB) + +ifeq ($(findstring GCC,$(CCVER)),GCC) +decompress/zstd_decompress_block.o : CFLAGS+=-fno-tree-vectorize +endif + + +# macOS linker doesn't support -soname, and use different extension +# see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html +UNAME_TARGET_SYSTEM ?= $(UNAME) + +ifeq ($(UNAME_TARGET_SYSTEM), Darwin) + SHARED_EXT = dylib + SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT) + SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT) + SONAME_FLAGS = -install_name $(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) +else + ifeq ($(UNAME_TARGET_SYSTEM), AIX) + SONAME_FLAGS = + else + SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) + endif + SHARED_EXT = so + SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR) + SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER) +endif + + +.PHONY: all +all: lib + + +.PHONY: libzstd.a # must be run every time +libzstd.a: CPPFLAGS += $(CPPFLAGS_STATICLIB) + +SET_CACHE_DIRECTORY = \ + +$(MAKE) --no-print-directory $@ \ + BUILD_DIR=obj/$(HASH_DIR) \ + CPPFLAGS="$(CPPFLAGS)" \ + CFLAGS="$(CFLAGS)" \ + LDFLAGS="$(LDFLAGS)" + +ifndef BUILD_DIR +# determine BUILD_DIR from compilation flags + +libzstd.a: + $(SET_CACHE_DIRECTORY) + +else +# BUILD_DIR is defined + +ZSTD_STATICLIB_DIR := $(BUILD_DIR)/static +ZSTD_STATICLIB := $(ZSTD_STATICLIB_DIR)/libzstd.a +ZSTD_STATICLIB_OBJ := $(addprefix $(ZSTD_STATICLIB_DIR)/,$(ZSTD_LOCAL_OBJ)) +$(ZSTD_STATICLIB): ARFLAGS = rcs +$(ZSTD_STATICLIB): | $(ZSTD_STATICLIB_DIR) +$(ZSTD_STATICLIB): $(ZSTD_STATICLIB_OBJ) + # Check for multithread flag at target execution time + $(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\ + @echo compiling multi-threaded static library $(LIBVER),\ + @echo compiling single-threaded static library $(LIBVER)) + $(AR) $(ARFLAGS) $@ $^ + +libzstd.a: $(ZSTD_STATICLIB) + cp -f $< $@ + +endif + +ifneq (,$(filter Windows%,$(TARGET_SYSTEM))) + +LIBZSTD = dll/libzstd.dll +$(LIBZSTD): $(ZSTD_FILES) + @echo compiling dynamic library $(LIBVER) + $(CC) $(FLAGS) -DZSTD_DLL_EXPORT=1 -Wl,--out-implib,dll/libzstd.dll.a -shared $^ -o $@ + +else # not Windows + +LIBZSTD = libzstd.$(SHARED_EXT_VER) +.PHONY: $(LIBZSTD) # must be run every time +$(LIBZSTD): CPPFLAGS += $(CPPFLAGS_DYNLIB) +$(LIBZSTD): CFLAGS += -fPIC -fvisibility=hidden +$(LIBZSTD): LDFLAGS += -shared $(LDFLAGS_DYNLIB) + +ifndef BUILD_DIR +# determine BUILD_DIR from compilation flags + +$(LIBZSTD): + $(SET_CACHE_DIRECTORY) + +else +# BUILD_DIR is defined + +ZSTD_DYNLIB_DIR := $(BUILD_DIR)/dynamic +ZSTD_DYNLIB := $(ZSTD_DYNLIB_DIR)/$(LIBZSTD) +ZSTD_DYNLIB_OBJ := $(addprefix $(ZSTD_DYNLIB_DIR)/,$(ZSTD_LOCAL_OBJ)) + +$(ZSTD_DYNLIB): | $(ZSTD_DYNLIB_DIR) +$(ZSTD_DYNLIB): $(ZSTD_DYNLIB_OBJ) +# Check for multithread flag at target execution time + $(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\ + @echo compiling multi-threaded dynamic library $(LIBVER),\ + @echo compiling single-threaded dynamic library $(LIBVER)) + $(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ + @echo creating versioned links + ln -sf $@ libzstd.$(SHARED_EXT_MAJOR) + ln -sf $@ libzstd.$(SHARED_EXT) + +$(LIBZSTD): $(ZSTD_DYNLIB) + cp -f $< $@ + +endif # ifndef BUILD_DIR +endif # if windows + +.PHONY: libzstd +libzstd : $(LIBZSTD) + +.PHONY: lib +lib : libzstd.a libzstd + + +# note : do not define lib-mt or lib-release as .PHONY +# make does not consider implicit pattern rule for .PHONY target + +%-mt : CPPFLAGS_DYNLIB := -DZSTD_MULTITHREAD +%-mt : CPPFLAGS_STATICLIB := -DZSTD_MULTITHREAD +%-mt : LDFLAGS_DYNLIB := -pthread +%-mt : PCLIB := +%-mt : PCMTLIB := $(LDFLAGS_DYNLIB) +%-mt : % + @echo multi-threaded build completed + +%-nomt : CPPFLAGS_DYNLIB := +%-nomt : LDFLAGS_DYNLIB := +%-nomt : CPPFLAGS_STATICLIB := +%-nomt : PCLIB := +%-nomt : % + @echo single-threaded build completed + +%-release : DEBUGFLAGS := +%-release : % + @echo release build completed + + +# Generate .h dependencies automatically + +# -MMD: compiler generates dependency information as a side-effect of compilation, without system headers +# -MP: adds phony target for each dependency other than main file. +DEPFLAGS = -MMD -MP + +# ensure that ZSTD_DYNLIB_DIR exists prior to generating %.o +$(ZSTD_DYNLIB_DIR)/%.o : %.c | $(ZSTD_DYNLIB_DIR) + @echo CC $@ + $(COMPILE.c) $(DEPFLAGS) $(OUTPUT_OPTION) $< + +$(ZSTD_STATICLIB_DIR)/%.o : %.c | $(ZSTD_STATICLIB_DIR) + @echo CC $@ + $(COMPILE.c) $(DEPFLAGS) $(OUTPUT_OPTION) $< + +$(ZSTD_DYNLIB_DIR)/%.o : %.S | $(ZSTD_DYNLIB_DIR) + @echo AS $@ + $(COMPILE.S) $(OUTPUT_OPTION) $< + +$(ZSTD_STATICLIB_DIR)/%.o : %.S | $(ZSTD_STATICLIB_DIR) + @echo AS $@ + $(COMPILE.S) $(OUTPUT_OPTION) $< + +MKDIR ?= mkdir -p +$(BUILD_DIR) $(ZSTD_DYNLIB_DIR) $(ZSTD_STATICLIB_DIR): + $(MKDIR) $@ + +DEPFILES := $(ZSTD_DYNLIB_OBJ:.o=.d) $(ZSTD_STATICLIB_OBJ:.o=.d) +$(DEPFILES): + +# The leading '-' means: do not fail is include fails (ex: directory does not exist yet) +-include $(wildcard $(DEPFILES)) + + +# Special case : build library in single-thread mode _and_ without zstdmt_compress.c +# Note : we still need threading.c and pool.c for the dictionary builder, +# but they will correctly behave single-threaded. +ZSTDMT_FILES = zstdmt_compress.c +ZSTD_NOMT_FILES = $(filter-out $(ZSTDMT_FILES),$(notdir $(ZSTD_FILES))) +libzstd-nomt: CFLAGS += -fPIC -fvisibility=hidden +libzstd-nomt: LDFLAGS += -shared +libzstd-nomt: $(ZSTD_NOMT_FILES) + @echo compiling single-thread dynamic library $(LIBVER) + @echo files : $(ZSTD_NOMT_FILES) + @if echo "$(ZSTD_NOMT_FILES)" | tr ' ' '\n' | $(GREP) -q zstdmt; then \ + echo "Error: Found zstdmt in list."; \ + exit 1; \ + fi + $(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ + +.PHONY: clean +clean: + $(RM) -r *.dSYM # macOS-specific + $(RM) core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc + $(RM) dll/libzstd.dll dll/libzstd.lib libzstd-nomt* + $(RM) -r obj/* + @echo Cleaning library completed + +#----------------------------------------------------------------------------- +# make install is validated only for below listed environments +#----------------------------------------------------------------------------- +ifneq (,$(filter Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX MSYS_NT% CYGWIN_NT%,$(UNAME))) + +lib: libzstd.pc + +HAS_EXPLICIT_EXEC_PREFIX := $(if $(or $(EXEC_PREFIX),$(exec_prefix)),1,) + +DESTDIR ?= +# directory variables : GNU conventions prefer lowercase +# see https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html +# support both lower and uppercase (BSD), use uppercase in script +prefix ?= /usr/local +PREFIX ?= $(prefix) +exec_prefix ?= $(PREFIX) +EXEC_PREFIX ?= $(exec_prefix) +libdir ?= $(EXEC_PREFIX)/lib +LIBDIR ?= $(libdir) +includedir ?= $(PREFIX)/include +INCLUDEDIR ?= $(includedir) + +PCINCDIR := $(patsubst $(PREFIX)%,%,$(INCLUDEDIR)) +PCLIBDIR := $(patsubst $(EXEC_PREFIX)%,%,$(LIBDIR)) + +# If we successfully stripped off a prefix, we'll add a reference to the +# relevant pc variable. +PCINCPREFIX := $(if $(findstring $(INCLUDEDIR),$(PCINCDIR)),,$${prefix}) +PCLIBPREFIX := $(if $(findstring $(LIBDIR),$(PCLIBDIR)),,$${exec_prefix}) + +# If no explicit EXEC_PREFIX was set by the caller, write it out as a reference +# to PREFIX, rather than as a resolved value. +PCEXEC_PREFIX := $(if $(HAS_EXPLICIT_EXEC_PREFIX),$(EXEC_PREFIX),$${prefix}) + + +ifneq ($(MT),) + PCLIB := + PCMTLIB := $(LDFLAGS_DYNLIB) +else + PCLIB := $(LDFLAGS_DYNLIB) +endif + +ifneq (,$(filter FreeBSD NetBSD DragonFly,$(UNAME))) + PKGCONFIGDIR ?= $(PREFIX)/libdata/pkgconfig +else + PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig +endif + +ifneq (,$(filter SunOS,$(UNAME))) + INSTALL ?= ginstall +else + INSTALL ?= install +endif + +INSTALL_PROGRAM ?= $(INSTALL) +INSTALL_DATA ?= $(INSTALL) -m 644 + + +# pkg-config library define. +# For static single-threaded library declare -pthread in Libs.private +# For static multi-threaded library declare -pthread in Libs and Cflags +.PHONY: libzstd.pc +libzstd.pc: libzstd.pc.in + @echo creating pkgconfig + @sed \ + -e 's|@PREFIX@|$(PREFIX)|' \ + -e 's|@EXEC_PREFIX@|$(PCEXEC_PREFIX)|' \ + -e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \ + -e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \ + -e 's|@VERSION@|$(VERSION)|' \ + -e 's|@LIBS_MT@|$(PCMTLIB)|' \ + -e 's|@LIBS_PRIVATE@|$(PCLIB)|' \ + $< >$@ + +.PHONY: install +install: install-pc install-static install-shared install-includes + @echo zstd static and shared library installed + +.PHONY: install-pc +install-pc: libzstd.pc + [ -e $(DESTDIR)$(PKGCONFIGDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(PKGCONFIGDIR)/ + $(INSTALL_DATA) libzstd.pc $(DESTDIR)$(PKGCONFIGDIR)/ + +.PHONY: install-static +install-static: + # only generate libzstd.a if it's not already present + [ -e libzstd.a ] || $(MAKE) libzstd.a-release + [ -e $(DESTDIR)$(LIBDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/ + @echo Installing static library + $(INSTALL_DATA) libzstd.a $(DESTDIR)$(LIBDIR) + +.PHONY: install-shared +install-shared: + # only generate libzstd.so if it's not already present + [ -e $(LIBZSTD) ] || $(MAKE) libzstd-release + [ -e $(DESTDIR)$(LIBDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/ + @echo Installing shared library + $(INSTALL_PROGRAM) $(LIBZSTD) $(DESTDIR)$(LIBDIR) + ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) + ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT) + +.PHONY: install-includes +install-includes: + [ -e $(DESTDIR)$(INCLUDEDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(INCLUDEDIR)/ + @echo Installing includes + $(INSTALL_DATA) zstd.h $(DESTDIR)$(INCLUDEDIR) + $(INSTALL_DATA) zstd_errors.h $(DESTDIR)$(INCLUDEDIR) + $(INSTALL_DATA) zdict.h $(DESTDIR)$(INCLUDEDIR) + +.PHONY: uninstall +uninstall: + $(RM) $(DESTDIR)$(LIBDIR)/libzstd.a + $(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT) + $(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) + $(RM) $(DESTDIR)$(LIBDIR)/$(LIBZSTD) + $(RM) $(DESTDIR)$(PKGCONFIGDIR)/libzstd.pc + $(RM) $(DESTDIR)$(INCLUDEDIR)/zstd.h + $(RM) $(DESTDIR)$(INCLUDEDIR)/zstd_errors.h + $(RM) $(DESTDIR)$(INCLUDEDIR)/zdict.h + @echo zstd libraries successfully uninstalled + +endif diff --git a/cpp/third_party/zstd-1.5.7/lib/README.md b/cpp/third_party/zstd-1.5.7/lib/README.md new file mode 100644 index 000000000..b37f5fc4f --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/README.md @@ -0,0 +1,248 @@ +Zstandard library files +================================ + +The __lib__ directory is split into several sub-directories, +in order to make it easier to select or exclude features. + + +#### Building + +`Makefile` script is provided, supporting [Makefile conventions](https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html#Makefile-Conventions), +including commands variables, staged install, directory variables and standard targets. +- `make` : generates both static and dynamic libraries +- `make install` : install libraries and headers in target system directories + +`libzstd` default scope is pretty large, including compression, decompression, dictionary builder, +and support for decoding legacy formats >= v0.5.0. +The scope can be reduced on demand (see paragraph _modular build_). + + +#### Multithreading support + +When building with `make`, by default the dynamic library is multithreaded and static library is single-threaded (for compatibility reasons). + +Enabling multithreading requires 2 conditions : +- set build macro `ZSTD_MULTITHREAD` (`-DZSTD_MULTITHREAD` for `gcc`) +- for POSIX systems : compile with pthread (`-pthread` compilation flag for `gcc`) + +For convenience, we provide a build target to generate multi and single threaded libraries: +- Force enable multithreading on both dynamic and static libraries by appending `-mt` to the target, e.g. `make lib-mt`. + Note that the `.pc` generated on calling `make lib-mt` will already include the require Libs and Cflags. +- Force disable multithreading on both dynamic and static libraries by appending `-nomt` to the target, e.g. `make lib-nomt`. +- By default, as mentioned before, dynamic library is multithreaded, and static library is single-threaded, e.g. `make lib`. + +When linking a POSIX program with a multithreaded version of `libzstd`, +note that it's necessary to invoke the `-pthread` flag during link stage. + +The `.pc` generated from `make install` or `make install-pc` always assume a single-threaded static library +is compiled. To correctly generate a `.pc` for the multi-threaded static library, set `MT=1` as ENV variable. + +Multithreading capabilities are exposed +via the [advanced API defined in `lib/zstd.h`](https://github.com/facebook/zstd/blob/v1.4.3/lib/zstd.h#L351). + + +#### API + +Zstandard's stable API is exposed within [lib/zstd.h](zstd.h). + + +#### Advanced API + +Optional advanced features are exposed via : + +- `lib/zstd_errors.h` : translates `size_t` function results + into a `ZSTD_ErrorCode`, for accurate error handling. + +- `ZSTD_STATIC_LINKING_ONLY` : if this macro is defined _before_ including `zstd.h`, + it unlocks access to the experimental API, + exposed in the second part of `zstd.h`. + All definitions in the experimental APIs are unstable, + they may still change in the future, or even be removed. + As a consequence, experimental definitions shall ___never be used with dynamic library___ ! + Only static linking is allowed. + + +#### Modular build + +It's possible to compile only a limited set of features within `libzstd`. +The file structure is designed to make this selection manually achievable for any build system : + +- Directory `lib/common` is always required, for all variants. + +- Compression source code lies in `lib/compress` + +- Decompression source code lies in `lib/decompress` + +- It's possible to include only `compress` or only `decompress`, they don't depend on each other. + +- `lib/dictBuilder` : makes it possible to generate dictionaries from a set of samples. + The API is exposed in `lib/dictBuilder/zdict.h`. + This module depends on both `lib/common` and `lib/compress` . + +- `lib/legacy` : makes it possible to decompress legacy zstd formats, starting from `v0.1.0`. + This module depends on `lib/common` and `lib/decompress`. + To enable this feature, define `ZSTD_LEGACY_SUPPORT` during compilation. + Specifying a number limits versions supported to that version onward. + For example, `ZSTD_LEGACY_SUPPORT=2` means : "support legacy formats >= v0.2.0". + Conversely, `ZSTD_LEGACY_SUPPORT=0` means "do __not__ support legacy formats". + By default, this build macro is set as `ZSTD_LEGACY_SUPPORT=5`. + Decoding supported legacy format is a transparent capability triggered within decompression functions. + It's also allowed to invoke legacy API directly, exposed in `lib/legacy/zstd_legacy.h`. + Each version does also provide its own set of advanced API. + For example, advanced API for version `v0.4` is exposed in `lib/legacy/zstd_v04.h` . + +- While invoking `make libzstd`, it's possible to define build macros + `ZSTD_LIB_COMPRESSION`, `ZSTD_LIB_DECOMPRESSION`, `ZSTD_LIB_DICTBUILDER`, + and `ZSTD_LIB_DEPRECATED` as `0` to forgo compilation of the + corresponding features. This will also disable compilation of all + dependencies (e.g. `ZSTD_LIB_COMPRESSION=0` will also disable + dictBuilder). + +- There are a number of options that can help minimize the binary size of + `libzstd`. + + The first step is to select the components needed (using the above-described + `ZSTD_LIB_COMPRESSION` etc.). + + The next step is to set `ZSTD_LIB_MINIFY` to `1` when invoking `make`. This + disables various optional components and changes the compilation flags to + prioritize space-saving. + + Detailed options: Zstandard's code and build environment is set up by default + to optimize above all else for performance. In pursuit of this goal, Zstandard + makes significant trade-offs in code size. For example, Zstandard often has + more than one implementation of a particular component, with each + implementation optimized for different scenarios. For example, the Huffman + decoder has complementary implementations that decode the stream one symbol at + a time or two symbols at a time. Zstd normally includes both (and dispatches + between them at runtime), but by defining `HUF_FORCE_DECOMPRESS_X1` or + `HUF_FORCE_DECOMPRESS_X2`, you can force the use of one or the other, avoiding + compilation of the other. Similarly, `ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT` + and `ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG` force the compilation and use of + only one or the other of two decompression implementations. The smallest + binary is achieved by using `HUF_FORCE_DECOMPRESS_X1` and + `ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT` (implied by `ZSTD_LIB_MINIFY`). + + On the compressor side, Zstd's compression levels map to several internal + strategies. In environments where the higher compression levels aren't used, + it is possible to exclude all but the fastest strategy with + `ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP=1`. (Note that this will change + the behavior of the default compression level.) Or if you want to retain the + default compressor as well, you can set + `ZSTD_LIB_EXCLUDE_COMPRESSORS_GREEDY_AND_UP=1`, at the cost of an additional + ~20KB or so. + + For squeezing the last ounce of size out, you can also define + `ZSTD_NO_INLINE`, which disables inlining, and `ZSTD_STRIP_ERROR_STRINGS`, + which removes the error messages that are otherwise returned by + `ZSTD_getErrorName` (implied by `ZSTD_LIB_MINIFY`). + + Finally, when integrating into your application, make sure you're doing link- + time optimization and unused symbol garbage collection (via some combination of, + e.g., `-flto`, `-ffat-lto-objects`, `-fuse-linker-plugin`, + `-ffunction-sections`, `-fdata-sections`, `-fmerge-all-constants`, + `-Wl,--gc-sections`, `-Wl,-z,norelro`, and an archiver that understands + the compiler's intermediate representation, e.g., `AR=gcc-ar`). Consult your + compiler's documentation. + +- While invoking `make libzstd`, the build macro `ZSTD_LEGACY_MULTITHREADED_API=1` + will expose the deprecated `ZSTDMT` API exposed by `zstdmt_compress.h` in + the shared library, which is now hidden by default. + +- The build macro `STATIC_BMI2` can be set to 1 to force usage of `bmi2` instructions. + It is generally not necessary to set this build macro, + because `STATIC_BMI2` will be automatically set to 1 + on detecting the presence of the corresponding instruction set in the compilation target. + It's nonetheless available as an optional manual toggle for better control, + and can also be used to forcefully disable `bmi2` instructions by setting it to 0. + +- The build macro `DYNAMIC_BMI2` can be set to 1 or 0 in order to generate binaries + which can detect at runtime the presence of BMI2 instructions, and use them only if present. + These instructions contribute to better performance, notably on the decoder side. + By default, this feature is automatically enabled on detecting + the right instruction set (x64) and compiler (clang or gcc >= 5). + It's obviously disabled for different cpus, + or when BMI2 instruction set is _required_ by the compiler command line + (in this case, only the BMI2 code path is generated). + Setting this macro will either force to generate the BMI2 dispatcher (1) + or prevent it (0). It overrides automatic detection. + +- The build macro `ZSTD_NO_UNUSED_FUNCTIONS` can be defined to hide the definitions of functions + that zstd does not use. Not all unused functions are hidden, but they can be if needed. + Currently, this macro will hide function definitions in FSE and HUF that use an excessive + amount of stack space. + +- The build macro `ZSTD_NO_INTRINSICS` can be defined to disable all explicit intrinsics. + Compiler builtins are still used. + +- The build macro `ZSTD_DECODER_INTERNAL_BUFFER` can be set to control + the amount of extra memory used during decompression to store literals. + This defaults to 64kB. Reducing this value reduces the memory footprint of + `ZSTD_DCtx` decompression contexts, + but might also result in a small decompression speed cost. + +- The C compiler macros `ZSTDLIB_VISIBLE`, `ZSTDERRORLIB_VISIBLE` and `ZDICTLIB_VISIBLE` + can be overridden to control the visibility of zstd's API. Additionally, + `ZSTDLIB_STATIC_API` and `ZDICTLIB_STATIC_API` can be overridden to control the visibility + of zstd's static API. Specifically, it can be set to `ZSTDLIB_HIDDEN` to hide the symbols + from the shared library. These macros default to `ZSTDLIB_VISIBILITY`, + `ZSTDERRORLIB_VSIBILITY`, and `ZDICTLIB_VISIBILITY` if unset, for backwards compatibility + with the old macro names. + +- The C compiler macro `HUF_DISABLE_FAST_DECODE` disables the newer Huffman fast C + and assembly decoding loops. You may want to use this macro if these loops are + slower on your platform. + +#### Windows : using MinGW+MSYS to create DLL + +DLL can be created using MinGW+MSYS with the `make libzstd` command. +This command creates `dll\libzstd.dll` and the import library `dll\libzstd.lib`. +The import library is only required with Visual C++. +The header file `zstd.h` and the dynamic library `dll\libzstd.dll` are required to +compile a project using gcc/MinGW. +The dynamic library has to be added to linking options. +It means that if a project that uses ZSTD consists of a single `test-dll.c` +file it should be linked with `dll\libzstd.dll`. For example: +``` + gcc $(CFLAGS) -Iinclude/ test-dll.c -o test-dll dll\libzstd.dll +``` +The compiled executable will require ZSTD DLL which is available at `dll\libzstd.dll`. + + +#### Advanced Build options + +The build system requires a hash function in order to +separate object files created with different compilation flags. +By default, it tries to use `md5sum` or equivalent. +The hash function can be manually switched by setting the `HASH` variable. +For example : `make HASH=xxhsum` +The hash function needs to generate at least 64-bit using hexadecimal format. +When no hash function is found, +the Makefile just generates all object files into the same default directory, +irrespective of compilation flags. +This functionality only matters if `libzstd` is compiled multiple times +with different build flags. + +The build directory, where object files are stored +can also be manually controlled using variable `BUILD_DIR`, +for example `make BUILD_DIR=objectDir/v1`. +In which case, the hash function doesn't matter. + + +#### Deprecated API + +Obsolete API on their way out are stored in directory `lib/deprecated`. +At this stage, it contains older streaming prototypes, in `lib/deprecated/zbuff.h`. +These prototypes will be removed in some future version. +Consider migrating code towards supported streaming API exposed in `zstd.h`. + + +#### Miscellaneous + +The other files are not source code. There are : + + - `BUCK` : support for `buck` build system (https://buckbuild.com/) + - `Makefile` : `make` script to build and install zstd library (static and dynamic) + - `README.md` : this file + - `dll/` : resources directory for Windows compilation + - `libzstd.pc.in` : script for `pkg-config` (used in `make install`) diff --git a/cpp/third_party/zstd-1.5.7/lib/common/allocations.h b/cpp/third_party/zstd-1.5.7/lib/common/allocations.h new file mode 100644 index 000000000..5e8995501 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/allocations.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This file provides custom allocation primitives + */ + +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */ + +#include "compiler.h" /* MEM_STATIC */ +#define ZSTD_STATIC_LINKING_ONLY +#include "../zstd.h" /* ZSTD_customMem */ + +#ifndef ZSTD_ALLOCATIONS_H +#define ZSTD_ALLOCATIONS_H + +/* custom memory allocation functions */ + +MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) + return customMem.customAlloc(customMem.opaque, size); + return ZSTD_malloc(size); +} + +MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) { + /* calloc implemented as malloc+memset; + * not as efficient as calloc, but next best guess for custom malloc */ + void* const ptr = customMem.customAlloc(customMem.opaque, size); + ZSTD_memset(ptr, 0, size); + return ptr; + } + return ZSTD_calloc(1, size); +} + +MEM_STATIC void ZSTD_customFree(void* ptr, ZSTD_customMem customMem) +{ + if (ptr!=NULL) { + if (customMem.customFree) + customMem.customFree(customMem.opaque, ptr); + else + ZSTD_free(ptr); + } +} + +#endif /* ZSTD_ALLOCATIONS_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/bits.h b/cpp/third_party/zstd-1.5.7/lib/common/bits.h new file mode 100644 index 000000000..f452f0889 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/bits.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_BITS_H +#define ZSTD_BITS_H + +#include "mem.h" + +MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val) +{ + assert(val != 0); + { + static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3, + 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, + 26, 12, 18, 6, 11, 5, 10, 9}; + return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27]; + } +} + +MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val) +{ + assert(val != 0); +#if defined(_MSC_VER) +# if STATIC_BMI2 + return (unsigned)_tzcnt_u32(val); +# else + if (val != 0) { + unsigned long r; + _BitScanForward(&r, val); + return (unsigned)r; + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)__builtin_ctz(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_ctz(val); +#else + return ZSTD_countTrailingZeros32_fallback(val); +#endif +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) +{ + assert(val != 0); + { + static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27]; + } +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val) +{ + assert(val != 0); +#if defined(_MSC_VER) +# if STATIC_BMI2 + return (unsigned)_lzcnt_u32(val); +# else + if (val != 0) { + unsigned long r; + _BitScanReverse(&r, val); + return (unsigned)(31 - r); + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)__builtin_clz(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_clz(val); +#else + return ZSTD_countLeadingZeros32_fallback(val); +#endif +} + +MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val) +{ + assert(val != 0); +#if defined(_MSC_VER) && defined(_WIN64) +# if STATIC_BMI2 + return (unsigned)_tzcnt_u64(val); +# else + if (val != 0) { + unsigned long r; + _BitScanForward64(&r, val); + return (unsigned)r; + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__) + return (unsigned)__builtin_ctzll(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_ctzll(val); +#else + { + U32 mostSignificantWord = (U32)(val >> 32); + U32 leastSignificantWord = (U32)val; + if (leastSignificantWord == 0) { + return 32 + ZSTD_countTrailingZeros32(mostSignificantWord); + } else { + return ZSTD_countTrailingZeros32(leastSignificantWord); + } + } +#endif +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val) +{ + assert(val != 0); +#if defined(_MSC_VER) && defined(_WIN64) +# if STATIC_BMI2 + return (unsigned)_lzcnt_u64(val); +# else + if (val != 0) { + unsigned long r; + _BitScanReverse64(&r, val); + return (unsigned)(63 - r); + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)(__builtin_clzll(val)); +#elif defined(__ICCARM__) + return (unsigned)(__builtin_clzll(val)); +#else + { + U32 mostSignificantWord = (U32)(val >> 32); + U32 leastSignificantWord = (U32)val; + if (mostSignificantWord == 0) { + return 32 + ZSTD_countLeadingZeros32(leastSignificantWord); + } else { + return ZSTD_countLeadingZeros32(mostSignificantWord); + } + } +#endif +} + +MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val) +{ + if (MEM_isLittleEndian()) { + if (MEM_64bits()) { + return ZSTD_countTrailingZeros64((U64)val) >> 3; + } else { + return ZSTD_countTrailingZeros32((U32)val) >> 3; + } + } else { /* Big Endian CPU */ + if (MEM_64bits()) { + return ZSTD_countLeadingZeros64((U64)val) >> 3; + } else { + return ZSTD_countLeadingZeros32((U32)val) >> 3; + } + } +} + +MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */ +{ + assert(val != 0); + return 31 - ZSTD_countLeadingZeros32(val); +} + +/* ZSTD_rotateRight_*(): + * Rotates a bitfield to the right by "count" bits. + * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts + */ +MEM_STATIC +U64 ZSTD_rotateRight_U64(U64 const value, U32 count) { + assert(count < 64); + count &= 0x3F; /* for fickle pattern recognition */ + return (value >> count) | (U64)(value << ((0U - count) & 0x3F)); +} + +MEM_STATIC +U32 ZSTD_rotateRight_U32(U32 const value, U32 count) { + assert(count < 32); + count &= 0x1F; /* for fickle pattern recognition */ + return (value >> count) | (U32)(value << ((0U - count) & 0x1F)); +} + +MEM_STATIC +U16 ZSTD_rotateRight_U16(U16 const value, U32 count) { + assert(count < 16); + count &= 0x0F; /* for fickle pattern recognition */ + return (value >> count) | (U16)(value << ((0U - count) & 0x0F)); +} + +#endif /* ZSTD_BITS_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/bitstream.h b/cpp/third_party/zstd-1.5.7/lib/common/bitstream.h new file mode 100644 index 000000000..3b7ad483d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/bitstream.h @@ -0,0 +1,454 @@ +/* ****************************************************************** + * bitstream + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ +#ifndef BITSTREAM_H_MODULE +#define BITSTREAM_H_MODULE + +/* +* This API consists of small unitary functions, which must be inlined for best performance. +* Since link-time-optimization is not available for all compilers, +* these functions are defined into a .h to be included. +*/ + +/*-**************************************** +* Dependencies +******************************************/ +#include "mem.h" /* unaligned access routines */ +#include "compiler.h" /* UNLIKELY() */ +#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */ +#include "error_private.h" /* error codes and messages */ +#include "bits.h" /* ZSTD_highbit32 */ + +/*========================================= +* Target specific +=========================================*/ +#ifndef ZSTD_NO_INTRINSICS +# if (defined(__BMI__) || defined(__BMI2__)) && defined(__GNUC__) +# include /* support for bextr (experimental)/bzhi */ +# elif defined(__ICCARM__) +# include +# endif +#endif + +#define STREAM_ACCUMULATOR_MIN_32 25 +#define STREAM_ACCUMULATOR_MIN_64 57 +#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) + + +/*-****************************************** +* bitStream encoding API (write forward) +********************************************/ +typedef size_t BitContainerType; +/* bitStream can mix input from multiple sources. + * A critical property of these streams is that they encode and decode in **reverse** direction. + * So the first bit sequence you add will be the last to be read, like a LIFO stack. + */ +typedef struct { + BitContainerType bitContainer; + unsigned bitPos; + char* startPtr; + char* ptr; + char* endPtr; +} BIT_CStream_t; + +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits); +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC); +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); + +/* Start with initCStream, providing the size of buffer to write into. +* bitStream will never write outside of this buffer. +* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. +* +* bits are first added to a local register. +* Local register is BitContainerType, 64-bits on 64-bits systems, or 32-bits on 32-bits systems. +* Writing data into memory is an explicit operation, performed by the flushBits function. +* Hence keep track how many bits are potentially stored into local register to avoid register overflow. +* After a flushBits, a maximum of 7 bits might still be stored into local register. +* +* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers. +* +* Last operation is to close the bitStream. +* The function returns the final size of CStream in bytes. +* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) +*/ + + +/*-******************************************** +* bitStream decoding API (read backward) +**********************************************/ +typedef struct { + BitContainerType bitContainer; + unsigned bitsConsumed; + const char* ptr; + const char* start; + const char* limitPtr; +} BIT_DStream_t; + +typedef enum { BIT_DStream_unfinished = 0, /* fully refilled */ + BIT_DStream_endOfBuffer = 1, /* still some bits left in bitstream */ + BIT_DStream_completed = 2, /* bitstream entirely consumed, bit-exact */ + BIT_DStream_overflow = 3 /* user requested more bits than present in bitstream */ + } BIT_DStream_status; /* result of BIT_reloadDStream() */ + +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); +MEM_STATIC BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); + + +/* Start by invoking BIT_initDStream(). +* A chunk of the bitStream is then stored into a local register. +* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (BitContainerType). +* You can then retrieve bitFields stored into the local register, **in reverse order**. +* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. +* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. +* Otherwise, it can be less than that, so proceed accordingly. +* Checking if DStream has reached its end can be performed with BIT_endOfDStream(). +*/ + + +/*-**************************************** +* unsafe API +******************************************/ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits); +/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ + +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); +/* unsafe version; does not check buffer overflow */ + +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); +/* faster, but works only if nbBits >= 1 */ + +/*===== Local Constants =====*/ +static const unsigned BIT_mask[] = { + 0, 1, 3, 7, 0xF, 0x1F, + 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, + 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, + 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, + 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */ +#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0])) + +/*-************************************************************** +* bitStream encoding +****************************************************************/ +/*! BIT_initCStream() : + * `dstCapacity` must be > sizeof(size_t) + * @return : 0 if success, + * otherwise an error code (can be tested using ERR_isError()) */ +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, + void* startPtr, size_t dstCapacity) +{ + bitC->bitContainer = 0; + bitC->bitPos = 0; + bitC->startPtr = (char*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer); + if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall); + return 0; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getLowerBits(BitContainerType bitContainer, U32 const nbBits) +{ +#if STATIC_BMI2 && !defined(ZSTD_NO_INTRINSICS) +# if (defined(__x86_64__) || defined(_M_X64)) && !defined(__ILP32__) + return _bzhi_u64(bitContainer, nbBits); +# else + DEBUG_STATIC_ASSERT(sizeof(bitContainer) == sizeof(U32)); + return _bzhi_u32(bitContainer, nbBits); +# endif +#else + assert(nbBits < BIT_MASK_SIZE); + return bitContainer & BIT_mask[nbBits]; +#endif +} + +/*! BIT_addBits() : + * can add up to 31 bits into `bitC`. + * Note : does not check for register overflow ! */ +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, + BitContainerType value, unsigned nbBits) +{ + DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32); + assert(nbBits < BIT_MASK_SIZE); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_addBitsFast() : + * works only if `value` is _clean_, + * meaning all high bits above nbBits are 0 */ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, + BitContainerType value, unsigned nbBits) +{ + assert((value>>nbBits) == 0); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= value << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_flushBitsFast() : + * assumption : bitContainer has not overflowed + * unsafe version; does not check buffer overflow */ +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_flushBits() : + * assumption : bitContainer has not overflowed + * safe version; check for buffer overflow, and prevents it. + * note : does not signal buffer overflow. + * overflow will be revealed later on using BIT_closeCStream() */ +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_closeCStream() : + * @return : size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) +{ + BIT_addBitsFast(bitC, 1, 1); /* endMark */ + BIT_flushBits(bitC); + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (size_t)(bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); +} + + +/*-******************************************************** +* bitStream decoding +**********************************************************/ +/*! BIT_initDStream() : + * Initialize a BIT_DStream_t. + * `bitD` : a pointer to an already allocated BIT_DStream_t structure. + * `srcSize` must be the *exact* size of the bitStream, in bytes. + * @return : size of stream (== srcSize), or an errorCode if a problem is detected + */ +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) +{ + if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } + + bitD->start = (const char*)srcBuffer; + bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer); + + if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ + bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); + bitD->bitContainer = MEM_readLEST(bitD->ptr); + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ + if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } + } else { + bitD->ptr = bitD->start; + bitD->bitContainer = *(const BYTE*)(bitD->start); + switch(srcSize) + { + case 7: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); + ZSTD_FALLTHROUGH; + + case 6: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); + ZSTD_FALLTHROUGH; + + case 5: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); + ZSTD_FALLTHROUGH; + + case 4: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[3]) << 24; + ZSTD_FALLTHROUGH; + + case 3: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[2]) << 16; + ZSTD_FALLTHROUGH; + + case 2: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[1]) << 8; + ZSTD_FALLTHROUGH; + + default: break; + } + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; + if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */ + } + bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; + } + + return srcSize; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getUpperBits(BitContainerType bitContainer, U32 const start) +{ + return bitContainer >> start; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits) +{ + U32 const regMask = sizeof(bitContainer)*8 - 1; + /* if start > regMask, bitstream is corrupted, and result is undefined */ + assert(nbBits < BIT_MASK_SIZE); + /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better + * than accessing memory. When bmi2 instruction is not present, we consider + * such cpus old (pre-Haswell, 2013) and their performance is not of that + * importance. + */ +#if defined(__x86_64__) || defined(_M_X64) + return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1); +#else + return (bitContainer >> (start & regMask)) & BIT_mask[nbBits]; +#endif +} + +/*! BIT_lookBits() : + * Provides next n bits from local register. + * local register is not modified. + * On 32-bits, maxNbBits==24. + * On 64-bits, maxNbBits==56. + * @return : value extracted */ +FORCE_INLINE_TEMPLATE BitContainerType BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) +{ + /* arbitrate between double-shift and shift+mask */ +#if 1 + /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8, + * bitstream is likely corrupted, and result is undefined */ + return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); +#else + /* this code path is slower on my os-x laptop */ + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask); +#endif +} + +/*! BIT_lookBitsFast() : + * unsafe version; only works if nbBits >= 1 */ +MEM_STATIC BitContainerType BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) +{ + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + assert(nbBits >= 1); + return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); +} + +FORCE_INLINE_TEMPLATE void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +{ + bitD->bitsConsumed += nbBits; +} + +/*! BIT_readBits() : + * Read (consume) next n bits from local register and update. + * Pay attention to not read more than nbBits contained into local register. + * @return : extracted value. */ +FORCE_INLINE_TEMPLATE BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) +{ + BitContainerType const value = BIT_lookBits(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_readBitsFast() : + * unsafe version; only works if nbBits >= 1 */ +MEM_STATIC BitContainerType BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits) +{ + BitContainerType const value = BIT_lookBitsFast(bitD, nbBits); + assert(nbBits >= 1); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_reloadDStream_internal() : + * Simple variant of BIT_reloadDStream(), with two conditions: + * 1. bitstream is valid : bitsConsumed <= sizeof(bitD->bitContainer)*8 + * 2. look window is valid after shifted down : bitD->ptr >= bitD->start + */ +MEM_STATIC BIT_DStream_status BIT_reloadDStream_internal(BIT_DStream_t* bitD) +{ + assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8); + bitD->ptr -= bitD->bitsConsumed >> 3; + assert(bitD->ptr >= bitD->start); + bitD->bitsConsumed &= 7; + bitD->bitContainer = MEM_readLEST(bitD->ptr); + return BIT_DStream_unfinished; +} + +/*! BIT_reloadDStreamFast() : + * Similar to BIT_reloadDStream(), but with two differences: + * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold! + * 2. Returns BIT_DStream_overflow when bitD->ptr < bitD->limitPtr, at this + * point you must use BIT_reloadDStream() to reload. + */ +MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD) +{ + if (UNLIKELY(bitD->ptr < bitD->limitPtr)) + return BIT_DStream_overflow; + return BIT_reloadDStream_internal(bitD); +} + +/*! BIT_reloadDStream() : + * Refill `bitD` from buffer previously set in BIT_initDStream() . + * This function is safe, it guarantees it will not never beyond src buffer. + * @return : status of `BIT_DStream_t` internal register. + * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ +FORCE_INLINE_TEMPLATE BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) +{ + /* note : once in overflow mode, a bitstream remains in this mode until it's reset */ + if (UNLIKELY(bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))) { + static const BitContainerType zeroFilled = 0; + bitD->ptr = (const char*)&zeroFilled; /* aliasing is allowed for char */ + /* overflow detected, erroneous scenario or end of stream: no update */ + return BIT_DStream_overflow; + } + + assert(bitD->ptr >= bitD->start); + + if (bitD->ptr >= bitD->limitPtr) { + return BIT_reloadDStream_internal(bitD); + } + if (bitD->ptr == bitD->start) { + /* reached end of bitStream => no update */ + if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; + return BIT_DStream_completed; + } + /* start < ptr < limitPtr => cautious update */ + { U32 nbBytes = bitD->bitsConsumed >> 3; + BIT_DStream_status result = BIT_DStream_unfinished; + if (bitD->ptr - nbBytes < bitD->start) { + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ + result = BIT_DStream_endOfBuffer; + } + bitD->ptr -= nbBytes; + bitD->bitsConsumed -= nbBytes*8; + bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */ + return result; + } +} + +/*! BIT_endOfDStream() : + * @return : 1 if DStream has _exactly_ reached its end (all bits consumed). + */ +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) +{ + return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); +} + +#endif /* BITSTREAM_H_MODULE */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/compiler.h b/cpp/third_party/zstd-1.5.7/lib/common/compiler.h new file mode 100644 index 000000000..1f7da50e6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/compiler.h @@ -0,0 +1,464 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPILER_H +#define ZSTD_COMPILER_H + +#include + +#include "portability_macros.h" + +/*-******************************************************* +* Compiler specifics +*********************************************************/ +/* force inlining */ + +#if !defined(ZSTD_NO_INLINE) +#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# define INLINE_KEYWORD inline +#else +# define INLINE_KEYWORD +#endif + +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define FORCE_INLINE_ATTR __attribute__((always_inline)) +#elif defined(_MSC_VER) +# define FORCE_INLINE_ATTR __forceinline +#else +# define FORCE_INLINE_ATTR +#endif + +#else + +#define INLINE_KEYWORD +#define FORCE_INLINE_ATTR + +#endif + +/** + On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC). + This explicitly marks such functions as __cdecl so that the code will still compile + if a CC other than __cdecl has been made the default. +*/ +#if defined(_MSC_VER) +# define WIN_CDECL __cdecl +#else +# define WIN_CDECL +#endif + +/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define UNUSED_ATTR __attribute__((unused)) +#else +# define UNUSED_ATTR +#endif + +/** + * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant + * parameters. They must be inlined for the compiler to eliminate the constant + * branches. + */ +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR +/** + * HINT_INLINE is used to help the compiler generate better code. It is *not* + * used for "templates", so it can be tweaked based on the compilers + * performance. + * + * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the + * always_inline attribute. + * + * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline + * attribute. + */ +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5 +# define HINT_INLINE static INLINE_KEYWORD +#else +# define HINT_INLINE FORCE_INLINE_TEMPLATE +#endif + +/* "soft" inline : + * The compiler is free to select if it's a good idea to inline or not. + * The main objective is to silence compiler warnings + * when a defined function in included but not used. + * + * Note : this macro is prefixed `MEM_` because it used to be provided by `mem.h` unit. + * Updating the prefix is probably preferable, but requires a fairly large codemod, + * since this name is used everywhere. + */ +#ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */ +#if defined(__GNUC__) +# define MEM_STATIC static __inline UNUSED_ATTR +#elif defined(__IAR_SYSTEMS_ICC__) +# define MEM_STATIC static inline UNUSED_ATTR +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define MEM_STATIC static inline +#elif defined(_MSC_VER) +# define MEM_STATIC static __inline +#else +# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif +#endif + +/* force no inlining */ +#ifdef _MSC_VER +# define FORCE_NOINLINE static __declspec(noinline) +#else +# if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define FORCE_NOINLINE static __attribute__((__noinline__)) +# else +# define FORCE_NOINLINE static +# endif +#endif + + +/* target attribute */ +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) +#else +# define TARGET_ATTRIBUTE(target) +#endif + +/* Target attribute for BMI2 dynamic dispatch. + * Enable lzcnt, bmi, and bmi2. + * We test for bmi1 & bmi2. lzcnt is included in bmi1. + */ +#define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2") + +/* prefetch + * can be disabled, by declaring NO_PREFETCH build macro */ +#if defined(NO_PREFETCH) +# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */ +# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */ +#else +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && !defined(_M_ARM64EC) /* _mm_prefetch() is not defined outside of x86/x64 */ +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) +# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) +# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) +# elif defined(__aarch64__) +# define PREFETCH_L1(ptr) do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0) +# define PREFETCH_L2(ptr) do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0) +# else +# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */ +# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */ +# endif +#endif /* NO_PREFETCH */ + +#define CACHELINE_SIZE 64 + +#define PREFETCH_AREA(p, s) \ + do { \ + const char* const _ptr = (const char*)(p); \ + size_t const _size = (size_t)(s); \ + size_t _pos; \ + for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \ + PREFETCH_L2(_ptr + _pos); \ + } \ + } while (0) + +/* vectorization + * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax, + * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */ +#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5) +# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) +# else +# define DONT_VECTORIZE _Pragma("GCC optimize(\"no-tree-vectorize\")") +# endif +#else +# define DONT_VECTORIZE +#endif + +/* Tell the compiler that a branch is likely or unlikely. + * Only use these macros if it causes the compiler to generate better code. + * If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc + * and clang, please do. + */ +#if defined(__GNUC__) +#define LIKELY(x) (__builtin_expect((x), 1)) +#define UNLIKELY(x) (__builtin_expect((x), 0)) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif + +#if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) +# define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0) +#else +# define ZSTD_UNREACHABLE do { assert(0); } while (0) +#endif + +/* disable warnings */ +#ifdef _MSC_VER /* Visual Studio */ +# include /* For Visual 2005 */ +# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ +# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ +# pragma warning(disable : 4324) /* disable: C4324: padded structure */ +#endif + +/* compile time determination of SIMD support */ +#if !defined(ZSTD_NO_INTRINSICS) +# if defined(__AVX2__) +# define ZSTD_ARCH_X86_AVX2 +# endif +# if defined(__SSE2__) || defined(_M_X64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) +# define ZSTD_ARCH_X86_SSE2 +# endif +# if defined(__ARM_NEON) || defined(_M_ARM64) +# define ZSTD_ARCH_ARM_NEON +# endif +# +# if defined(ZSTD_ARCH_X86_AVX2) +# include +# endif +# if defined(ZSTD_ARCH_X86_SSE2) +# include +# elif defined(ZSTD_ARCH_ARM_NEON) +# include +# endif +#endif + +/* C-language Attributes are added in C23. */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute) +# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) +#else +# define ZSTD_HAS_C_ATTRIBUTE(x) 0 +#endif + +/* Only use C++ attributes in C++. Some compilers report support for C++ + * attributes when compiling with C. + */ +#if defined(__cplusplus) && defined(__has_cpp_attribute) +# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute. + * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough + * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough + * - Else: __attribute__((__fallthrough__)) + */ +#ifndef ZSTD_FALLTHROUGH +# if ZSTD_HAS_C_ATTRIBUTE(fallthrough) +# define ZSTD_FALLTHROUGH [[fallthrough]] +# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough) +# define ZSTD_FALLTHROUGH [[fallthrough]] +# elif __has_attribute(__fallthrough__) +/* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon + * gcc complains about: a label can only be part of a statement and a declaration is not a statement. + */ +# define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__)) +# else +# define ZSTD_FALLTHROUGH +# endif +#endif + +/*-************************************************************** +* Alignment +*****************************************************************/ + +/* @return 1 if @u is a 2^n value, 0 otherwise + * useful to check a value is valid for alignment restrictions */ +MEM_STATIC int ZSTD_isPower2(size_t u) { + return (u & (u-1)) == 0; +} + +/* this test was initially positioned in mem.h, + * but this file is removed (or replaced) for linux kernel + * so it's now hosted in compiler.h, + * which remains valid for both user & kernel spaces. + */ + +#ifndef ZSTD_ALIGNOF +# if defined(__GNUC__) || defined(_MSC_VER) +/* covers gcc, clang & MSVC */ +/* note : this section must come first, before C11, + * due to a limitation in the kernel source generator */ +# define ZSTD_ALIGNOF(T) __alignof(T) + +# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +/* C11 support */ +# include +# define ZSTD_ALIGNOF(T) alignof(T) + +# else +/* No known support for alignof() - imperfect backup */ +# define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T)) + +# endif +#endif /* ZSTD_ALIGNOF */ + +#ifndef ZSTD_ALIGNED +/* C90-compatible alignment macro (GCC/Clang). Adjust for other compilers if needed. */ +# if defined(__GNUC__) || defined(__clang__) +# define ZSTD_ALIGNED(a) __attribute__((aligned(a))) +# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ +# define ZSTD_ALIGNED(a) _Alignas(a) +#elif defined(_MSC_VER) +# define ZSTD_ALIGNED(n) __declspec(align(n)) +# else + /* this compiler will require its own alignment instruction */ +# define ZSTD_ALIGNED(...) +# endif +#endif /* ZSTD_ALIGNED */ + + +/*-************************************************************** +* Sanitizer +*****************************************************************/ + +/** + * Zstd relies on pointer overflow in its decompressor. + * We add this attribute to functions that rely on pointer overflow. + */ +#ifndef ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +# if __has_attribute(no_sanitize) +# if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8 + /* gcc < 8 only has signed-integer-overlow which triggers on pointer overflow */ +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("signed-integer-overflow"))) +# else + /* older versions of clang [3.7, 5.0) will warn that pointer-overflow is ignored. */ +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("pointer-overflow"))) +# endif +# else +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +# endif +#endif + +/** + * Helper function to perform a wrapped pointer difference without triggering + * UBSAN. + * + * @returns lhs - rhs with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs) +{ + return lhs - rhs; +} + +/** + * Helper function to perform a wrapped pointer add without triggering UBSAN. + * + * @return ptr + add with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add) +{ + return ptr + add; +} + +/** + * Helper function to perform a wrapped pointer subtraction without triggering + * UBSAN. + * + * @return ptr - sub with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub) +{ + return ptr - sub; +} + +/** + * Helper function to add to a pointer that works around C's undefined behavior + * of adding 0 to NULL. + * + * @returns `ptr + add` except it defines `NULL + 0 == NULL`. + */ +MEM_STATIC +unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add) +{ + return add > 0 ? ptr + add : ptr; +} + +/* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an + * abundance of caution, disable our custom poisoning on mingw. */ +#ifdef __MINGW32__ +#ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE +#define ZSTD_ASAN_DONT_POISON_WORKSPACE 1 +#endif +#ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE +#define ZSTD_MSAN_DONT_POISON_WORKSPACE 1 +#endif +#endif + +#if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE) +/* Not all platforms that support msan provide sanitizers/msan_interface.h. + * We therefore declare the functions we need ourselves, rather than trying to + * include the header file... */ +#include /* size_t */ +#define ZSTD_DEPS_NEED_STDINT +#include "zstd_deps.h" /* intptr_t */ + +/* Make memory region fully initialized (without changing its contents). */ +void __msan_unpoison(const volatile void *a, size_t size); + +/* Make memory region fully uninitialized (without changing its contents). + This is a legacy interface that does not update origin information. Use + __msan_allocated_memory() instead. */ +void __msan_poison(const volatile void *a, size_t size); + +/* Returns the offset of the first (at least partially) poisoned byte in the + memory range, or -1 if the whole range is good. */ +intptr_t __msan_test_shadow(const volatile void *x, size_t size); + +/* Print shadow and origin for the memory range to stderr in a human-readable + format. */ +void __msan_print_shadow(const volatile void *x, size_t size); +#endif + +#if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE) +/* Not all platforms that support asan provide sanitizers/asan_interface.h. + * We therefore declare the functions we need ourselves, rather than trying to + * include the header file... */ +#include /* size_t */ + +/** + * Marks a memory region ([addr, addr+size)) as unaddressable. + * + * This memory must be previously allocated by your program. Instrumented + * code is forbidden from accessing addresses in this region until it is + * unpoisoned. This function is not guaranteed to poison the entire region - + * it could poison only a subregion of [addr, addr+size) due to ASan + * alignment restrictions. + * + * \note This function is not thread-safe because no two threads can poison or + * unpoison memory in the same memory region simultaneously. + * + * \param addr Start of memory region. + * \param size Size of memory region. */ +void __asan_poison_memory_region(void const volatile *addr, size_t size); + +/** + * Marks a memory region ([addr, addr+size)) as addressable. + * + * This memory must be previously allocated by your program. Accessing + * addresses in this region is allowed until this region is poisoned again. + * This function could unpoison a super-region of [addr, addr+size) due + * to ASan alignment restrictions. + * + * \note This function is not thread-safe because no two threads can + * poison or unpoison memory in the same memory region simultaneously. + * + * \param addr Start of memory region. + * \param size Size of memory region. */ +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#endif + +#endif /* ZSTD_COMPILER_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/cpu.h b/cpp/third_party/zstd-1.5.7/lib/common/cpu.h new file mode 100644 index 000000000..3f15d560f --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/cpu.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMMON_CPU_H +#define ZSTD_COMMON_CPU_H + +/** + * Implementation taken from folly/CpuId.h + * https://github.com/facebook/folly/blob/master/folly/CpuId.h + */ + +#include "mem.h" + +#ifdef _MSC_VER +#include +#endif + +typedef struct { + U32 f1c; + U32 f1d; + U32 f7b; + U32 f7c; +} ZSTD_cpuid_t; + +MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { + U32 f1c = 0; + U32 f1d = 0; + U32 f7b = 0; + U32 f7c = 0; +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) +#if !defined(_M_X64) || !defined(__clang__) || __clang_major__ >= 16 + int reg[4]; + __cpuid((int*)reg, 0); + { + int const n = reg[0]; + if (n >= 1) { + __cpuid((int*)reg, 1); + f1c = (U32)reg[2]; + f1d = (U32)reg[3]; + } + if (n >= 7) { + __cpuidex((int*)reg, 7, 0); + f7b = (U32)reg[1]; + f7c = (U32)reg[2]; + } + } +#else + /* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in + * which the `__cpuid` intrinsic does not save and restore `rbx` as it needs + * to due to being a reserved register. So in that case, do the `cpuid` + * ourselves. Clang supports inline assembly anyway. + */ + U32 n; + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "popq %%rbx\n\t" + : "=a"(n) + : "a"(0) + : "rcx", "rdx"); + if (n >= 1) { + U32 f1a; + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "popq %%rbx\n\t" + : "=a"(f1a), "=c"(f1c), "=d"(f1d) + : "a"(1) + :); + } + if (n >= 7) { + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "movq %%rbx, %%rax\n\t" + "popq %%rbx" + : "=a"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "rdx"); + } +#endif +#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__) + /* The following block like the normal cpuid branch below, but gcc + * reserves ebx for use of its pic register so we must specially + * handle the save and restore to avoid clobbering the register + */ + U32 n; + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(n) + : "a"(0) + : "ecx", "edx"); + if (n >= 1) { + U32 f1a; + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(f1a), "=c"(f1c), "=d"(f1d) + : "a"(1)); + } + if (n >= 7) { + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "movl %%ebx, %%eax\n\t" + "popl %%ebx" + : "=a"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "edx"); + } +#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__) + U32 n; + __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx"); + if (n >= 1) { + U32 f1a; + __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx"); + } + if (n >= 7) { + U32 f7a; + __asm__("cpuid" + : "=a"(f7a), "=b"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "edx"); + } +#endif + { + ZSTD_cpuid_t cpuid; + cpuid.f1c = f1c; + cpuid.f1d = f1d; + cpuid.f7b = f7b; + cpuid.f7c = f7c; + return cpuid; + } +} + +#define X(name, r, bit) \ + MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \ + return ((cpuid.r) & (1U << bit)) != 0; \ + } + +/* cpuid(1): Processor Info and Feature Bits. */ +#define C(name, bit) X(name, f1c, bit) + C(sse3, 0) + C(pclmuldq, 1) + C(dtes64, 2) + C(monitor, 3) + C(dscpl, 4) + C(vmx, 5) + C(smx, 6) + C(eist, 7) + C(tm2, 8) + C(ssse3, 9) + C(cnxtid, 10) + C(fma, 12) + C(cx16, 13) + C(xtpr, 14) + C(pdcm, 15) + C(pcid, 17) + C(dca, 18) + C(sse41, 19) + C(sse42, 20) + C(x2apic, 21) + C(movbe, 22) + C(popcnt, 23) + C(tscdeadline, 24) + C(aes, 25) + C(xsave, 26) + C(osxsave, 27) + C(avx, 28) + C(f16c, 29) + C(rdrand, 30) +#undef C +#define D(name, bit) X(name, f1d, bit) + D(fpu, 0) + D(vme, 1) + D(de, 2) + D(pse, 3) + D(tsc, 4) + D(msr, 5) + D(pae, 6) + D(mce, 7) + D(cx8, 8) + D(apic, 9) + D(sep, 11) + D(mtrr, 12) + D(pge, 13) + D(mca, 14) + D(cmov, 15) + D(pat, 16) + D(pse36, 17) + D(psn, 18) + D(clfsh, 19) + D(ds, 21) + D(acpi, 22) + D(mmx, 23) + D(fxsr, 24) + D(sse, 25) + D(sse2, 26) + D(ss, 27) + D(htt, 28) + D(tm, 29) + D(pbe, 31) +#undef D + +/* cpuid(7): Extended Features. */ +#define B(name, bit) X(name, f7b, bit) + B(bmi1, 3) + B(hle, 4) + B(avx2, 5) + B(smep, 7) + B(bmi2, 8) + B(erms, 9) + B(invpcid, 10) + B(rtm, 11) + B(mpx, 14) + B(avx512f, 16) + B(avx512dq, 17) + B(rdseed, 18) + B(adx, 19) + B(smap, 20) + B(avx512ifma, 21) + B(pcommit, 22) + B(clflushopt, 23) + B(clwb, 24) + B(avx512pf, 26) + B(avx512er, 27) + B(avx512cd, 28) + B(sha, 29) + B(avx512bw, 30) + B(avx512vl, 31) +#undef B +#define C(name, bit) X(name, f7c, bit) + C(prefetchwt1, 0) + C(avx512vbmi, 1) +#undef C + +#undef X + +#endif /* ZSTD_COMMON_CPU_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/debug.c b/cpp/third_party/zstd-1.5.7/lib/common/debug.c new file mode 100644 index 000000000..9d0b7d229 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/debug.c @@ -0,0 +1,30 @@ +/* ****************************************************************** + * debug + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* + * This module only hosts one global variable + * which can be used to dynamically influence the verbosity of traces, + * such as DEBUGLOG and RAWLOG + */ + +#include "debug.h" + +#if !defined(ZSTD_LINUX_KERNEL) || (DEBUGLEVEL>=2) +/* We only use this when DEBUGLEVEL>=2, but we get -Werror=pedantic errors if a + * translation unit is empty. So remove this from Linux kernel builds, but + * otherwise just leave it in. + */ +int g_debuglevel = DEBUGLEVEL; +#endif diff --git a/cpp/third_party/zstd-1.5.7/lib/common/debug.h b/cpp/third_party/zstd-1.5.7/lib/common/debug.h new file mode 100644 index 000000000..4b60ddf7f --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/debug.h @@ -0,0 +1,107 @@ +/* ****************************************************************** + * debug + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* + * The purpose of this header is to enable debug functions. + * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, + * and DEBUG_STATIC_ASSERT() for compile-time. + * + * By default, DEBUGLEVEL==0, which means run-time debug is disabled. + * + * Level 1 enables assert() only. + * Starting level 2, traces can be generated and pushed to stderr. + * The higher the level, the more verbose the traces. + * + * It's possible to dynamically adjust level using variable g_debug_level, + * which is only declared if DEBUGLEVEL>=2, + * and is a global variable, not multi-thread protected (use with care) + */ + +#ifndef DEBUG_H_12987983217 +#define DEBUG_H_12987983217 + + +/* static assert is triggered at compile time, leaving no runtime artefact. + * static assert only works with compile-time constants. + * Also, this variant can only be used inside a function. */ +#define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) + + +/* DEBUGLEVEL is expected to be defined externally, + * typically through compiler command line. + * Value must be a number. */ +#ifndef DEBUGLEVEL +# define DEBUGLEVEL 0 +#endif + + +/* recommended values for DEBUGLEVEL : + * 0 : release mode, no debug, all run-time checks disabled + * 1 : enables assert() only, no display + * 2 : reserved, for currently active debug path + * 3 : events once per object lifetime (CCtx, CDict, etc.) + * 4 : events once per frame + * 5 : events once per block + * 6 : events once per sequence (verbose) + * 7+: events at every position (*very* verbose) + * + * It's generally inconvenient to output traces > 5. + * In which case, it's possible to selectively trigger high verbosity levels + * by modifying g_debug_level. + */ + +#if (DEBUGLEVEL>=1) +# define ZSTD_DEPS_NEED_ASSERT +# include "zstd_deps.h" +#else +# ifndef assert /* assert may be already defined, due to prior #include */ +# define assert(condition) ((void)0) /* disable assert (default) */ +# endif +#endif + +#if (DEBUGLEVEL>=2) +# define ZSTD_DEPS_NEED_IO +# include "zstd_deps.h" +extern int g_debuglevel; /* the variable is only declared, + it actually lives in debug.c, + and is shared by the whole process. + It's not thread-safe. + It's useful when enabling very verbose levels + on selective conditions (such as position in src) */ + +# define RAWLOG(l, ...) \ + do { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__VA_ARGS__); \ + } \ + } while (0) + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define LINE_AS_STRING TOSTRING(__LINE__) + +# define DEBUGLOG(l, ...) \ + do { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__FILE__ ":" LINE_AS_STRING ": " __VA_ARGS__); \ + ZSTD_DEBUG_PRINT(" \n"); \ + } \ + } while (0) +#else +# define RAWLOG(l, ...) do { } while (0) /* disabled */ +# define DEBUGLOG(l, ...) do { } while (0) /* disabled */ +#endif + +#endif /* DEBUG_H_12987983217 */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/entropy_common.c b/cpp/third_party/zstd-1.5.7/lib/common/entropy_common.c new file mode 100644 index 000000000..e2173afb0 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/entropy_common.c @@ -0,0 +1,340 @@ +/* ****************************************************************** + * Common functions of New Generation Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************* +* Dependencies +***************************************/ +#include "mem.h" +#include "error_private.h" /* ERR_*, ERROR */ +#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ +#include "fse.h" +#include "huf.h" +#include "bits.h" /* ZSDT_highbit32, ZSTD_countTrailingZeros32 */ + + +/*=== Version ===*/ +unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } + + +/*=== Error Management ===*/ +unsigned FSE_isError(size_t code) { return ERR_isError(code); } +const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } + +unsigned HUF_isError(size_t code) { return ERR_isError(code); } +const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } + + +/*-************************************************************** +* FSE NCount encoding-decoding +****************************************************************/ +FORCE_INLINE_TEMPLATE +size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + const BYTE* const istart = (const BYTE*) headerBuffer; + const BYTE* const iend = istart + hbSize; + const BYTE* ip = istart; + int nbBits; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + unsigned const maxSV1 = *maxSVPtr + 1; + int previous0 = 0; + + if (hbSize < 8) { + /* This function only works when hbSize >= 8 */ + char buffer[8] = {0}; + ZSTD_memcpy(buffer, headerBuffer, hbSize); + { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, + buffer, sizeof(buffer)); + if (FSE_isError(countSize)) return countSize; + if (countSize > hbSize) return ERROR(corruption_detected); + return countSize; + } } + assert(hbSize >= 8); + + /* init */ + ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ + bitStream = MEM_readLE32(ip); + nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ + if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); + bitStream >>= 4; + bitCount = 4; + *tableLogPtr = nbBits; + remaining = (1<> 1; + while (repeats >= 12) { + charnum += 3 * 12; + if (LIKELY(ip <= iend-7)) { + ip += 3; + } else { + bitCount -= (int)(8 * (iend - 7 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1; + } + charnum += 3 * repeats; + bitStream >>= 2 * repeats; + bitCount += 2 * repeats; + + /* Add the final repeat which isn't 0b11. */ + assert((bitStream & 3) < 3); + charnum += bitStream & 3; + bitCount += 2; + + /* This is an error, but break and return an error + * at the end, because returning out of a loop makes + * it harder for the compiler to optimize. + */ + if (charnum >= maxSV1) break; + + /* We don't need to set the normalized count to 0 + * because we already memset the whole buffer to 0. + */ + + if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + assert((bitCount >> 3) <= 3); /* For first condition to work */ + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + } + { + int const max = (2*threshold-1) - remaining; + int count; + + if ((bitStream & (threshold-1)) < (U32)max) { + count = bitStream & (threshold-1); + bitCount += nbBits-1; + } else { + count = bitStream & (2*threshold-1); + if (count >= threshold) count -= max; + bitCount += nbBits; + } + + count--; /* extra accuracy */ + /* When it matters (small blocks), this is a + * predictable branch, because we don't use -1. + */ + if (count >= 0) { + remaining -= count; + } else { + assert(count == -1); + remaining += count; + } + normalizedCounter[charnum++] = (short)count; + previous0 = !count; + + assert(threshold > 1); + if (remaining < threshold) { + /* This branch can be folded into the + * threshold update condition because we + * know that threshold > 1. + */ + if (remaining <= 1) break; + nbBits = ZSTD_highbit32(remaining) + 1; + threshold = 1 << (nbBits - 1); + } + if (charnum >= maxSV1) break; + + if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + } } + if (remaining != 1) return ERROR(corruption_detected); + /* Only possible when there are too many zeros. */ + if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall); + if (bitCount > 32) return ERROR(corruption_detected); + *maxSVPtr = charnum-1; + + ip += (bitCount+7)>>3; + return ip-istart; +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t FSE_readNCount_body_default( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} + +#if DYNAMIC_BMI2 +BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} +#endif + +size_t FSE_readNCount_bmi2( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); + } +#endif + (void)bmi2; + return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} + +size_t FSE_readNCount( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0); +} + + +/*! HUF_readStats() : + Read compact Huffman tree, saved by HUF_writeCTable(). + `huffWeight` is destination buffer. + `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableX?() . +*/ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize) +{ + U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; + return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* flags */ 0); +} + +FORCE_INLINE_TEMPLATE size_t +HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, + int bmi2) +{ + U32 weightTotal; + const BYTE* ip = (const BYTE*) src; + size_t iSize; + size_t oSize; + + if (!srcSize) return ERROR(srcSize_wrong); + iSize = ip[0]; + /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ + + if (iSize >= 128) { /* special header */ + oSize = iSize - 127; + iSize = ((oSize+1)/2); + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + if (oSize >= hwSize) return ERROR(corruption_detected); + ip += 1; + { U32 n; + for (n=0; n> 4; + huffWeight[n+1] = ip[n/2] & 15; + } } } + else { /* header compressed with FSE (normal case) */ + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + /* max (hwSize-1) values decoded, as last one is implied */ + oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2); + if (FSE_isError(oSize)) return oSize; + } + + /* collect weight stats */ + ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); + weightTotal = 0; + { U32 n; for (n=0; n HUF_TABLELOG_MAX) return ERROR(corruption_detected); + rankStats[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } } + if (weightTotal == 0) return ERROR(corruption_detected); + + /* get last non-null symbol weight (implied, total must be 2^n) */ + { U32 const tableLog = ZSTD_highbit32(weightTotal) + 1; + if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); + *tableLogPtr = tableLog; + /* determine last weight */ + { U32 const total = 1 << tableLog; + U32 const rest = total - weightTotal; + U32 const verif = 1 << ZSTD_highbit32(rest); + U32 const lastWeight = ZSTD_highbit32(rest) + 1; + if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankStats[lastWeight]++; + } } + + /* check tree construction validity */ + if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ + + /* results */ + *nbSymbolsPtr = (U32)(oSize+1); + return iSize+1; +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0); +} + +#if DYNAMIC_BMI2 +static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1); +} +#endif + +size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, + int flags) +{ +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); + } +#endif + (void)flags; + return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); +} diff --git a/cpp/third_party/zstd-1.5.7/lib/common/error_private.c b/cpp/third_party/zstd-1.5.7/lib/common/error_private.c new file mode 100644 index 000000000..7e7f24f67 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/error_private.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* The purpose of this file is to have a single list of error strings embedded in binary */ + +#include "error_private.h" + +const char* ERR_getErrorString(ERR_enum code) +{ +#ifdef ZSTD_STRIP_ERROR_STRINGS + (void)code; + return "Error strings stripped"; +#else + static const char* const notErrorCode = "Unspecified error code"; + switch( code ) + { + case PREFIX(no_error): return "No error detected"; + case PREFIX(GENERIC): return "Error (generic)"; + case PREFIX(prefix_unknown): return "Unknown frame descriptor"; + case PREFIX(version_unsupported): return "Version not supported"; + case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter"; + case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; + case PREFIX(corruption_detected): return "Data corruption detected"; + case PREFIX(checksum_wrong): return "Restored data doesn't match checksum"; + case PREFIX(literals_headerWrong): return "Header of Literals' block doesn't respect format specification"; + case PREFIX(parameter_unsupported): return "Unsupported parameter"; + case PREFIX(parameter_combination_unsupported): return "Unsupported combination of parameters"; + case PREFIX(parameter_outOfBound): return "Parameter is out of bound"; + case PREFIX(init_missing): return "Context should be init first"; + case PREFIX(memory_allocation): return "Allocation error : not enough memory"; + case PREFIX(workSpace_tooSmall): return "workSpace buffer is not large enough"; + case PREFIX(stage_wrong): return "Operation not authorized at current processing stage"; + case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; + case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; + case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; + case PREFIX(cannotProduce_uncompressedBlock): return "This mode cannot generate an uncompressed block"; + case PREFIX(stabilityCondition_notRespected): return "pledged buffer stability condition is not respected"; + case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; + case PREFIX(dictionary_wrong): return "Dictionary mismatch"; + case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; + case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; + case PREFIX(srcSize_wrong): return "Src size is incorrect"; + case PREFIX(dstBuffer_null): return "Operation on NULL destination buffer"; + case PREFIX(noForwardProgress_destFull): return "Operation made no progress over multiple calls, due to output buffer being full"; + case PREFIX(noForwardProgress_inputEmpty): return "Operation made no progress over multiple calls, due to input being empty"; + /* following error codes are not stable and may be removed or changed in a future version */ + case PREFIX(frameIndex_tooLarge): return "Frame index is too large"; + case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking"; + case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong"; + case PREFIX(srcBuffer_wrong): return "Source buffer is wrong"; + case PREFIX(sequenceProducer_failed): return "Block-level external sequence producer returned an error code"; + case PREFIX(externalSequences_invalid): return "External sequences are not valid"; + case PREFIX(maxCode): + default: return notErrorCode; + } +#endif +} diff --git a/cpp/third_party/zstd-1.5.7/lib/common/error_private.h b/cpp/third_party/zstd-1.5.7/lib/common/error_private.h new file mode 100644 index 000000000..9dcc85951 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/error_private.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* Note : this module is expected to remain private, do not expose it */ + +#ifndef ERROR_H_MODULE +#define ERROR_H_MODULE + +/* **************************************** +* Dependencies +******************************************/ +#include "../zstd_errors.h" /* enum list */ +#include "compiler.h" +#include "debug.h" +#include "zstd_deps.h" /* size_t */ + +/* **************************************** +* Compiler-specific +******************************************/ +#if defined(__GNUC__) +# define ERR_STATIC static __attribute__((unused)) +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define ERR_STATIC static inline +#elif defined(_MSC_VER) +# define ERR_STATIC static __inline +#else +# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif + + +/*-**************************************** +* Customization (error_public.h) +******************************************/ +typedef ZSTD_ErrorCode ERR_enum; +#define PREFIX(name) ZSTD_error_##name + + +/*-**************************************** +* Error codes handling +******************************************/ +#undef ERROR /* already defined on Visual Studio */ +#define ERROR(name) ZSTD_ERROR(name) +#define ZSTD_ERROR(name) ((size_t)-PREFIX(name)) + +ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } + +ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); } + +/* check and forward error code */ +#define CHECK_V_F(e, f) \ + size_t const e = f; \ + do { \ + if (ERR_isError(e)) \ + return e; \ + } while (0) +#define CHECK_F(f) do { CHECK_V_F(_var_err__, f); } while (0) + + +/*-**************************************** +* Error Strings +******************************************/ + +const char* ERR_getErrorString(ERR_enum code); /* error_private.c */ + +ERR_STATIC const char* ERR_getErrorName(size_t code) +{ + return ERR_getErrorString(ERR_getErrorCode(code)); +} + +/** + * Ignore: this is an internal helper. + * + * This is a helper function to help force C99-correctness during compilation. + * Under strict compilation modes, variadic macro arguments can't be empty. + * However, variadic function arguments can be. Using a function therefore lets + * us statically check that at least one (string) argument was passed, + * independent of the compilation flags. + */ +static INLINE_KEYWORD UNUSED_ATTR +void _force_has_format_string(const char *format, ...) { + (void)format; +} + +/** + * Ignore: this is an internal helper. + * + * We want to force this function invocation to be syntactically correct, but + * we don't want to force runtime evaluation of its arguments. + */ +#define _FORCE_HAS_FORMAT_STRING(...) \ + do { \ + if (0) { \ + _force_has_format_string(__VA_ARGS__); \ + } \ + } while (0) + +#define ERR_QUOTE(str) #str + +/** + * Return the specified error if the condition evaluates to true. + * + * In debug modes, prints additional information. + * In order to do that (particularly, printing the conditional that failed), + * this can't just wrap RETURN_ERROR(). + */ +#define RETURN_ERROR_IF(cond, err, ...) \ + do { \ + if (cond) { \ + RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } \ + } while (0) + +/** + * Unconditionally return the specified error. + * + * In debug modes, prints additional information. + */ +#define RETURN_ERROR(err, ...) \ + do { \ + RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } while(0) + +/** + * If the provided expression evaluates to an error code, returns that error code. + * + * In debug modes, prints additional information. + */ +#define FORWARD_IF_ERROR(err, ...) \ + do { \ + size_t const err_code = (err); \ + if (ERR_isError(err_code)) { \ + RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \ + __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return err_code; \ + } \ + } while(0) + +#endif /* ERROR_H_MODULE */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/fse.h b/cpp/third_party/zstd-1.5.7/lib/common/fse.h new file mode 100644 index 000000000..b6c2a3e9c --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/fse.h @@ -0,0 +1,625 @@ +/* ****************************************************************** + * FSE : Finite State Entropy codec + * Public Prototypes declaration + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ +#ifndef FSE_H +#define FSE_H + + +/*-***************************************** +* Dependencies +******************************************/ +#include "zstd_deps.h" /* size_t, ptrdiff_t */ + +/*-***************************************** +* FSE_PUBLIC_API : control library symbols visibility +******************************************/ +#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) +# define FSE_PUBLIC_API __attribute__ ((visibility ("default"))) +#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ +# define FSE_PUBLIC_API __declspec(dllexport) +#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) +# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define FSE_PUBLIC_API +#endif + +/*------ Version ------*/ +#define FSE_VERSION_MAJOR 0 +#define FSE_VERSION_MINOR 9 +#define FSE_VERSION_RELEASE 0 + +#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE +#define FSE_QUOTE(str) #str +#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) +#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) + +#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) +FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ + + +/*-***************************************** +* Tool functions +******************************************/ +FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ + +/* Error Management */ +FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ +FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ + + +/*-***************************************** +* FSE detailed API +******************************************/ +/*! +FSE_compress() does the following: +1. count symbol occurrence from source[] into table count[] (see hist.h) +2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog) +3. save normalized counters to memory buffer using writeNCount() +4. build encoding table 'CTable' from normalized counters +5. encode the data stream using encoding table 'CTable' + +FSE_decompress() does the following: +1. read normalized counters with readNCount() +2. build decoding table 'DTable' from normalized counters +3. decode the data stream using decoding table 'DTable' + +The following API allows targeting specific sub-functions for advanced tasks. +For example, it's possible to compress several blocks using the same 'CTable', +or to save and provide normalized distribution using external method. +*/ + +/* *** COMPRESSION *** */ + +/*! FSE_optimalTableLog(): + dynamically downsize 'tableLog' when conditions are met. + It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. + @return : recommended tableLog (necessarily <= 'maxTableLog') */ +FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_normalizeCount(): + normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) + 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). + useLowProbCount is a boolean parameter which trades off compressed size for + faster header decoding. When it is set to 1, the compressed data will be slightly + smaller. And when it is set to 0, FSE_readNCount() and FSE_buildDTable() will be + faster. If you are compressing a small amount of data (< 2 KB) then useLowProbCount=0 + is a good default, since header deserialization makes a big speed difference. + Otherwise, useLowProbCount=1 is a good default, since the speed difference is small. + @return : tableLog, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount); + +/*! FSE_NCountWriteBound(): + Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. + Typically useful for allocation purpose. */ +FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_writeNCount(): + Compactly save 'normalizedCounter' into 'buffer'. + @return : size of the compressed table, + or an errorCode, which can be tested using FSE_isError(). */ +FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, + const short* normalizedCounter, + unsigned maxSymbolValue, unsigned tableLog); + +/*! Constructor and Destructor of FSE_CTable. + Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ +typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ + +/*! FSE_buildCTable(): + Builds `ct`, which must be already allocated, using FSE_createCTable(). + @return : 0, or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_compress_usingCTable(): + Compress `src` using `ct` into `dst` which must be already allocated. + @return : size of compressed data (<= `dstCapacity`), + or 0 if compressed data could not fit into `dst`, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); + +/*! +Tutorial : +---------- +The first step is to count all symbols. FSE_count() does this job very fast. +Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells. +'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0] +maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value) +FSE_count() will return the number of occurrence of the most frequent symbol. +This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). + +The next step is to normalize the frequencies. +FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'. +It also guarantees a minimum of 1 to any Symbol with frequency >= 1. +You can use 'tableLog'==0 to mean "use default tableLog value". +If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(), +which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default"). + +The result of FSE_normalizeCount() will be saved into a table, +called 'normalizedCounter', which is a table of signed short. +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells. +The return value is tableLog if everything proceeded as expected. +It is 0 if there is a single symbol within distribution. +If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()). + +'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount(). +'buffer' must be already allocated. +For guaranteed success, buffer size must be at least FSE_headerBound(). +The result of the function is the number of bytes written into 'buffer'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small). + +'normalizedCounter' can then be used to create the compression table 'CTable'. +The space required by 'CTable' must be already allocated, using FSE_createCTable(). +You can then use FSE_buildCTable() to fill 'CTable'. +If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()). + +'CTable' can then be used to compress 'src', with FSE_compress_usingCTable(). +Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize' +The function returns the size of compressed data (without header), necessarily <= `dstCapacity`. +If it returns '0', compressed data could not fit into 'dst'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). +*/ + + +/* *** DECOMPRESSION *** */ + +/*! FSE_readNCount(): + Read compactly saved 'normalizedCounter' from 'rBuffer'. + @return : size read from 'rBuffer', + or an errorCode, which can be tested using FSE_isError(). + maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ +FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize); + +/*! FSE_readNCount_bmi2(): + * Same as FSE_readNCount() but pass bmi2=1 when your CPU supports BMI2 and 0 otherwise. + */ +FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize, int bmi2); + +typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ + +/*! +Tutorial : +---------- +(Note : these functions only decompress FSE-compressed blocks. + If block is uncompressed, use memcpy() instead + If block is a single repeated byte, use memset() instead ) + +The first step is to obtain the normalized frequencies of symbols. +This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount(). +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short. +In practice, that means it's necessary to know 'maxSymbolValue' beforehand, +or size the table to handle worst case situations (typically 256). +FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'. +The result of FSE_readNCount() is the number of bytes read from 'rBuffer'. +Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that. +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'. +This is performed by the function FSE_buildDTable(). +The space required by 'FSE_DTable' must be already allocated using FSE_createDTable(). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable(). +`cSrcSize` must be strictly correct, otherwise decompression will fail. +FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) +*/ + +#endif /* FSE_H */ + + +#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) +#define FSE_H_FSE_STATIC_LINKING_ONLY +#include "bitstream.h" + +/* ***************************************** +* Static allocation +*******************************************/ +/* FSE buffer bounds */ +#define FSE_NCOUNTBOUND 512 +#define FSE_BLOCKBOUND(size) ((size) + ((size)>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */) +#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ +#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<((maxTableLog)-1)) + (((maxSymbolValue)+1)*2)) +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<(maxTableLog))) + +/* or use the size to malloc() space directly. Pay attention to alignment restrictions though */ +#define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable)) +#define FSE_DTABLE_SIZE(maxTableLog) (FSE_DTABLE_SIZE_U32(maxTableLog) * sizeof(FSE_DTable)) + + +/* ***************************************** + * FSE advanced API + ***************************************** */ + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus); +/**< same as FSE_optimalTableLog(), which used `minus==2` */ + +size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); +/**< build a fake FSE_CTable, designed to compress always the same symbolValue */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`. + * See FSE_buildCTable_wksp() for breakdown of workspace usage. + */ +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2 + sizeof(U64)/sizeof(U32) /* additional 8 bytes for potential table overwrite */) +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)) +size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); + +#define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) (sizeof(short) * (maxSymbolValue + 1) + (1ULL << maxTableLog) + 8) +#define FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ((FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) + sizeof(unsigned) - 1) / sizeof(unsigned)) +FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); +/**< Same as FSE_buildDTable(), using an externally allocated `workspace` produced with `FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxSymbolValue)` */ + +#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + 1 + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) + (FSE_MAX_SYMBOL_VALUE + 1) / 2 + 1) +#define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned)) +size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2); +/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)`. + * Set bmi2 to 1 if your CPU supports BMI2 or 0 if it doesn't */ + +typedef enum { + FSE_repeat_none, /**< Cannot use the previous table */ + FSE_repeat_check, /**< Can use the previous table but it must be checked */ + FSE_repeat_valid /**< Can use the previous table and it is assumed to be valid */ + } FSE_repeat; + +/* ***************************************** +* FSE symbol compression API +*******************************************/ +/*! + This API consists of small unitary functions, which highly benefit from being inlined. + Hence their body are included in next section. +*/ +typedef struct { + ptrdiff_t value; + const void* stateTable; + const void* symbolTT; + unsigned stateLog; +} FSE_CState_t; + +static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct); + +static void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol); + +static void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr); + +/**< +These functions are inner components of FSE_compress_usingCTable(). +They allow the creation of custom streams, mixing multiple tables and bit sources. + +A key property to keep in mind is that encoding and decoding are done **in reverse direction**. +So the first symbol you will encode is the last you will decode, like a LIFO stack. + +You will need a few variables to track your CStream. They are : + +FSE_CTable ct; // Provided by FSE_buildCTable() +BIT_CStream_t bitStream; // bitStream tracking structure +FSE_CState_t state; // State tracking structure (can have several) + + +The first thing to do is to init bitStream and state. + size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize); + FSE_initCState(&state, ct); + +Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError(); +You can then encode your input data, byte after byte. +FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time. +Remember decoding will be done in reverse direction. + FSE_encodeByte(&bitStream, &state, symbol); + +At any time, you can also add any bit sequence. +Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders + BIT_addBits(&bitStream, bitField, nbBits); + +The above methods don't commit data to memory, they just store it into local register, for speed. +Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). +Writing data to memory is a manual operation, performed by the flushBits function. + BIT_flushBits(&bitStream); + +Your last FSE encoding operation shall be to flush your last state value(s). + FSE_flushState(&bitStream, &state); + +Finally, you must close the bitStream. +The function returns the size of CStream in bytes. +If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible) +If there is an error, it returns an errorCode (which can be tested using FSE_isError()). + size_t size = BIT_closeCStream(&bitStream); +*/ + + +/* ***************************************** +* FSE symbol decompression API +*******************************************/ +typedef struct { + size_t state; + const void* table; /* precise table may vary, depending on U16 */ +} FSE_DState_t; + + +static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt); + +static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); + +static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr); + +/**< +Let's now decompose FSE_decompress_usingDTable() into its unitary components. +You will decode FSE-encoded symbols from the bitStream, +and also any other bitFields you put in, **in reverse order**. + +You will need a few variables to track your bitStream. They are : + +BIT_DStream_t DStream; // Stream context +FSE_DState_t DState; // State context. Multiple ones are possible +FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable() + +The first thing to do is to init the bitStream. + errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize); + +You should then retrieve your initial state(s) +(in reverse flushing order if you have several ones) : + errorCode = FSE_initDState(&DState, &DStream, DTablePtr); + +You can then decode your data, symbol after symbol. +For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'. +Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out). + unsigned char symbol = FSE_decodeSymbol(&DState, &DStream); + +You can retrieve any bitfield you eventually stored into the bitStream (in reverse order) +Note : maximum allowed nbBits is 25, for 32-bits compatibility + size_t bitField = BIT_readBits(&DStream, nbBits); + +All above operations only read from local register (which size depends on size_t). +Refueling the register from memory is manually performed by the reload method. + endSignal = FSE_reloadDStream(&DStream); + +BIT_reloadDStream() result tells if there is still some more data to read from DStream. +BIT_DStream_unfinished : there is still some data left into the DStream. +BIT_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled. +BIT_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed. +BIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted. + +When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop, +to properly detect the exact end of stream. +After each decoded symbol, check if DStream is fully consumed using this simple test : + BIT_reloadDStream(&DStream) >= BIT_DStream_completed + +When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. +Checking if DStream has reached its end is performed by : + BIT_endOfDStream(&DStream); +Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. + FSE_endOfDState(&DState); +*/ + + +/* ***************************************** +* FSE unsafe API +*******************************************/ +static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); +/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ + + +/* ***************************************** +* Implementation of inlined functions +*******************************************/ +typedef struct { + int deltaFindState; + U32 deltaNbBits; +} FSE_symbolCompressionTransform; /* total 8 bytes */ + +MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) +{ + const void* ptr = ct; + const U16* u16ptr = (const U16*) ptr; + const U32 tableLog = MEM_read16(ptr); + statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2; + statePtr->symbolTT = ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1); + statePtr->stateLog = tableLog; +} + + +/*! FSE_initCState2() : +* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) +* uses the smallest state value possible, saving the cost of this symbol */ +MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol) +{ + FSE_initCState(statePtr, ct); + { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* stateTable = (const U16*)(statePtr->stateTable); + U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16); + statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; + statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; + } +} + +MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, unsigned symbol) +{ + FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* const stateTable = (const U16*)(statePtr->stateTable); + U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); + BIT_addBits(bitC, (BitContainerType)statePtr->value, nbBitsOut); + statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; +} + +MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) +{ + BIT_addBits(bitC, (BitContainerType)statePtr->value, statePtr->stateLog); + BIT_flushBits(bitC); +} + + +/* FSE_getMaxNbBits() : + * Approximate maximum cost of a symbol, in bits. + * Fractional get rounded up (i.e. a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16; +} + +/* FSE_bitCost() : + * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16; + U32 const threshold = (minNbBits+1) << 16; + assert(tableLog < 16); + assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */ + { U32 const tableSize = 1 << tableLog; + U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize); + U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */ + U32 const bitMultiplier = 1 << accuracyLog; + assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold); + assert(normalizedDeltaFromThreshold <= bitMultiplier); + return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold; + } +} + + +/* ====== Decompression ====== */ + +typedef struct { + U16 tableLog; + U16 fastMode; +} FSE_DTableHeader; /* sizeof U32 */ + +typedef struct +{ + unsigned short newState; + unsigned char symbol; + unsigned char nbBits; +} FSE_decode_t; /* size == U32 */ + +MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) +{ + const void* ptr = dt; + const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + return DInfo.symbol; +} + +MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = DInfo.newState + lowBits; +} + +MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBits(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +/*! FSE_decodeSymbolFast() : + unsafe, only works if no symbol has a probability > 50% */ +MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBitsFast(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) +{ + return DStatePtr->state == 0; +} + + + +#ifndef FSE_COMMONDEFS_ONLY + +/* ************************************************************** +* Tuning parameters +****************************************************************/ +/*!MEMORY_USAGE : +* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect +* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ +#ifndef FSE_MAX_MEMORY_USAGE +# define FSE_MAX_MEMORY_USAGE 14 +#endif +#ifndef FSE_DEFAULT_MEMORY_USAGE +# define FSE_DEFAULT_MEMORY_USAGE 13 +#endif +#if (FSE_DEFAULT_MEMORY_USAGE > FSE_MAX_MEMORY_USAGE) +# error "FSE_DEFAULT_MEMORY_USAGE must be <= FSE_MAX_MEMORY_USAGE" +#endif + +/*!FSE_MAX_SYMBOL_VALUE : +* Maximum symbol value authorized. +* Required for proper stack allocation */ +#ifndef FSE_MAX_SYMBOL_VALUE +# define FSE_MAX_SYMBOL_VALUE 255 +#endif + +/* ************************************************************** +* template functions type & suffix +****************************************************************/ +#define FSE_FUNCTION_TYPE BYTE +#define FSE_FUNCTION_EXTENSION +#define FSE_DECODE_TYPE FSE_decode_t + + +#endif /* !FSE_COMMONDEFS_ONLY */ + + +/* *************************************************************** +* Constants +*****************************************************************/ +#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) +#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX +# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" +#endif + +#define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3) + +#endif /* FSE_STATIC_LINKING_ONLY */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/fse_decompress.c b/cpp/third_party/zstd-1.5.7/lib/common/fse_decompress.c new file mode 100644 index 000000000..c8f1bb0cf --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/fse_decompress.c @@ -0,0 +1,315 @@ +/* ****************************************************************** + * FSE : Finite State Entropy decoder + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* ************************************************************** +* Includes +****************************************************************/ +#include "debug.h" /* assert */ +#include "bitstream.h" +#include "compiler.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "error_private.h" +#include "zstd_deps.h" /* ZSTD_memcpy */ +#include "bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError +#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + +static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) +{ + void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ + FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); + U16* symbolNext = (U16*)workSpace; + BYTE* spread = (BYTE*)(symbolNext + maxSymbolValue + 1); + + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + U32 highThreshold = tableSize-1; + + /* Sanity Checks */ + if (FSE_BUILD_DTABLE_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(maxSymbolValue_tooLarge); + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + + /* Init, lay down lowprob symbols */ + { FSE_DTableHeader DTableH; + DTableH.tableLog = (U16)tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + symbolNext[s] = (U16)normalizedCounter[s]; + } } } + ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + if (highThreshold == tableSize - 1) { + size_t const tableMask = tableSize-1; + size_t const step = FSE_TABLESTEP(tableSize); + /* First lay down the symbols in order. + * We use a uint64_t to lay down 8 bytes at a time. This reduces branch + * misses since small blocks generally have small table logs, so nearly + * all symbols have counts <= 8. We ensure we have 8 bytes at the end of + * our buffer to handle the over-write. + */ + { U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ + } } + if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { U32 u; + for (u=0; u sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[1] = FSE_GETSYMBOL(&state2); + + if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } + + op[2] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[3] = FSE_GETSYMBOL(&state2); + } + + /* tail */ + /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ + while (1) { + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state1); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state2); + break; + } + + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state2); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state1); + break; + } } + + assert(op >= ostart); + return (size_t)(op-ostart); +} + +typedef struct { + short ncount[FSE_MAX_SYMBOL_VALUE + 1]; +} FSE_DecompressWksp; + + +FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body( + void* dst, size_t dstCapacity, + const void* cSrc, size_t cSrcSize, + unsigned maxLog, void* workSpace, size_t wkspSize, + int bmi2) +{ + const BYTE* const istart = (const BYTE*)cSrc; + const BYTE* ip = istart; + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace; + size_t const dtablePos = sizeof(FSE_DecompressWksp) / sizeof(FSE_DTable); + FSE_DTable* const dtable = (FSE_DTable*)workSpace + dtablePos; + + FSE_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0); + if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC); + + /* correct offset to dtable depends on this property */ + FSE_STATIC_ASSERT(sizeof(FSE_DecompressWksp) % sizeof(FSE_DTable) == 0); + + /* normal FSE decoding mode */ + { size_t const NCountLength = + FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2); + if (FSE_isError(NCountLength)) return NCountLength; + if (tableLog > maxLog) return ERROR(tableLog_tooLarge); + assert(NCountLength <= cSrcSize); + ip += NCountLength; + cSrcSize -= NCountLength; + } + + if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge); + assert(sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog) <= wkspSize); + workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); + wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); + + CHECK_F( FSE_buildDTable_internal(dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) ); + + { + const void* ptr = dtable; + const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; + const U32 fastMode = DTableH->fastMode; + + /* select fast mode (static) */ + if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1); + return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0); + } +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 0); +} + +#if DYNAMIC_BMI2 +BMI2_TARGET_ATTRIBUTE static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1); +} +#endif + +size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return FSE_decompress_wksp_body_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); + } +#endif + (void)bmi2; + return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); +} + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/huf.h b/cpp/third_party/zstd-1.5.7/lib/common/huf.h new file mode 100644 index 000000000..4b142c4f9 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/huf.h @@ -0,0 +1,277 @@ +/* ****************************************************************** + * huff0 huffman codec, + * part of Finite State Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +#ifndef HUF_H_298734234 +#define HUF_H_298734234 + +/* *** Dependencies *** */ +#include "zstd_deps.h" /* size_t */ +#include "mem.h" /* U32 */ +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" + +/* *** Tool functions *** */ +#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ +size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ + +/* Error Management */ +unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */ +const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */ + + +#define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */) +#define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64)) + +/* *** Constants *** */ +#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */ +#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ +#define HUF_SYMBOLVALUE_MAX 255 + +#define HUF_TABLELOG_ABSOLUTEMAX 12 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) +# error "HUF_TABLELOG_MAX is too large !" +#endif + + +/* **************************************** +* Static allocation +******************************************/ +/* HUF buffer bounds */ +#define HUF_CTABLEBOUND 129 +#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */ +#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* static allocation of HUF's Compression Table */ +/* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */ +typedef size_t HUF_CElt; /* consider it an incomplete type */ +#define HUF_CTABLE_SIZE_ST(maxSymbolValue) ((maxSymbolValue)+2) /* Use tables of size_t, for proper alignment */ +#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_ST(maxSymbolValue) * sizeof(size_t)) +#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ + HUF_CElt name[HUF_CTABLE_SIZE_ST(maxSymbolValue)] /* no final ; */ + +/* static allocation of HUF's DTable */ +typedef U32 HUF_DTable; +#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) +#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } +#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } + + +/* **************************************** +* Advanced decompression functions +******************************************/ + +/** + * Huffman flags bitset. + * For all flags, 0 is the default value. + */ +typedef enum { + /** + * If compiled with DYNAMIC_BMI2: Set flag only if the CPU supports BMI2 at runtime. + * Otherwise: Ignored. + */ + HUF_flags_bmi2 = (1 << 0), + /** + * If set: Test possible table depths to find the one that produces the smallest header + encoded size. + * If unset: Use heuristic to find the table depth. + */ + HUF_flags_optimalDepth = (1 << 1), + /** + * If set: If the previous table can encode the input, always reuse the previous table. + * If unset: If the previous table can encode the input, reuse the previous table if it results in a smaller output. + */ + HUF_flags_preferRepeat = (1 << 2), + /** + * If set: Sample the input and check if the sample is uncompressible, if it is then don't attempt to compress. + * If unset: Always histogram the entire input. + */ + HUF_flags_suspectUncompressible = (1 << 3), + /** + * If set: Don't use assembly implementations + * If unset: Allow using assembly implementations + */ + HUF_flags_disableAsm = (1 << 4), + /** + * If set: Don't use the fast decoding loop, always use the fallback decoding loop. + * If unset: Use the fast decoding loop when possible. + */ + HUF_flags_disableFast = (1 << 5) +} HUF_flags_e; + + +/* **************************************** + * HUF detailed API + * ****************************************/ +#define HUF_OPTIMAL_DEPTH_THRESHOLD ZSTD_btultra + +/*! HUF_compress() does the following: + * 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h") + * 2. (optional) refine tableLog using HUF_optimalTableLog() + * 3. build Huffman table from count using HUF_buildCTable() + * 4. save Huffman table to memory buffer using HUF_writeCTable() + * 5. encode the data stream using HUF_compress4X_usingCTable() + * + * The following API allows targeting specific sub-functions for advanced tasks. + * For example, it's possible to compress several blocks using the same 'CTable', + * or to save and regenerate 'CTable' using external methods. + */ +unsigned HUF_minTableLog(unsigned symbolCardinality); +unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue); +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void* workSpace, + size_t wkspSize, HUF_CElt* table, const unsigned* count, int flags); /* table is used as scratch space for building and testing tables, not a return value */ +size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize); +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags); +size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); +int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); + +typedef enum { + HUF_repeat_none, /**< Cannot use the previous table */ + HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */ + HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */ + } HUF_repeat; + +/** HUF_compress4X_repeat() : + * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. + * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ +size_t HUF_compress4X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int flags); + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE. + */ +#define HUF_CTABLE_WORKSPACE_SIZE_U32 ((4 * (HUF_SYMBOLVALUE_MAX + 1)) + 192) +#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_buildCTable_wksp (HUF_CElt* tree, + const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, + void* workSpace, size_t wkspSize); + +/*! HUF_readStats() : + * Read compact Huffman tree, saved by HUF_writeCTable(). + * `huffWeight` is destination buffer. + * @return : size read from `src` , or an error Code . + * Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize); + +/*! HUF_readStats_wksp() : + * Same as HUF_readStats() but takes an external workspace which must be + * 4-byte aligned and its size must be >= HUF_READ_STATS_WORKSPACE_SIZE. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +#define HUF_READ_STATS_WORKSPACE_SIZE_U32 FSE_DECOMPRESS_WKSP_SIZE_U32(6, HUF_TABLELOG_MAX-1) +#define HUF_READ_STATS_WORKSPACE_SIZE (HUF_READ_STATS_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workspace, size_t wkspSize, + int flags); + +/** HUF_readCTable() : + * Loading a CTable saved with HUF_writeCTable() */ +size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights); + +/** HUF_getNbBitsFromCTable() : + * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX + * Note 1 : If symbolValue > HUF_readCTableHeader(symbolTable).maxSymbolValue, returns 0 + * Note 2 : is not inlined, as HUF_CElt definition is private + */ +U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue); + +typedef struct { + BYTE tableLog; + BYTE maxSymbolValue; + BYTE unused[sizeof(size_t) - 2]; +} HUF_CTableHeader; + +/** HUF_readCTableHeader() : + * @returns The header from the CTable specifying the tableLog and the maxSymbolValue. + */ +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable); + +/* + * HUF_decompress() does the following: + * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics + * 2. build Huffman table from save, using HUF_readDTableX?() + * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable() + */ + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize); + +/** + * The minimum workspace size for the `workSpace` used in + * HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp(). + * + * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when + * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. + * Buffer overflow errors may potentially occur if code modifications result in + * a required workspace size greater than that specified in the following + * macro. + */ +#define HUF_DECOMPRESS_WORKSPACE_SIZE ((2 << 10) + (1 << 9)) +#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) + + +/* ====================== */ +/* single stream variants */ +/* ====================== */ + +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags); +/** HUF_compress1X_repeat() : + * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. + * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ +size_t HUF_compress1X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int flags); + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); /**< double-symbols decoder */ +#endif + +/* BMI2 variants. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#endif +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags); +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags); +#endif +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags); +#endif + +#endif /* HUF_H_298734234 */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/mem.h b/cpp/third_party/zstd-1.5.7/lib/common/mem.h new file mode 100644 index 000000000..e66a2eaeb --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/mem.h @@ -0,0 +1,422 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef MEM_H_MODULE +#define MEM_H_MODULE + +/*-**************************************** +* Dependencies +******************************************/ +#include /* size_t, ptrdiff_t */ +#include "compiler.h" /* __has_builtin */ +#include "debug.h" /* DEBUG_STATIC_ASSERT */ +#include "zstd_deps.h" /* ZSTD_memcpy */ + + +/*-**************************************** +* Compiler specifics +******************************************/ +#if defined(_MSC_VER) /* Visual Studio */ +# include /* _byteswap_ulong */ +# include /* _byteswap_* */ +#elif defined(__ICCARM__) +# include +#endif + +/*-************************************************************** +* Basic Types +*****************************************************************/ +#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# if defined(_AIX) +# include +# else +# include /* intptr_t */ +# endif + typedef uint8_t BYTE; + typedef uint8_t U8; + typedef int8_t S8; + typedef uint16_t U16; + typedef int16_t S16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; + typedef int64_t S64; +#else +# include +#if CHAR_BIT != 8 +# error "this implementation requires char to be exactly 8-bit type" +#endif + typedef unsigned char BYTE; + typedef unsigned char U8; + typedef signed char S8; +#if USHRT_MAX != 65535 +# error "this implementation requires short to be exactly 16-bit type" +#endif + typedef unsigned short U16; + typedef signed short S16; +#if UINT_MAX != 4294967295 +# error "this implementation requires int to be exactly 32-bit type" +#endif + typedef unsigned int U32; + typedef signed int S32; +/* note : there are no limits defined for long long type in C90. + * limits exist in C99, however, in such case, is preferred */ + typedef unsigned long long U64; + typedef signed long long S64; +#endif + +/*-************************************************************** +* Memory I/O API +*****************************************************************/ +/*=== Static platform detection ===*/ +MEM_STATIC unsigned MEM_32bits(void); +MEM_STATIC unsigned MEM_64bits(void); +MEM_STATIC unsigned MEM_isLittleEndian(void); + +/*=== Native unaligned read/write ===*/ +MEM_STATIC U16 MEM_read16(const void* memPtr); +MEM_STATIC U32 MEM_read32(const void* memPtr); +MEM_STATIC U64 MEM_read64(const void* memPtr); +MEM_STATIC size_t MEM_readST(const void* memPtr); + +MEM_STATIC void MEM_write16(void* memPtr, U16 value); +MEM_STATIC void MEM_write32(void* memPtr, U32 value); +MEM_STATIC void MEM_write64(void* memPtr, U64 value); + +/*=== Little endian unaligned read/write ===*/ +MEM_STATIC U16 MEM_readLE16(const void* memPtr); +MEM_STATIC U32 MEM_readLE24(const void* memPtr); +MEM_STATIC U32 MEM_readLE32(const void* memPtr); +MEM_STATIC U64 MEM_readLE64(const void* memPtr); +MEM_STATIC size_t MEM_readLEST(const void* memPtr); + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val); +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val); +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val); + +/*=== Big endian unaligned read/write ===*/ +MEM_STATIC U32 MEM_readBE32(const void* memPtr); +MEM_STATIC U64 MEM_readBE64(const void* memPtr); +MEM_STATIC size_t MEM_readBEST(const void* memPtr); + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val); + +/*=== Byteswap ===*/ +MEM_STATIC U32 MEM_swap32(U32 in); +MEM_STATIC U64 MEM_swap64(U64 in); +MEM_STATIC size_t MEM_swapST(size_t in); + + +/*-************************************************************** +* Memory I/O Implementation +*****************************************************************/ +/* MEM_FORCE_MEMORY_ACCESS : For accessing unaligned memory: + * Method 0 : always use `memcpy()`. Safe and portable. + * Method 1 : Use compiler extension to set unaligned access. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets depending on alignment. + * Default : method 1 if supported, else method 0 + */ +#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# ifdef __GNUC__ +# define MEM_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } +MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } + +MEM_STATIC unsigned MEM_isLittleEndian(void) +{ +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + return 1; +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + return 0; +#elif defined(__clang__) && __LITTLE_ENDIAN__ + return 1; +#elif defined(__clang__) && __BIG_ENDIAN__ + return 0; +#elif defined(_MSC_VER) && (_M_X64 || _M_IX86) + return 1; +#elif defined(__DMC__) && defined(_M_IX86) + return 1; +#elif defined(__IAR_SYSTEMS_ICC__) && __LITTLE_ENDIAN__ + return 1; +#else + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +#endif +} + +#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) + +/* violates C standard, by lying on structure alignment. +Only use if no other choice to achieve best performance on target platform */ +MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } +MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } +MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } +MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } + +#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) + +typedef __attribute__((aligned(1))) U16 unalign16; +typedef __attribute__((aligned(1))) U32 unalign32; +typedef __attribute__((aligned(1))) U64 unalign64; +typedef __attribute__((aligned(1))) size_t unalignArch; + +MEM_STATIC U16 MEM_read16(const void* ptr) { return *(const unalign16*)ptr; } +MEM_STATIC U32 MEM_read32(const void* ptr) { return *(const unalign32*)ptr; } +MEM_STATIC U64 MEM_read64(const void* ptr) { return *(const unalign64*)ptr; } +MEM_STATIC size_t MEM_readST(const void* ptr) { return *(const unalignArch*)ptr; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(unalign16*)memPtr = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(unalign32*)memPtr = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(unalign64*)memPtr = value; } + +#else + +/* default method, safe and standard. + can sometimes prove slower */ + +MEM_STATIC U16 MEM_read16(const void* memPtr) +{ + U16 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U32 MEM_read32(const void* memPtr) +{ + U32 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U64 MEM_read64(const void* memPtr) +{ + U64 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC size_t MEM_readST(const void* memPtr) +{ + size_t val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write32(void* memPtr, U32 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write64(void* memPtr, U64 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* MEM_FORCE_MEMORY_ACCESS */ + +MEM_STATIC U32 MEM_swap32_fallback(U32 in) +{ + return ((in << 24) & 0xff000000 ) | + ((in << 8) & 0x00ff0000 ) | + ((in >> 8) & 0x0000ff00 ) | + ((in >> 24) & 0x000000ff ); +} + +MEM_STATIC U32 MEM_swap32(U32 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_ulong(in); +#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \ + || (defined(__clang__) && __has_builtin(__builtin_bswap32)) + return __builtin_bswap32(in); +#elif defined(__ICCARM__) + return __REV(in); +#else + return MEM_swap32_fallback(in); +#endif +} + +MEM_STATIC U64 MEM_swap64_fallback(U64 in) +{ + return ((in << 56) & 0xff00000000000000ULL) | + ((in << 40) & 0x00ff000000000000ULL) | + ((in << 24) & 0x0000ff0000000000ULL) | + ((in << 8) & 0x000000ff00000000ULL) | + ((in >> 8) & 0x00000000ff000000ULL) | + ((in >> 24) & 0x0000000000ff0000ULL) | + ((in >> 40) & 0x000000000000ff00ULL) | + ((in >> 56) & 0x00000000000000ffULL); +} + +MEM_STATIC U64 MEM_swap64(U64 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_uint64(in); +#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \ + || (defined(__clang__) && __has_builtin(__builtin_bswap64)) + return __builtin_bswap64(in); +#else + return MEM_swap64_fallback(in); +#endif +} + +MEM_STATIC size_t MEM_swapST(size_t in) +{ + if (MEM_32bits()) + return (size_t)MEM_swap32((U32)in); + else + return (size_t)MEM_swap64((U64)in); +} + +/*=== Little endian r/w ===*/ + +MEM_STATIC U16 MEM_readLE16(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read16(memPtr); + else { + const BYTE* p = (const BYTE*)memPtr; + return (U16)(p[0] + (p[1]<<8)); + } +} + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) +{ + if (MEM_isLittleEndian()) { + MEM_write16(memPtr, val); + } else { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE)val; + p[1] = (BYTE)(val>>8); + } +} + +MEM_STATIC U32 MEM_readLE24(const void* memPtr) +{ + return (U32)MEM_readLE16(memPtr) + ((U32)(((const BYTE*)memPtr)[2]) << 16); +} + +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val) +{ + MEM_writeLE16(memPtr, (U16)val); + ((BYTE*)memPtr)[2] = (BYTE)(val>>16); +} + +MEM_STATIC U32 MEM_readLE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read32(memPtr); + else + return MEM_swap32(MEM_read32(memPtr)); +} + +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, val32); + else + MEM_write32(memPtr, MEM_swap32(val32)); +} + +MEM_STATIC U64 MEM_readLE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read64(memPtr); + else + return MEM_swap64(MEM_read64(memPtr)); +} + +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, val64); + else + MEM_write64(memPtr, MEM_swap64(val64)); +} + +MEM_STATIC size_t MEM_readLEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readLE32(memPtr); + else + return (size_t)MEM_readLE64(memPtr); +} + +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeLE32(memPtr, (U32)val); + else + MEM_writeLE64(memPtr, (U64)val); +} + +/*=== Big endian r/w ===*/ + +MEM_STATIC U32 MEM_readBE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap32(MEM_read32(memPtr)); + else + return MEM_read32(memPtr); +} + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, MEM_swap32(val32)); + else + MEM_write32(memPtr, val32); +} + +MEM_STATIC U64 MEM_readBE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap64(MEM_read64(memPtr)); + else + return MEM_read64(memPtr); +} + +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, MEM_swap64(val64)); + else + MEM_write64(memPtr, val64); +} + +MEM_STATIC size_t MEM_readBEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readBE32(memPtr); + else + return (size_t)MEM_readBE64(memPtr); +} + +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeBE32(memPtr, (U32)val); + else + MEM_writeBE64(memPtr, (U64)val); +} + +/* code only tested on 32 and 64 bits systems */ +MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } + +#endif /* MEM_H_MODULE */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/pool.c b/cpp/third_party/zstd-1.5.7/lib/common/pool.c new file mode 100644 index 000000000..3adcefc9a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/pool.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* ====== Dependencies ======= */ +#include "../common/allocations.h" /* ZSTD_customCalloc, ZSTD_customFree */ +#include "zstd_deps.h" /* size_t */ +#include "debug.h" /* assert */ +#include "pool.h" + +/* ====== Compiler specifics ====== */ +#if defined(_MSC_VER) +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ +#endif + + +#ifdef ZSTD_MULTITHREAD + +#include "threading.h" /* pthread adaptation */ + +/* A job is a function and an opaque argument */ +typedef struct POOL_job_s { + POOL_function function; + void *opaque; +} POOL_job; + +struct POOL_ctx_s { + ZSTD_customMem customMem; + /* Keep track of the threads */ + ZSTD_pthread_t* threads; + size_t threadCapacity; + size_t threadLimit; + + /* The queue is a circular buffer */ + POOL_job *queue; + size_t queueHead; + size_t queueTail; + size_t queueSize; + + /* The number of threads working on jobs */ + size_t numThreadsBusy; + /* Indicates if the queue is empty */ + int queueEmpty; + + /* The mutex protects the queue */ + ZSTD_pthread_mutex_t queueMutex; + /* Condition variable for pushers to wait on when the queue is full */ + ZSTD_pthread_cond_t queuePushCond; + /* Condition variables for poppers to wait on when the queue is empty */ + ZSTD_pthread_cond_t queuePopCond; + /* Indicates if the queue is shutting down */ + int shutdown; +}; + +/* POOL_thread() : + * Work thread for the thread pool. + * Waits for jobs and executes them. + * @returns : NULL on failure else non-null. + */ +static void* POOL_thread(void* opaque) { + POOL_ctx* const ctx = (POOL_ctx*)opaque; + if (!ctx) { return NULL; } + for (;;) { + /* Lock the mutex and wait for a non-empty queue or until shutdown */ + ZSTD_pthread_mutex_lock(&ctx->queueMutex); + + while ( ctx->queueEmpty + || (ctx->numThreadsBusy >= ctx->threadLimit) ) { + if (ctx->shutdown) { + /* even if !queueEmpty, (possible if numThreadsBusy >= threadLimit), + * a few threads will be shutdown while !queueEmpty, + * but enough threads will remain active to finish the queue */ + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); + return opaque; + } + ZSTD_pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex); + } + /* Pop a job off the queue */ + { POOL_job const job = ctx->queue[ctx->queueHead]; + ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize; + ctx->numThreadsBusy++; + ctx->queueEmpty = (ctx->queueHead == ctx->queueTail); + /* Unlock the mutex, signal a pusher, and run the job */ + ZSTD_pthread_cond_signal(&ctx->queuePushCond); + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); + + job.function(job.opaque); + + /* If the intended queue size was 0, signal after finishing job */ + ZSTD_pthread_mutex_lock(&ctx->queueMutex); + ctx->numThreadsBusy--; + ZSTD_pthread_cond_signal(&ctx->queuePushCond); + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); + } + } /* for (;;) */ + assert(0); /* Unreachable */ +} + +/* ZSTD_createThreadPool() : public access point */ +POOL_ctx* ZSTD_createThreadPool(size_t numThreads) { + return POOL_create (numThreads, 0); +} + +POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) { + return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem); +} + +POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, + ZSTD_customMem customMem) +{ + POOL_ctx* ctx; + /* Check parameters */ + if (!numThreads) { return NULL; } + /* Allocate the context and zero initialize */ + ctx = (POOL_ctx*)ZSTD_customCalloc(sizeof(POOL_ctx), customMem); + if (!ctx) { return NULL; } + /* Initialize the job queue. + * It needs one extra space since one space is wasted to differentiate + * empty and full queues. + */ + ctx->queueSize = queueSize + 1; + ctx->queue = (POOL_job*)ZSTD_customCalloc(ctx->queueSize * sizeof(POOL_job), customMem); + ctx->queueHead = 0; + ctx->queueTail = 0; + ctx->numThreadsBusy = 0; + ctx->queueEmpty = 1; + { + int error = 0; + error |= ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL); + error |= ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL); + error |= ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL); + if (error) { POOL_free(ctx); return NULL; } + } + ctx->shutdown = 0; + /* Allocate space for the thread handles */ + ctx->threads = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), customMem); + ctx->threadCapacity = 0; + ctx->customMem = customMem; + /* Check for errors */ + if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; } + /* Initialize the threads */ + { size_t i; + for (i = 0; i < numThreads; ++i) { + if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) { + ctx->threadCapacity = i; + POOL_free(ctx); + return NULL; + } } + ctx->threadCapacity = numThreads; + ctx->threadLimit = numThreads; + } + return ctx; +} + +/*! POOL_join() : + Shutdown the queue, wake any sleeping threads, and join all of the threads. +*/ +static void POOL_join(POOL_ctx* ctx) { + /* Shut down the queue */ + ZSTD_pthread_mutex_lock(&ctx->queueMutex); + ctx->shutdown = 1; + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); + /* Wake up sleeping threads */ + ZSTD_pthread_cond_broadcast(&ctx->queuePushCond); + ZSTD_pthread_cond_broadcast(&ctx->queuePopCond); + /* Join all of the threads */ + { size_t i; + for (i = 0; i < ctx->threadCapacity; ++i) { + ZSTD_pthread_join(ctx->threads[i]); /* note : could fail */ + } } +} + +void POOL_free(POOL_ctx *ctx) { + if (!ctx) { return; } + POOL_join(ctx); + ZSTD_pthread_mutex_destroy(&ctx->queueMutex); + ZSTD_pthread_cond_destroy(&ctx->queuePushCond); + ZSTD_pthread_cond_destroy(&ctx->queuePopCond); + ZSTD_customFree(ctx->queue, ctx->customMem); + ZSTD_customFree(ctx->threads, ctx->customMem); + ZSTD_customFree(ctx, ctx->customMem); +} + +/*! POOL_joinJobs() : + * Waits for all queued jobs to finish executing. + */ +void POOL_joinJobs(POOL_ctx* ctx) { + ZSTD_pthread_mutex_lock(&ctx->queueMutex); + while(!ctx->queueEmpty || ctx->numThreadsBusy > 0) { + ZSTD_pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex); + } + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); +} + +void ZSTD_freeThreadPool (ZSTD_threadPool* pool) { + POOL_free (pool); +} + +size_t POOL_sizeof(const POOL_ctx* ctx) { + if (ctx==NULL) return 0; /* supports sizeof NULL */ + return sizeof(*ctx) + + ctx->queueSize * sizeof(POOL_job) + + ctx->threadCapacity * sizeof(ZSTD_pthread_t); +} + + +/* @return : 0 on success, 1 on error */ +static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads) +{ + if (numThreads <= ctx->threadCapacity) { + if (!numThreads) return 1; + ctx->threadLimit = numThreads; + return 0; + } + /* numThreads > threadCapacity */ + { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem); + if (!threadPool) return 1; + /* replace existing thread pool */ + ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(ZSTD_pthread_t)); + ZSTD_customFree(ctx->threads, ctx->customMem); + ctx->threads = threadPool; + /* Initialize additional threads */ + { size_t threadId; + for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) { + if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) { + ctx->threadCapacity = threadId; + return 1; + } } + } } + /* successfully expanded */ + ctx->threadCapacity = numThreads; + ctx->threadLimit = numThreads; + return 0; +} + +/* @return : 0 on success, 1 on error */ +int POOL_resize(POOL_ctx* ctx, size_t numThreads) +{ + int result; + if (ctx==NULL) return 1; + ZSTD_pthread_mutex_lock(&ctx->queueMutex); + result = POOL_resize_internal(ctx, numThreads); + ZSTD_pthread_cond_broadcast(&ctx->queuePopCond); + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); + return result; +} + +/** + * Returns 1 if the queue is full and 0 otherwise. + * + * When queueSize is 1 (pool was created with an intended queueSize of 0), + * then a queue is empty if there is a thread free _and_ no job is waiting. + */ +static int isQueueFull(POOL_ctx const* ctx) { + if (ctx->queueSize > 1) { + return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize); + } else { + return (ctx->numThreadsBusy == ctx->threadLimit) || + !ctx->queueEmpty; + } +} + + +static void +POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque) +{ + POOL_job job; + job.function = function; + job.opaque = opaque; + assert(ctx != NULL); + if (ctx->shutdown) return; + + ctx->queueEmpty = 0; + ctx->queue[ctx->queueTail] = job; + ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize; + ZSTD_pthread_cond_signal(&ctx->queuePopCond); +} + +void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) +{ + assert(ctx != NULL); + ZSTD_pthread_mutex_lock(&ctx->queueMutex); + /* Wait until there is space in the queue for the new job */ + while (isQueueFull(ctx) && (!ctx->shutdown)) { + ZSTD_pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex); + } + POOL_add_internal(ctx, function, opaque); + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); +} + + +int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) +{ + assert(ctx != NULL); + ZSTD_pthread_mutex_lock(&ctx->queueMutex); + if (isQueueFull(ctx)) { + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); + return 0; + } + POOL_add_internal(ctx, function, opaque); + ZSTD_pthread_mutex_unlock(&ctx->queueMutex); + return 1; +} + + +#else /* ZSTD_MULTITHREAD not defined */ + +/* ========================== */ +/* No multi-threading support */ +/* ========================== */ + + +/* We don't need any data, but if it is empty, malloc() might return NULL. */ +struct POOL_ctx_s { + int dummy; +}; +static POOL_ctx g_poolCtx; + +POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) { + return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem); +} + +POOL_ctx* +POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) +{ + (void)numThreads; + (void)queueSize; + (void)customMem; + return &g_poolCtx; +} + +void POOL_free(POOL_ctx* ctx) { + assert(!ctx || ctx == &g_poolCtx); + (void)ctx; +} + +void POOL_joinJobs(POOL_ctx* ctx){ + assert(!ctx || ctx == &g_poolCtx); + (void)ctx; +} + +int POOL_resize(POOL_ctx* ctx, size_t numThreads) { + (void)ctx; (void)numThreads; + return 0; +} + +void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) { + (void)ctx; + function(opaque); +} + +int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) { + (void)ctx; + function(opaque); + return 1; +} + +size_t POOL_sizeof(const POOL_ctx* ctx) { + if (ctx==NULL) return 0; /* supports sizeof NULL */ + assert(ctx == &g_poolCtx); + return sizeof(*ctx); +} + +#endif /* ZSTD_MULTITHREAD */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/pool.h b/cpp/third_party/zstd-1.5.7/lib/common/pool.h new file mode 100644 index 000000000..f39b7f1eb --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/pool.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef POOL_H +#define POOL_H + + +#include "zstd_deps.h" +#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */ +#include "../zstd.h" + +typedef struct POOL_ctx_s POOL_ctx; + +/*! POOL_create() : + * Create a thread pool with at most `numThreads` threads. + * `numThreads` must be at least 1. + * The maximum number of queued jobs before blocking is `queueSize`. + * @return : POOL_ctx pointer on success, else NULL. +*/ +POOL_ctx* POOL_create(size_t numThreads, size_t queueSize); + +POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, + ZSTD_customMem customMem); + +/*! POOL_free() : + * Free a thread pool returned by POOL_create(). + */ +void POOL_free(POOL_ctx* ctx); + + +/*! POOL_joinJobs() : + * Waits for all queued jobs to finish executing. + */ +void POOL_joinJobs(POOL_ctx* ctx); + +/*! POOL_resize() : + * Expands or shrinks pool's number of threads. + * This is more efficient than releasing + creating a new context, + * since it tries to preserve and reuse existing threads. + * `numThreads` must be at least 1. + * @return : 0 when resize was successful, + * !0 (typically 1) if there is an error. + * note : only numThreads can be resized, queueSize remains unchanged. + */ +int POOL_resize(POOL_ctx* ctx, size_t numThreads); + +/*! POOL_sizeof() : + * @return threadpool memory usage + * note : compatible with NULL (returns 0 in this case) + */ +size_t POOL_sizeof(const POOL_ctx* ctx); + +/*! POOL_function : + * The function type that can be added to a thread pool. + */ +typedef void (*POOL_function)(void*); + +/*! POOL_add() : + * Add the job `function(opaque)` to the thread pool. `ctx` must be valid. + * Possibly blocks until there is room in the queue. + * Note : The function may be executed asynchronously, + * therefore, `opaque` must live until function has been completed. + */ +void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque); + + +/*! POOL_tryAdd() : + * Add the job `function(opaque)` to thread pool _if_ a queue slot is available. + * Returns immediately even if not (does not block). + * @return : 1 if successful, 0 if not. + */ +int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque); + +#endif diff --git a/cpp/third_party/zstd-1.5.7/lib/common/portability_macros.h b/cpp/third_party/zstd-1.5.7/lib/common/portability_macros.h new file mode 100644 index 000000000..860734141 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/portability_macros.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_PORTABILITY_MACROS_H +#define ZSTD_PORTABILITY_MACROS_H + +/** + * This header file contains macro definitions to support portability. + * This header is shared between C and ASM code, so it MUST only + * contain macro definitions. It MUST not contain any C code. + * + * This header ONLY defines macros to detect platforms/feature support. + * + */ + + +/* compat. with non-clang compilers */ +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +/* detects whether we are being compiled under msan */ +#ifndef ZSTD_MEMORY_SANITIZER +# if __has_feature(memory_sanitizer) +# define ZSTD_MEMORY_SANITIZER 1 +# else +# define ZSTD_MEMORY_SANITIZER 0 +# endif +#endif + +/* detects whether we are being compiled under asan */ +#ifndef ZSTD_ADDRESS_SANITIZER +# if __has_feature(address_sanitizer) +# define ZSTD_ADDRESS_SANITIZER 1 +# elif defined(__SANITIZE_ADDRESS__) +# define ZSTD_ADDRESS_SANITIZER 1 +# else +# define ZSTD_ADDRESS_SANITIZER 0 +# endif +#endif + +/* detects whether we are being compiled under dfsan */ +#ifndef ZSTD_DATAFLOW_SANITIZER +# if __has_feature(dataflow_sanitizer) +# define ZSTD_DATAFLOW_SANITIZER 1 +# else +# define ZSTD_DATAFLOW_SANITIZER 0 +# endif +#endif + +/* Mark the internal assembly functions as hidden */ +#ifdef __ELF__ +# define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func +#elif defined(__APPLE__) +# define ZSTD_HIDE_ASM_FUNCTION(func) .private_extern func +#else +# define ZSTD_HIDE_ASM_FUNCTION(func) +#endif + +/* Compile time determination of BMI2 support */ +#ifndef STATIC_BMI2 +# if defined(__BMI2__) +# define STATIC_BMI2 1 +# elif defined(_MSC_VER) && defined(__AVX2__) +# define STATIC_BMI2 1 /* MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2 */ +# endif +#endif + +#ifndef STATIC_BMI2 +# define STATIC_BMI2 0 +#endif + +/* Enable runtime BMI2 dispatch based on the CPU. + * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. + */ +#ifndef DYNAMIC_BMI2 +# if ((defined(__clang__) && __has_attribute(__target__)) \ + || (defined(__GNUC__) \ + && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ + && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)) \ + && !defined(__BMI2__) +# define DYNAMIC_BMI2 1 +# else +# define DYNAMIC_BMI2 0 +# endif +#endif + +/** + * Only enable assembly for GNU C compatible compilers, + * because other platforms may not support GAS assembly syntax. + * + * Only enable assembly for Linux / MacOS / Win32, other platforms may + * work, but they haven't been tested. This could likely be + * extended to BSD systems. + * + * Disable assembly when MSAN is enabled, because MSAN requires + * 100% of code to be instrumented to work. + */ +#if defined(__GNUC__) +# if defined(__linux__) || defined(__linux) || defined(__APPLE__) || defined(_WIN32) +# if ZSTD_MEMORY_SANITIZER +# define ZSTD_ASM_SUPPORTED 0 +# elif ZSTD_DATAFLOW_SANITIZER +# define ZSTD_ASM_SUPPORTED 0 +# else +# define ZSTD_ASM_SUPPORTED 1 +# endif +# else +# define ZSTD_ASM_SUPPORTED 0 +# endif +#else +# define ZSTD_ASM_SUPPORTED 0 +#endif + +/** + * Determines whether we should enable assembly for x86-64 + * with BMI2. + * + * Enable if all of the following conditions hold: + * - ASM hasn't been explicitly disabled by defining ZSTD_DISABLE_ASM + * - Assembly is supported + * - We are compiling for x86-64 and either: + * - DYNAMIC_BMI2 is enabled + * - BMI2 is supported at compile time + */ +#if !defined(ZSTD_DISABLE_ASM) && \ + ZSTD_ASM_SUPPORTED && \ + defined(__x86_64__) && \ + (DYNAMIC_BMI2 || defined(__BMI2__)) +# define ZSTD_ENABLE_ASM_X86_64_BMI2 1 +#else +# define ZSTD_ENABLE_ASM_X86_64_BMI2 0 +#endif + +/* + * For x86 ELF targets, add .note.gnu.property section for Intel CET in + * assembly sources when CET is enabled. + * + * Additionally, any function that may be called indirectly must begin + * with ZSTD_CET_ENDBRANCH. + */ +#if defined(__ELF__) && (defined(__x86_64__) || defined(__i386__)) \ + && defined(__has_include) +# if __has_include() +# include +# define ZSTD_CET_ENDBRANCH _CET_ENDBR +# endif +#endif + +#ifndef ZSTD_CET_ENDBRANCH +# define ZSTD_CET_ENDBRANCH +#endif + +#endif /* ZSTD_PORTABILITY_MACROS_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/threading.c b/cpp/third_party/zstd-1.5.7/lib/common/threading.c new file mode 100644 index 000000000..25bb8b981 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/threading.c @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2016 Tino Reichardt + * All rights reserved. + * + * You can contact the author at: + * - zstdmt source repository: https://github.com/mcmilk/zstdmt + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/** + * This file will hold wrapper for systems, which do not support pthreads + */ + +#include "threading.h" + +/* create fake symbol to avoid empty translation unit warning */ +int g_ZSTD_threading_useless_symbol; + +#if defined(ZSTD_MULTITHREAD) && defined(_WIN32) + +/** + * Windows minimalist Pthread Wrapper + */ + + +/* === Dependencies === */ +#include +#include + + +/* === Implementation === */ + +typedef struct { + void* (*start_routine)(void*); + void* arg; + int initialized; + ZSTD_pthread_cond_t initialized_cond; + ZSTD_pthread_mutex_t initialized_mutex; +} ZSTD_thread_params_t; + +static unsigned __stdcall worker(void *arg) +{ + void* (*start_routine)(void*); + void* thread_arg; + + /* Initialized thread_arg and start_routine and signal main thread that we don't need it + * to wait any longer. + */ + { + ZSTD_thread_params_t* thread_param = (ZSTD_thread_params_t*)arg; + thread_arg = thread_param->arg; + start_routine = thread_param->start_routine; + + /* Signal main thread that we are running and do not depend on its memory anymore */ + ZSTD_pthread_mutex_lock(&thread_param->initialized_mutex); + thread_param->initialized = 1; + ZSTD_pthread_cond_signal(&thread_param->initialized_cond); + ZSTD_pthread_mutex_unlock(&thread_param->initialized_mutex); + } + + start_routine(thread_arg); + + return 0; +} + +int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, + void* (*start_routine) (void*), void* arg) +{ + ZSTD_thread_params_t thread_param; + (void)unused; + + if (thread==NULL) return -1; + *thread = NULL; + + thread_param.start_routine = start_routine; + thread_param.arg = arg; + thread_param.initialized = 0; + + /* Setup thread initialization synchronization */ + if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) { + /* Should never happen on Windows */ + return -1; + } + if(ZSTD_pthread_mutex_init(&thread_param.initialized_mutex, NULL)) { + /* Should never happen on Windows */ + ZSTD_pthread_cond_destroy(&thread_param.initialized_cond); + return -1; + } + + /* Spawn thread */ + *thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL); + if (*thread==NULL) { + ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex); + ZSTD_pthread_cond_destroy(&thread_param.initialized_cond); + return errno; + } + + /* Wait for thread to be initialized */ + ZSTD_pthread_mutex_lock(&thread_param.initialized_mutex); + while(!thread_param.initialized) { + ZSTD_pthread_cond_wait(&thread_param.initialized_cond, &thread_param.initialized_mutex); + } + ZSTD_pthread_mutex_unlock(&thread_param.initialized_mutex); + ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex); + ZSTD_pthread_cond_destroy(&thread_param.initialized_cond); + + return 0; +} + +int ZSTD_pthread_join(ZSTD_pthread_t thread) +{ + DWORD result; + + if (!thread) return 0; + + result = WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + switch (result) { + case WAIT_OBJECT_0: + return 0; + case WAIT_ABANDONED: + return EINVAL; + default: + return GetLastError(); + } +} + +#endif /* ZSTD_MULTITHREAD */ + +#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32) + +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" + +int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr) +{ + assert(mutex != NULL); + *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t)); + if (!*mutex) + return 1; + return pthread_mutex_init(*mutex, attr); +} + +int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex) +{ + assert(mutex != NULL); + if (!*mutex) + return 0; + { + int const ret = pthread_mutex_destroy(*mutex); + ZSTD_free(*mutex); + return ret; + } +} + +int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr) +{ + assert(cond != NULL); + *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t)); + if (!*cond) + return 1; + return pthread_cond_init(*cond, attr); +} + +int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond) +{ + assert(cond != NULL); + if (!*cond) + return 0; + { + int const ret = pthread_cond_destroy(*cond); + ZSTD_free(*cond); + return ret; + } +} + +#endif diff --git a/cpp/third_party/zstd-1.5.7/lib/common/threading.h b/cpp/third_party/zstd-1.5.7/lib/common/threading.h new file mode 100644 index 000000000..e123cdf14 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/threading.h @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2016 Tino Reichardt + * All rights reserved. + * + * You can contact the author at: + * - zstdmt source repository: https://github.com/mcmilk/zstdmt + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef THREADING_H_938743 +#define THREADING_H_938743 + +#include "debug.h" + +#if defined(ZSTD_MULTITHREAD) && defined(_WIN32) + +/** + * Windows minimalist Pthread Wrapper + */ +#ifdef WINVER +# undef WINVER +#endif +#define WINVER 0x0600 + +#ifdef _WIN32_WINNT +# undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0600 + +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */ +#include +#undef ERROR +#define ERROR(name) ZSTD_ERROR(name) + + +/* mutex */ +#define ZSTD_pthread_mutex_t CRITICAL_SECTION +#define ZSTD_pthread_mutex_init(a, b) ((void)(b), InitializeCriticalSection((a)), 0) +#define ZSTD_pthread_mutex_destroy(a) DeleteCriticalSection((a)) +#define ZSTD_pthread_mutex_lock(a) EnterCriticalSection((a)) +#define ZSTD_pthread_mutex_unlock(a) LeaveCriticalSection((a)) + +/* condition variable */ +#define ZSTD_pthread_cond_t CONDITION_VARIABLE +#define ZSTD_pthread_cond_init(a, b) ((void)(b), InitializeConditionVariable((a)), 0) +#define ZSTD_pthread_cond_destroy(a) ((void)(a)) +#define ZSTD_pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE) +#define ZSTD_pthread_cond_signal(a) WakeConditionVariable((a)) +#define ZSTD_pthread_cond_broadcast(a) WakeAllConditionVariable((a)) + +/* ZSTD_pthread_create() and ZSTD_pthread_join() */ +typedef HANDLE ZSTD_pthread_t; + +int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, + void* (*start_routine) (void*), void* arg); + +int ZSTD_pthread_join(ZSTD_pthread_t thread); + +/** + * add here more wrappers as required + */ + +#elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */ +/* === POSIX Systems === */ +# include + +#if DEBUGLEVEL < 1 + +#define ZSTD_pthread_mutex_t pthread_mutex_t +#define ZSTD_pthread_mutex_init(a, b) pthread_mutex_init((a), (b)) +#define ZSTD_pthread_mutex_destroy(a) pthread_mutex_destroy((a)) +#define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock((a)) +#define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock((a)) + +#define ZSTD_pthread_cond_t pthread_cond_t +#define ZSTD_pthread_cond_init(a, b) pthread_cond_init((a), (b)) +#define ZSTD_pthread_cond_destroy(a) pthread_cond_destroy((a)) +#define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait((a), (b)) +#define ZSTD_pthread_cond_signal(a) pthread_cond_signal((a)) +#define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast((a)) + +#define ZSTD_pthread_t pthread_t +#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d)) +#define ZSTD_pthread_join(a) pthread_join((a),NULL) + +#else /* DEBUGLEVEL >= 1 */ + +/* Debug implementation of threading. + * In this implementation we use pointers for mutexes and condition variables. + * This way, if we forget to init/destroy them the program will crash or ASAN + * will report leaks. + */ + +#define ZSTD_pthread_mutex_t pthread_mutex_t* +int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr); +int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex); +#define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock(*(a)) +#define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock(*(a)) + +#define ZSTD_pthread_cond_t pthread_cond_t* +int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr); +int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond); +#define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait(*(a), *(b)) +#define ZSTD_pthread_cond_signal(a) pthread_cond_signal(*(a)) +#define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast(*(a)) + +#define ZSTD_pthread_t pthread_t +#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d)) +#define ZSTD_pthread_join(a) pthread_join((a),NULL) + +#endif + +#else /* ZSTD_MULTITHREAD not defined */ +/* No multithreading support */ + +typedef int ZSTD_pthread_mutex_t; +#define ZSTD_pthread_mutex_init(a, b) ((void)(a), (void)(b), 0) +#define ZSTD_pthread_mutex_destroy(a) ((void)(a)) +#define ZSTD_pthread_mutex_lock(a) ((void)(a)) +#define ZSTD_pthread_mutex_unlock(a) ((void)(a)) + +typedef int ZSTD_pthread_cond_t; +#define ZSTD_pthread_cond_init(a, b) ((void)(a), (void)(b), 0) +#define ZSTD_pthread_cond_destroy(a) ((void)(a)) +#define ZSTD_pthread_cond_wait(a, b) ((void)(a), (void)(b)) +#define ZSTD_pthread_cond_signal(a) ((void)(a)) +#define ZSTD_pthread_cond_broadcast(a) ((void)(a)) + +/* do not use ZSTD_pthread_t */ + +#endif /* ZSTD_MULTITHREAD */ + + +#endif /* THREADING_H_938743 */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/xxhash.c b/cpp/third_party/zstd-1.5.7/lib/common/xxhash.c new file mode 100644 index 000000000..052cd5228 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/xxhash.c @@ -0,0 +1,18 @@ +/* + * xxHash - Extremely Fast Hash algorithm + * Copyright (c) Yann Collet - Meta Platforms, Inc + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* + * xxhash.c instantiates functions defined in xxhash.h + */ + +#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */ +#define XXH_IMPLEMENTATION /* access definitions */ + +#include "xxhash.h" diff --git a/cpp/third_party/zstd-1.5.7/lib/common/xxhash.h b/cpp/third_party/zstd-1.5.7/lib/common/xxhash.h new file mode 100644 index 000000000..b6af402fd --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/xxhash.h @@ -0,0 +1,7094 @@ +/* + * xxHash - Extremely Fast Hash algorithm + * Header File + * Copyright (c) Yann Collet - Meta Platforms, Inc + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* Local adaptations for Zstandard */ + +#ifndef XXH_NO_XXH3 +# define XXH_NO_XXH3 +#endif + +#ifndef XXH_NAMESPACE +# define XXH_NAMESPACE ZSTD_ +#endif + +/*! + * @mainpage xxHash + * + * xxHash is an extremely fast non-cryptographic hash algorithm, working at RAM speed + * limits. + * + * It is proposed in four flavors, in three families: + * 1. @ref XXH32_family + * - Classic 32-bit hash function. Simple, compact, and runs on almost all + * 32-bit and 64-bit systems. + * 2. @ref XXH64_family + * - Classic 64-bit adaptation of XXH32. Just as simple, and runs well on most + * 64-bit systems (but _not_ 32-bit systems). + * 3. @ref XXH3_family + * - Modern 64-bit and 128-bit hash function family which features improved + * strength and performance across the board, especially on smaller data. + * It benefits greatly from SIMD and 64-bit without requiring it. + * + * Benchmarks + * --- + * The reference system uses an Intel i7-9700K CPU, and runs Ubuntu x64 20.04. + * The open source benchmark program is compiled with clang v10.0 using -O3 flag. + * + * | Hash Name | ISA ext | Width | Large Data Speed | Small Data Velocity | + * | -------------------- | ------- | ----: | ---------------: | ------------------: | + * | XXH3_64bits() | @b AVX2 | 64 | 59.4 GB/s | 133.1 | + * | MeowHash | AES-NI | 128 | 58.2 GB/s | 52.5 | + * | XXH3_128bits() | @b AVX2 | 128 | 57.9 GB/s | 118.1 | + * | CLHash | PCLMUL | 64 | 37.1 GB/s | 58.1 | + * | XXH3_64bits() | @b SSE2 | 64 | 31.5 GB/s | 133.1 | + * | XXH3_128bits() | @b SSE2 | 128 | 29.6 GB/s | 118.1 | + * | RAM sequential read | | N/A | 28.0 GB/s | N/A | + * | ahash | AES-NI | 64 | 22.5 GB/s | 107.2 | + * | City64 | | 64 | 22.0 GB/s | 76.6 | + * | T1ha2 | | 64 | 22.0 GB/s | 99.0 | + * | City128 | | 128 | 21.7 GB/s | 57.7 | + * | FarmHash | AES-NI | 64 | 21.3 GB/s | 71.9 | + * | XXH64() | | 64 | 19.4 GB/s | 71.0 | + * | SpookyHash | | 64 | 19.3 GB/s | 53.2 | + * | Mum | | 64 | 18.0 GB/s | 67.0 | + * | CRC32C | SSE4.2 | 32 | 13.0 GB/s | 57.9 | + * | XXH32() | | 32 | 9.7 GB/s | 71.9 | + * | City32 | | 32 | 9.1 GB/s | 66.0 | + * | Blake3* | @b AVX2 | 256 | 4.4 GB/s | 8.1 | + * | Murmur3 | | 32 | 3.9 GB/s | 56.1 | + * | SipHash* | | 64 | 3.0 GB/s | 43.2 | + * | Blake3* | @b SSE2 | 256 | 2.4 GB/s | 8.1 | + * | HighwayHash | | 64 | 1.4 GB/s | 6.0 | + * | FNV64 | | 64 | 1.2 GB/s | 62.7 | + * | Blake2* | | 256 | 1.1 GB/s | 5.1 | + * | SHA1* | | 160 | 0.8 GB/s | 5.6 | + * | MD5* | | 128 | 0.6 GB/s | 7.8 | + * @note + * - Hashes which require a specific ISA extension are noted. SSE2 is also noted, + * even though it is mandatory on x64. + * - Hashes with an asterisk are cryptographic. Note that MD5 is non-cryptographic + * by modern standards. + * - Small data velocity is a rough average of algorithm's efficiency for small + * data. For more accurate information, see the wiki. + * - More benchmarks and strength tests are found on the wiki: + * https://github.com/Cyan4973/xxHash/wiki + * + * Usage + * ------ + * All xxHash variants use a similar API. Changing the algorithm is a trivial + * substitution. + * + * @pre + * For functions which take an input and length parameter, the following + * requirements are assumed: + * - The range from [`input`, `input + length`) is valid, readable memory. + * - The only exception is if the `length` is `0`, `input` may be `NULL`. + * - For C++, the objects must have the *TriviallyCopyable* property, as the + * functions access bytes directly as if it was an array of `unsigned char`. + * + * @anchor single_shot_example + * **Single Shot** + * + * These functions are stateless functions which hash a contiguous block of memory, + * immediately returning the result. They are the easiest and usually the fastest + * option. + * + * XXH32(), XXH64(), XXH3_64bits(), XXH3_128bits() + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which hashes a null terminated string with XXH32(). + * XXH32_hash_t hash_string(const char* string, XXH32_hash_t seed) + * { + * // NULL pointers are only valid if the length is zero + * size_t length = (string == NULL) ? 0 : strlen(string); + * return XXH32(string, length, seed); + * } + * @endcode + * + * + * @anchor streaming_example + * **Streaming** + * + * These groups of functions allow incremental hashing of unknown size, even + * more than what would fit in a size_t. + * + * XXH32_reset(), XXH64_reset(), XXH3_64bits_reset(), XXH3_128bits_reset() + * + * @code{.c} + * #include + * #include + * #include "xxhash.h" + * // Example for a function which hashes a FILE incrementally with XXH3_64bits(). + * XXH64_hash_t hashFile(FILE* f) + * { + * // Allocate a state struct. Do not just use malloc() or new. + * XXH3_state_t* state = XXH3_createState(); + * assert(state != NULL && "Out of memory!"); + * // Reset the state to start a new hashing session. + * XXH3_64bits_reset(state); + * char buffer[4096]; + * size_t count; + * // Read the file in chunks + * while ((count = fread(buffer, 1, sizeof(buffer), f)) != 0) { + * // Run update() as many times as necessary to process the data + * XXH3_64bits_update(state, buffer, count); + * } + * // Retrieve the finalized hash. This will not change the state. + * XXH64_hash_t result = XXH3_64bits_digest(state); + * // Free the state. Do not use free(). + * XXH3_freeState(state); + * return result; + * } + * @endcode + * + * Streaming functions generate the xxHash value from an incremental input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + * + * + * @anchor canonical_representation_example + * **Canonical Representation** + * + * The default return values from XXH functions are unsigned 32, 64 and 128 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + * + * XXH32_canonicalFromHash(), XXH32_hashFromCanonical(), + * XXH64_canonicalFromHash(), XXH64_hashFromCanonical(), + * XXH128_canonicalFromHash(), XXH128_hashFromCanonical(), + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which prints XXH32_hash_t in human readable format + * void printXxh32(XXH32_hash_t hash) + * { + * XXH32_canonical_t cano; + * XXH32_canonicalFromHash(&cano, hash); + * size_t i; + * for(i = 0; i < sizeof(cano.digest); ++i) { + * printf("%02x", cano.digest[i]); + * } + * printf("\n"); + * } + * + * // Example for a function which converts XXH32_canonical_t to XXH32_hash_t + * XXH32_hash_t convertCanonicalToXxh32(XXH32_canonical_t cano) + * { + * XXH32_hash_t hash = XXH32_hashFromCanonical(&cano); + * return hash; + * } + * @endcode + * + * + * @file xxhash.h + * xxHash prototypes and implementation + */ + +/* **************************** + * INLINE mode + ******************************/ +/*! + * @defgroup public Public API + * Contains details on the public xxHash functions. + * @{ + */ +#ifdef XXH_DOXYGEN +/*! + * @brief Gives access to internal state declaration, required for static allocation. + * + * Incompatible with dynamic linking, due to risks of ABI changes. + * + * Usage: + * @code{.c} + * #define XXH_STATIC_LINKING_ONLY + * #include "xxhash.h" + * @endcode + */ +# define XXH_STATIC_LINKING_ONLY +/* Do not undef XXH_STATIC_LINKING_ONLY for Doxygen */ + +/*! + * @brief Gives access to internal definitions. + * + * Usage: + * @code{.c} + * #define XXH_STATIC_LINKING_ONLY + * #define XXH_IMPLEMENTATION + * #include "xxhash.h" + * @endcode + */ +# define XXH_IMPLEMENTATION +/* Do not undef XXH_IMPLEMENTATION for Doxygen */ + +/*! + * @brief Exposes the implementation and marks all functions as `inline`. + * + * Use these build macros to inline xxhash into the target unit. + * Inlining improves performance on small inputs, especially when the length is + * expressed as a compile-time constant: + * + * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html + * + * It also keeps xxHash symbols private to the unit, so they are not exported. + * + * Usage: + * @code{.c} + * #define XXH_INLINE_ALL + * #include "xxhash.h" + * @endcode + * Do not compile and link xxhash.o as a separate object, as it is not useful. + */ +# define XXH_INLINE_ALL +# undef XXH_INLINE_ALL +/*! + * @brief Exposes the implementation without marking functions as inline. + */ +# define XXH_PRIVATE_API +# undef XXH_PRIVATE_API +/*! + * @brief Emulate a namespace by transparently prefixing all symbols. + * + * If you want to include _and expose_ xxHash functions from within your own + * library, but also want to avoid symbol collisions with other libraries which + * may also include xxHash, you can use @ref XXH_NAMESPACE to automatically prefix + * any public symbol from xxhash library with the value of @ref XXH_NAMESPACE + * (therefore, avoid empty or numeric values). + * + * Note that no change is required within the calling program as long as it + * includes `xxhash.h`: Regular symbol names will be automatically translated + * by this header. + */ +# define XXH_NAMESPACE /* YOUR NAME HERE */ +# undef XXH_NAMESPACE +#endif + +#if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \ + && !defined(XXH_INLINE_ALL_31684351384) + /* this section should be traversed only once */ +# define XXH_INLINE_ALL_31684351384 + /* give access to the advanced API, required to compile implementations */ +# undef XXH_STATIC_LINKING_ONLY /* avoid macro redef */ +# define XXH_STATIC_LINKING_ONLY + /* make all functions private */ +# undef XXH_PUBLIC_API +# if defined(__GNUC__) +# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define XXH_PUBLIC_API static inline +# elif defined(_MSC_VER) +# define XXH_PUBLIC_API static __inline +# else + /* note: this version may generate warnings for unused static functions */ +# define XXH_PUBLIC_API static +# endif + + /* + * This part deals with the special case where a unit wants to inline xxHash, + * but "xxhash.h" has previously been included without XXH_INLINE_ALL, + * such as part of some previously included *.h header file. + * Without further action, the new include would just be ignored, + * and functions would effectively _not_ be inlined (silent failure). + * The following macros solve this situation by prefixing all inlined names, + * avoiding naming collision with previous inclusions. + */ + /* Before that, we unconditionally #undef all symbols, + * in case they were already defined with XXH_NAMESPACE. + * They will then be redefined for XXH_INLINE_ALL + */ +# undef XXH_versionNumber + /* XXH32 */ +# undef XXH32 +# undef XXH32_createState +# undef XXH32_freeState +# undef XXH32_reset +# undef XXH32_update +# undef XXH32_digest +# undef XXH32_copyState +# undef XXH32_canonicalFromHash +# undef XXH32_hashFromCanonical + /* XXH64 */ +# undef XXH64 +# undef XXH64_createState +# undef XXH64_freeState +# undef XXH64_reset +# undef XXH64_update +# undef XXH64_digest +# undef XXH64_copyState +# undef XXH64_canonicalFromHash +# undef XXH64_hashFromCanonical + /* XXH3_64bits */ +# undef XXH3_64bits +# undef XXH3_64bits_withSecret +# undef XXH3_64bits_withSeed +# undef XXH3_64bits_withSecretandSeed +# undef XXH3_createState +# undef XXH3_freeState +# undef XXH3_copyState +# undef XXH3_64bits_reset +# undef XXH3_64bits_reset_withSeed +# undef XXH3_64bits_reset_withSecret +# undef XXH3_64bits_update +# undef XXH3_64bits_digest +# undef XXH3_generateSecret + /* XXH3_128bits */ +# undef XXH128 +# undef XXH3_128bits +# undef XXH3_128bits_withSeed +# undef XXH3_128bits_withSecret +# undef XXH3_128bits_reset +# undef XXH3_128bits_reset_withSeed +# undef XXH3_128bits_reset_withSecret +# undef XXH3_128bits_reset_withSecretandSeed +# undef XXH3_128bits_update +# undef XXH3_128bits_digest +# undef XXH128_isEqual +# undef XXH128_cmp +# undef XXH128_canonicalFromHash +# undef XXH128_hashFromCanonical + /* Finally, free the namespace itself */ +# undef XXH_NAMESPACE + + /* employ the namespace for XXH_INLINE_ALL */ +# define XXH_NAMESPACE XXH_INLINE_ + /* + * Some identifiers (enums, type names) are not symbols, + * but they must nonetheless be renamed to avoid redeclaration. + * Alternative solution: do not redeclare them. + * However, this requires some #ifdefs, and has a more dispersed impact. + * Meanwhile, renaming can be achieved in a single place. + */ +# define XXH_IPREF(Id) XXH_NAMESPACE ## Id +# define XXH_OK XXH_IPREF(XXH_OK) +# define XXH_ERROR XXH_IPREF(XXH_ERROR) +# define XXH_errorcode XXH_IPREF(XXH_errorcode) +# define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t) +# define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t) +# define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t) +# define XXH32_state_s XXH_IPREF(XXH32_state_s) +# define XXH32_state_t XXH_IPREF(XXH32_state_t) +# define XXH64_state_s XXH_IPREF(XXH64_state_s) +# define XXH64_state_t XXH_IPREF(XXH64_state_t) +# define XXH3_state_s XXH_IPREF(XXH3_state_s) +# define XXH3_state_t XXH_IPREF(XXH3_state_t) +# define XXH128_hash_t XXH_IPREF(XXH128_hash_t) + /* Ensure the header is parsed again, even if it was previously included */ +# undef XXHASH_H_5627135585666179 +# undef XXHASH_H_STATIC_13879238742 +#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ + +/* **************************************************************** + * Stable API + *****************************************************************/ +#ifndef XXHASH_H_5627135585666179 +#define XXHASH_H_5627135585666179 1 + +/*! @brief Marks a global symbol. */ +#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) +# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# ifdef XXH_EXPORT +# define XXH_PUBLIC_API __declspec(dllexport) +# elif XXH_IMPORT +# define XXH_PUBLIC_API __declspec(dllimport) +# endif +# else +# define XXH_PUBLIC_API /* do nothing */ +# endif +#endif + +#ifdef XXH_NAMESPACE +# define XXH_CAT(A,B) A##B +# define XXH_NAME2(A,B) XXH_CAT(A,B) +# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) +/* XXH32 */ +# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) +# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) +# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) +# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) +# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) +# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) +# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) +# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) +# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) +/* XXH64 */ +# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) +# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) +# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) +# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) +# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) +# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) +# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) +# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) +# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) +/* XXH3_64bits */ +# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits) +# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret) +# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed) +# define XXH3_64bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecretandSeed) +# define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState) +# define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState) +# define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState) +# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset) +# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed) +# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret) +# define XXH3_64bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecretandSeed) +# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update) +# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest) +# define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret) +# define XXH3_generateSecret_fromSeed XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret_fromSeed) +/* XXH3_128bits */ +# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128) +# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits) +# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed) +# define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret) +# define XXH3_128bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecretandSeed) +# define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset) +# define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed) +# define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret) +# define XXH3_128bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecretandSeed) +# define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update) +# define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest) +# define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual) +# define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp) +# define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash) +# define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical) +#endif + + +/* ************************************* +* Compiler specifics +***************************************/ + +/* specific declaration modes for Windows */ +#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) +# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# ifdef XXH_EXPORT +# define XXH_PUBLIC_API __declspec(dllexport) +# elif XXH_IMPORT +# define XXH_PUBLIC_API __declspec(dllimport) +# endif +# else +# define XXH_PUBLIC_API /* do nothing */ +# endif +#endif + +#if defined (__GNUC__) +# define XXH_CONSTF __attribute__((const)) +# define XXH_PUREF __attribute__((pure)) +# define XXH_MALLOCF __attribute__((malloc)) +#else +# define XXH_CONSTF /* disable */ +# define XXH_PUREF +# define XXH_MALLOCF +#endif + +/* ************************************* +* Version +***************************************/ +#define XXH_VERSION_MAJOR 0 +#define XXH_VERSION_MINOR 8 +#define XXH_VERSION_RELEASE 2 +/*! @brief Version number, encoded as two digits each */ +#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) + +#if defined (__cplusplus) +extern "C" { +#endif +/*! + * @brief Obtains the xxHash version. + * + * This is mostly useful when xxHash is compiled as a shared library, + * since the returned value comes from the library, as opposed to header file. + * + * @return @ref XXH_VERSION_NUMBER of the invoked library. + */ +XXH_PUBLIC_API XXH_CONSTF unsigned XXH_versionNumber (void); + +#if defined (__cplusplus) +} +#endif + +/* **************************** +* Common basic types +******************************/ +#include /* size_t */ +/*! + * @brief Exit code for the streaming API. + */ +typedef enum { + XXH_OK = 0, /*!< OK */ + XXH_ERROR /*!< Error */ +} XXH_errorcode; + + +/*-********************************************************************** +* 32-bit hash +************************************************************************/ +#if defined(XXH_DOXYGEN) /* Don't show include */ +/*! + * @brief An unsigned 32-bit integer. + * + * Not necessarily defined to `uint32_t` but functionally equivalent. + */ +typedef uint32_t XXH32_hash_t; + +#elif !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# ifdef _AIX +# include +# else +# include +# endif + typedef uint32_t XXH32_hash_t; + +#else +# include +# if UINT_MAX == 0xFFFFFFFFUL + typedef unsigned int XXH32_hash_t; +# elif ULONG_MAX == 0xFFFFFFFFUL + typedef unsigned long XXH32_hash_t; +# else +# error "unsupported platform: need a 32-bit type" +# endif +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + +/*! + * @} + * + * @defgroup XXH32_family XXH32 family + * @ingroup public + * Contains functions used in the classic 32-bit xxHash algorithm. + * + * @note + * XXH32 is useful for older platforms, with no or poor 64-bit performance. + * Note that the @ref XXH3_family provides competitive speed for both 32-bit + * and 64-bit systems, and offers true 64/128 bit hash results. + * + * @see @ref XXH64_family, @ref XXH3_family : Other xxHash families + * @see @ref XXH32_impl for implementation details + * @{ + */ + +/*! + * @brief Calculates the 32-bit hash of @p input using xxHash32. + * + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 32-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 32-bit xxHash32 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); + +#ifndef XXH_NO_STREAM +/*! + * @typedef struct XXH32_state_s XXH32_state_t + * @brief The opaque state struct for the XXH32 streaming API. + * + * @see XXH32_state_s for details. + */ +typedef struct XXH32_state_s XXH32_state_t; + +/*! + * @brief Allocates an @ref XXH32_state_t. + * + * @return An allocated pointer of @ref XXH32_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH32_freeState(). + */ +XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void); +/*! + * @brief Frees an @ref XXH32_state_t. + * + * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState(). + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH32_createState(). + * + */ +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); +/*! + * @brief Copies one @ref XXH32_state_t to another. + * + * @param dst_state The state to copy to. + * @param src_state The state to copy from. + * @pre + * @p dst_state and @p src_state must not be `NULL` and must not overlap. + */ +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state); + +/*! + * @brief Resets an @ref XXH32_state_t to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param seed The 32-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH32_update(). + */ +XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); + +/*! + * @brief Consumes a block of @p input to an @ref XXH32_state_t. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + */ +XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); + +/*! + * @brief Returns the calculated hash value from an @ref XXH32_state_t. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated 32-bit xxHash32 value from that state. + * + * @note + * Calling XXH32_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + */ +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ + +/******* Canonical representation *******/ + +/*! + * @brief Canonical (big endian) representation of @ref XXH32_hash_t. + */ +typedef struct { + unsigned char digest[4]; /*!< Hash bytes, big endian */ +} XXH32_canonical_t; + +/*! + * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t. + * + * @param dst The @ref XXH32_canonical_t pointer to be stored to. + * @param hash The @ref XXH32_hash_t to be converted. + * + * @pre + * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); + +/*! + * @brief Converts an @ref XXH32_canonical_t to a native @ref XXH32_hash_t. + * + * @param src The @ref XXH32_canonical_t to convert. + * + * @pre + * @p src must not be `NULL`. + * + * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); + + +/*! @cond Doxygen ignores this part */ +#ifdef __has_attribute +# define XXH_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +# define XXH_HAS_ATTRIBUTE(x) 0 +#endif +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ +/* + * C23 __STDC_VERSION__ number hasn't been specified yet. For now + * leave as `201711L` (C17 + 1). + * TODO: Update to correct value when its been specified. + */ +#define XXH_C23_VN 201711L +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ +/* C-language Attributes are added in C23. */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= XXH_C23_VN) && defined(__has_c_attribute) +# define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) +#else +# define XXH_HAS_C_ATTRIBUTE(x) 0 +#endif +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ +#if defined(__cplusplus) && defined(__has_cpp_attribute) +# define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define XXH_HAS_CPP_ATTRIBUTE(x) 0 +#endif +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ +/* + * Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute + * introduced in CPP17 and C23. + * CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough + * C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough + */ +#if XXH_HAS_C_ATTRIBUTE(fallthrough) || XXH_HAS_CPP_ATTRIBUTE(fallthrough) +# define XXH_FALLTHROUGH [[fallthrough]] +#elif XXH_HAS_ATTRIBUTE(__fallthrough__) +# define XXH_FALLTHROUGH __attribute__ ((__fallthrough__)) +#else +# define XXH_FALLTHROUGH /* fallthrough */ +#endif +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ +/* + * Define XXH_NOESCAPE for annotated pointers in public API. + * https://clang.llvm.org/docs/AttributeReference.html#noescape + * As of writing this, only supported by clang. + */ +#if XXH_HAS_ATTRIBUTE(noescape) +# define XXH_NOESCAPE __attribute__((noescape)) +#else +# define XXH_NOESCAPE +#endif +/*! @endcond */ + +#if defined (__cplusplus) +} /* end of extern "C" */ +#endif + +/*! + * @} + * @ingroup public + * @{ + */ + +#ifndef XXH_NO_LONG_LONG +/*-********************************************************************** +* 64-bit hash +************************************************************************/ +#if defined(XXH_DOXYGEN) /* don't include */ +/*! + * @brief An unsigned 64-bit integer. + * + * Not necessarily defined to `uint64_t` but functionally equivalent. + */ +typedef uint64_t XXH64_hash_t; +#elif !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# ifdef _AIX +# include +# else +# include +# endif + typedef uint64_t XXH64_hash_t; +#else +# include +# if defined(__LP64__) && ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL + /* LP64 ABI says uint64_t is unsigned long */ + typedef unsigned long XXH64_hash_t; +# else + /* the following type must have a width of 64-bit */ + typedef unsigned long long XXH64_hash_t; +# endif +#endif + +#if defined (__cplusplus) +extern "C" { +#endif +/*! + * @} + * + * @defgroup XXH64_family XXH64 family + * @ingroup public + * @{ + * Contains functions used in the classic 64-bit xxHash algorithm. + * + * @note + * XXH3 provides competitive speed for both 32-bit and 64-bit systems, + * and offers true 64/128 bit hash results. + * It provides better speed for systems with vector processing capabilities. + */ + +/*! + * @brief Calculates the 64-bit hash of @p input using xxHash64. + * + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit xxHash64 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); + +/******* Streaming *******/ +#ifndef XXH_NO_STREAM +/*! + * @brief The opaque state struct for the XXH64 streaming API. + * + * @see XXH64_state_s for details. + */ +typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ + +/*! + * @brief Allocates an @ref XXH64_state_t. + * + * @return An allocated pointer of @ref XXH64_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH64_freeState(). + */ +XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void); + +/*! + * @brief Frees an @ref XXH64_state_t. + * + * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState(). + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH64_createState(). + */ +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); + +/*! + * @brief Copies one @ref XXH64_state_t to another. + * + * @param dst_state The state to copy to. + * @param src_state The state to copy from. + * @pre + * @p dst_state and @p src_state must not be `NULL` and must not overlap. + */ +XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const XXH64_state_t* src_state); + +/*! + * @brief Resets an @ref XXH64_state_t to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH64_update(). + */ +XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed); + +/*! + * @brief Consumes a block of @p input to an @ref XXH64_state_t. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + */ +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Returns the calculated hash value from an @ref XXH64_state_t. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated 64-bit xxHash64 value from that state. + * + * @note + * Calling XXH64_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ +/******* Canonical representation *******/ + +/*! + * @brief Canonical (big endian) representation of @ref XXH64_hash_t. + */ +typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t; + +/*! + * @brief Converts an @ref XXH64_hash_t to a big endian @ref XXH64_canonical_t. + * + * @param dst The @ref XXH64_canonical_t pointer to be stored to. + * @param hash The @ref XXH64_hash_t to be converted. + * + * @pre + * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash); + +/*! + * @brief Converts an @ref XXH64_canonical_t to a native @ref XXH64_hash_t. + * + * @param src The @ref XXH64_canonical_t to convert. + * + * @pre + * @p src must not be `NULL`. + * + * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src); + +#ifndef XXH_NO_XXH3 + +/*! + * @} + * ************************************************************************ + * @defgroup XXH3_family XXH3 family + * @ingroup public + * @{ + * + * XXH3 is a more recent hash algorithm featuring: + * - Improved speed for both small and large inputs + * - True 64-bit and 128-bit outputs + * - SIMD acceleration + * - Improved 32-bit viability + * + * Speed analysis methodology is explained here: + * + * https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html + * + * Compared to XXH64, expect XXH3 to run approximately + * ~2x faster on large inputs and >3x faster on small ones, + * exact differences vary depending on platform. + * + * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic, + * but does not require it. + * Most 32-bit and 64-bit targets that can run XXH32 smoothly can run XXH3 + * at competitive speeds, even without vector support. Further details are + * explained in the implementation. + * + * XXH3 has a fast scalar implementation, but it also includes accelerated SIMD + * implementations for many common platforms: + * - AVX512 + * - AVX2 + * - SSE2 + * - ARM NEON + * - WebAssembly SIMD128 + * - POWER8 VSX + * - s390x ZVector + * This can be controlled via the @ref XXH_VECTOR macro, but it automatically + * selects the best version according to predefined macros. For the x86 family, an + * automatic runtime dispatcher is included separately in @ref xxh_x86dispatch.c. + * + * XXH3 implementation is portable: + * it has a generic C90 formulation that can be compiled on any platform, + * all implementations generate exactly the same hash value on all platforms. + * Starting from v0.8.0, it's also labelled "stable", meaning that + * any future version will also generate the same hash value. + * + * XXH3 offers 2 variants, _64bits and _128bits. + * + * When only 64 bits are needed, prefer invoking the _64bits variant, as it + * reduces the amount of mixing, resulting in faster speed on small inputs. + * It's also generally simpler to manipulate a scalar return type than a struct. + * + * The API supports one-shot hashing, streaming mode, and custom secrets. + */ +/*-********************************************************************** +* XXH3 64-bit variant +************************************************************************/ + +/*! + * @brief Calculates 64-bit unseeded variant of XXH3 hash of @p input. + * + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. + * + * @see + * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Calculates 64-bit seeded variant of XXH3 hash of @p input. + * + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); + +/*! + * The bare minimum size for a custom secret. + * + * @see + * XXH3_64bits_withSecret(), XXH3_64bits_reset_withSecret(), + * XXH3_128bits_withSecret(), XXH3_128bits_reset_withSecret(). + */ +#define XXH3_SECRET_SIZE_MIN 136 + +/*! + * @brief Calculates 64-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing @ref XXH3_generateSecret() instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); + + +/******* Streaming *******/ +#ifndef XXH_NO_STREAM +/* + * Streaming requires state maintenance. + * This operation costs memory and CPU. + * As a consequence, streaming is slower than one-shot hashing. + * For better performance, prefer one-shot functions whenever applicable. + */ + +/*! + * @brief The opaque state struct for the XXH3 streaming API. + * + * @see XXH3_state_s for details. + */ +typedef struct XXH3_state_s XXH3_state_t; +XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr); + +/*! + * @brief Copies one @ref XXH3_state_t to another. + * + * @param dst_state The state to copy to. + * @param src_state The state to copy from. + * @pre + * @p dst_state and @p src_state must not be `NULL` and must not overlap. + */ +XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOESCAPE const XXH3_state_t* src_state); + +/*! + * @brief Resets an @ref XXH3_state_t to begin a new hash. + * + * @param statePtr The state struct to reset. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits()`. + * + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); + +/*! + * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits_withSeed()`. + * + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); + +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * `secret` is referenced, it _must outlive_ the hash streaming session. + * + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); + +/*! + * @brief Consumes a block of @p input to an @ref XXH3_state_t. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated XXH3 64-bit hash value from that state. + * + * @note + * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ + +/* note : canonical representation of XXH3 is the same as XXH64 + * since they both produce XXH64_hash_t values */ + + +/*-********************************************************************** +* XXH3 128-bit variant +************************************************************************/ + +/*! + * @brief The return value from 128-bit hashes. + * + * Stored in little endian order, although the fields themselves are in native + * endianness. + */ +typedef struct { + XXH64_hash_t low64; /*!< `value & 0xFFFFFFFFFFFFFFFF` */ + XXH64_hash_t high64; /*!< `value >> 64` */ +} XXH128_hash_t; + +/*! + * @brief Calculates 128-bit unseeded variant of XXH3 of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead + * for shorter inputs. + * + * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. + * + * @see XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len); +/*! @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see XXH3_128bits(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); +/*! + * @brief Calculates 128-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing @ref XXH3_generateSecret() instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); + +/******* Streaming *******/ +#ifndef XXH_NO_STREAM +/* + * Streaming requires state maintenance. + * This operation costs memory and CPU. + * As a consequence, streaming is slower than one-shot hashing. + * For better performance, prefer one-shot functions whenever applicable. + * + * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits(). + * Use already declared XXH3_createState() and XXH3_freeState(). + * + * All reset and streaming functions have same meaning as their 64-bit counterpart. + */ + +/*! + * @brief Resets an @ref XXH3_state_t to begin a new hash. + * + * @param statePtr The state struct to reset. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits()`. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); + +/*! + * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits_withSeed()`. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); + +/*! + * @brief Consumes a block of @p input to an @ref XXH3_state_t. + * + * Call this to incrementally consume blocks of data. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated XXH3 128-bit hash value from that state. + * + * @note + * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ + +/* Following helper functions make it possible to compare XXH128_hast_t values. + * Since XXH128_hash_t is a structure, this capability is not offered by the language. + * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ + +/*! + * @brief Check equality of two XXH128_hash_t values + * + * @param h1 The 128-bit hash value. + * @param h2 Another 128-bit hash value. + * + * @return `1` if `h1` and `h2` are equal. + * @return `0` if they are not. + */ +XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); + +/*! + * @brief Compares two @ref XXH128_hash_t + * + * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. + * + * @param h128_1 Left-hand side value + * @param h128_2 Right-hand side value + * + * @return >0 if @p h128_1 > @p h128_2 + * @return =0 if @p h128_1 == @p h128_2 + * @return <0 if @p h128_1 < @p h128_2 + */ +XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2); + + +/******* Canonical representation *******/ +typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t; + + +/*! + * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t. + * + * @param dst The @ref XXH128_canonical_t pointer to be stored to. + * @param hash The @ref XXH128_hash_t to be converted. + * + * @pre + * @p dst must not be `NULL`. + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash); + +/*! + * @brief Converts an @ref XXH128_canonical_t to a native @ref XXH128_hash_t. + * + * @param src The @ref XXH128_canonical_t to convert. + * + * @pre + * @p src must not be `NULL`. + * + * @return The converted hash. + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src); + + +#endif /* !XXH_NO_XXH3 */ + +#if defined (__cplusplus) +} /* extern "C" */ +#endif + +#endif /* XXH_NO_LONG_LONG */ + +/*! + * @} + */ +#endif /* XXHASH_H_5627135585666179 */ + + + +#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) +#define XXHASH_H_STATIC_13879238742 +/* **************************************************************************** + * This section contains declarations which are not guaranteed to remain stable. + * They may change in future versions, becoming incompatible with a different + * version of the library. + * These declarations should only be used with static linking. + * Never use them in association with dynamic linking! + ***************************************************************************** */ + +/* + * These definitions are only present to allow static allocation + * of XXH states, on stack or in a struct, for example. + * Never **ever** access their members directly. + */ + +/*! + * @internal + * @brief Structure for XXH32 streaming API. + * + * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY, + * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is + * an opaque type. This allows fields to safely be changed. + * + * Typedef'd to @ref XXH32_state_t. + * Do not access the members of this struct directly. + * @see XXH64_state_s, XXH3_state_s + */ +struct XXH32_state_s { + XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */ + XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */ + XXH32_hash_t v[4]; /*!< Accumulator lanes */ + XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */ + XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */ + XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */ +}; /* typedef'd to XXH32_state_t */ + + +#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */ + +/*! + * @internal + * @brief Structure for XXH64 streaming API. + * + * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY, + * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is + * an opaque type. This allows fields to safely be changed. + * + * Typedef'd to @ref XXH64_state_t. + * Do not access the members of this struct directly. + * @see XXH32_state_s, XXH3_state_s + */ +struct XXH64_state_s { + XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */ + XXH64_hash_t v[4]; /*!< Accumulator lanes */ + XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */ + XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */ + XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/ + XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ +}; /* typedef'd to XXH64_state_t */ + +#ifndef XXH_NO_XXH3 + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ +# include +# define XXH_ALIGN(n) alignas(n) +#elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */ +/* In C++ alignas() is a keyword */ +# define XXH_ALIGN(n) alignas(n) +#elif defined(__GNUC__) +# define XXH_ALIGN(n) __attribute__ ((aligned(n))) +#elif defined(_MSC_VER) +# define XXH_ALIGN(n) __declspec(align(n)) +#else +# define XXH_ALIGN(n) /* disabled */ +#endif + +/* Old GCC versions only accept the attribute after the type in structures. */ +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \ + && ! (defined(__cplusplus) && (__cplusplus >= 201103L)) /* >= C++11 */ \ + && defined(__GNUC__) +# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align) +#else +# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type +#endif + +/*! + * @brief The size of the internal XXH3 buffer. + * + * This is the optimal update size for incremental hashing. + * + * @see XXH3_64b_update(), XXH3_128b_update(). + */ +#define XXH3_INTERNALBUFFER_SIZE 256 + +/*! + * @internal + * @brief Default size of the secret buffer (and @ref XXH3_kSecret). + * + * This is the size used in @ref XXH3_kSecret and the seeded functions. + * + * Not to be confused with @ref XXH3_SECRET_SIZE_MIN. + */ +#define XXH3_SECRET_DEFAULT_SIZE 192 + +/*! + * @internal + * @brief Structure for XXH3 streaming API. + * + * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY, + * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. + * Otherwise it is an opaque type. + * Never use this definition in combination with dynamic library. + * This allows fields to safely be changed in the future. + * + * @note ** This structure has a strict alignment requirement of 64 bytes!! ** + * Do not allocate this with `malloc()` or `new`, + * it will not be sufficiently aligned. + * Use @ref XXH3_createState() and @ref XXH3_freeState(), or stack allocation. + * + * Typedef'd to @ref XXH3_state_t. + * Do never access the members of this struct directly. + * + * @see XXH3_INITSTATE() for stack initialization. + * @see XXH3_createState(), XXH3_freeState(). + * @see XXH32_state_s, XXH64_state_s + */ +struct XXH3_state_s { + XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]); + /*!< The 8 accumulators. See @ref XXH32_state_s::v and @ref XXH64_state_s::v */ + XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]); + /*!< Used to store a custom secret generated from a seed. */ + XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]); + /*!< The internal buffer. @see XXH32_state_s::mem32 */ + XXH32_hash_t bufferedSize; + /*!< The amount of memory in @ref buffer, @see XXH32_state_s::memsize */ + XXH32_hash_t useSeed; + /*!< Reserved field. Needed for padding on 64-bit. */ + size_t nbStripesSoFar; + /*!< Number or stripes processed. */ + XXH64_hash_t totalLen; + /*!< Total length hashed. 64-bit even on 32-bit targets. */ + size_t nbStripesPerBlock; + /*!< Number of stripes per block. */ + size_t secretLimit; + /*!< Size of @ref customSecret or @ref extSecret */ + XXH64_hash_t seed; + /*!< Seed for _withSeed variants. Must be zero otherwise, @see XXH3_INITSTATE() */ + XXH64_hash_t reserved64; + /*!< Reserved field. */ + const unsigned char* extSecret; + /*!< Reference to an external secret for the _withSecret variants, NULL + * for other variants. */ + /* note: there may be some padding at the end due to alignment on 64 bytes */ +}; /* typedef'd to XXH3_state_t */ + +#undef XXH_ALIGN_MEMBER + +/*! + * @brief Initializes a stack-allocated `XXH3_state_s`. + * + * When the @ref XXH3_state_t structure is merely emplaced on stack, + * it should be initialized with XXH3_INITSTATE() or a memset() + * in case its first reset uses XXH3_NNbits_reset_withSeed(). + * This init can be omitted if the first reset uses default or _withSecret mode. + * This operation isn't necessary when the state is created with XXH3_createState(). + * Note that this doesn't prepare the state for a streaming operation, + * it's still necessary to use XXH3_NNbits_reset*() afterwards. + */ +#define XXH3_INITSTATE(XXH3_state_ptr) \ + do { \ + XXH3_state_t* tmp_xxh3_state_ptr = (XXH3_state_ptr); \ + tmp_xxh3_state_ptr->seed = 0; \ + tmp_xxh3_state_ptr->extSecret = NULL; \ + } while(0) + + +#if defined (__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calculates the 128-bit hash of @p data using XXH3. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p len is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 128-bit XXH3 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); + + +/* === Experimental API === */ +/* Symbols defined below must be considered tied to a specific library version. */ + +/*! + * @brief Derive a high-entropy secret from any user-defined content, named customSeed. + * + * @param secretBuffer A writable buffer for derived high-entropy secret data. + * @param secretSize Size of secretBuffer, in bytes. Must be >= XXH3_SECRET_DEFAULT_SIZE. + * @param customSeed A user-defined content. + * @param customSeedSize Size of customSeed, in bytes. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * The generated secret can be used in combination with `*_withSecret()` functions. + * The `_withSecret()` variants are useful to provide a higher level of protection + * than 64-bit seed, as it becomes much more difficult for an external actor to + * guess how to impact the calculation logic. + * + * The function accepts as input a custom seed of any length and any content, + * and derives from it a high-entropy secret of length @p secretSize into an + * already allocated buffer @p secretBuffer. + * + * The generated secret can then be used with any `*_withSecret()` variant. + * The functions @ref XXH3_128bits_withSecret(), @ref XXH3_64bits_withSecret(), + * @ref XXH3_128bits_reset_withSecret() and @ref XXH3_64bits_reset_withSecret() + * are part of this list. They all accept a `secret` parameter + * which must be large enough for implementation reasons (>= @ref XXH3_SECRET_SIZE_MIN) + * _and_ feature very high entropy (consist of random-looking bytes). + * These conditions can be a high bar to meet, so @ref XXH3_generateSecret() can + * be employed to ensure proper quality. + * + * @p customSeed can be anything. It can have any size, even small ones, + * and its content can be anything, even "poor entropy" sources such as a bunch + * of zeroes. The resulting `secret` will nonetheless provide all required qualities. + * + * @pre + * - @p secretSize must be >= @ref XXH3_SECRET_SIZE_MIN + * - When @p customSeedSize > 0, supplying NULL as customSeed is undefined behavior. + * + * Example code: + * @code{.c} + * #include + * #include + * #include + * #define XXH_STATIC_LINKING_ONLY // expose unstable API + * #include "xxhash.h" + * // Hashes argv[2] using the entropy from argv[1]. + * int main(int argc, char* argv[]) + * { + * char secret[XXH3_SECRET_SIZE_MIN]; + * if (argv != 3) { return 1; } + * XXH3_generateSecret(secret, sizeof(secret), argv[1], strlen(argv[1])); + * XXH64_hash_t h = XXH3_64bits_withSecret( + * argv[2], strlen(argv[2]), + * secret, sizeof(secret) + * ); + * printf("%016llx\n", (unsigned long long) h); + * } + * @endcode + */ +XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer, size_t secretSize, XXH_NOESCAPE const void* customSeed, size_t customSeedSize); + +/*! + * @brief Generate the same secret as the _withSeed() variants. + * + * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes + * @param seed The 64-bit seed to alter the hash result predictably. + * + * The generated secret can be used in combination with + *`*_withSecret()` and `_withSecretandSeed()` variants. + * + * Example C++ `std::string` hash class: + * @code{.cpp} + * #include + * #define XXH_STATIC_LINKING_ONLY // expose unstable API + * #include "xxhash.h" + * // Slow, seeds each time + * class HashSlow { + * XXH64_hash_t seed; + * public: + * HashSlow(XXH64_hash_t s) : seed{s} {} + * size_t operator()(const std::string& x) const { + * return size_t{XXH3_64bits_withSeed(x.c_str(), x.length(), seed)}; + * } + * }; + * // Fast, caches the seeded secret for future uses. + * class HashFast { + * unsigned char secret[XXH3_SECRET_SIZE_MIN]; + * public: + * HashFast(XXH64_hash_t s) { + * XXH3_generateSecret_fromSeed(secret, seed); + * } + * size_t operator()(const std::string& x) const { + * return size_t{ + * XXH3_64bits_withSecret(x.c_str(), x.length(), secret, sizeof(secret)) + * }; + * } + * }; + * @endcode + */ +XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed); + +/*! + * @brief Calculates 64/128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * These variants generate hash values using either + * @p seed for "short" keys (< @ref XXH3_MIDSIZE_MAX = 240 bytes) + * or @p secret for "large" keys (>= @ref XXH3_MIDSIZE_MAX). + * + * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. + * `_withSeed()` has to generate the secret on the fly for "large" keys. + * It's fast, but can be perceptible for "not so large" keys (< 1 KB). + * `_withSecret()` has to generate the masks on the fly for "small" keys, + * which requires more instructions than _withSeed() variants. + * Therefore, _withSecretandSeed variant combines the best of both worlds. + * + * When @p secret has been generated by XXH3_generateSecret_fromSeed(), + * this variant produces *exactly* the same results as `_withSeed()` variant, + * hence offering only a pure speed benefit on "large" input, + * by skipping the need to regenerate the secret for every large input. + * + * Another usage scenario is to hash the secret to a 64-bit hash value, + * for example with XXH3_64bits(), which then becomes the seed, + * and then employ both the seed and the secret in _withSecretandSeed(). + * On top of speed, an added benefit is that each bit in the secret + * has a 50% chance to swap each bit in the output, via its impact to the seed. + * + * This is not guaranteed when using the secret directly in "small data" scenarios, + * because only portions of the secret are employed for small data. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t +XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len, + XXH_NOESCAPE const void* secret, size_t secretSize, + XXH64_hash_t seed); +/*! + * @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param input The block of data to be hashed, at least @p len bytes in size. + * @param length The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed() + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t +XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, + XXH_NOESCAPE const void* secret, size_t secretSize, + XXH64_hash_t seed64); +#ifndef XXH_NO_STREAM +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed() + */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, + XXH_NOESCAPE const void* secret, size_t secretSize, + XXH64_hash_t seed64); +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed() + */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, + XXH_NOESCAPE const void* secret, size_t secretSize, + XXH64_hash_t seed64); +#endif /* !XXH_NO_STREAM */ + +#if defined (__cplusplus) +} /* extern "C" */ +#endif + +#endif /* !XXH_NO_XXH3 */ +#endif /* XXH_NO_LONG_LONG */ + +#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) +# define XXH_IMPLEMENTATION +#endif + +#endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */ + + +/* ======================================================================== */ +/* ======================================================================== */ +/* ======================================================================== */ + + +/*-********************************************************************** + * xxHash implementation + *-********************************************************************** + * xxHash's implementation used to be hosted inside xxhash.c. + * + * However, inlining requires implementation to be visible to the compiler, + * hence be included alongside the header. + * Previously, implementation was hosted inside xxhash.c, + * which was then #included when inlining was activated. + * This construction created issues with a few build and install systems, + * as it required xxhash.c to be stored in /include directory. + * + * xxHash implementation is now directly integrated within xxhash.h. + * As a consequence, xxhash.c is no longer needed in /include. + * + * xxhash.c is still available and is still useful. + * In a "normal" setup, when xxhash is not inlined, + * xxhash.h only exposes the prototypes and public symbols, + * while xxhash.c can be built into an object file xxhash.o + * which can then be linked into the final binary. + ************************************************************************/ + +#if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \ + || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387) +# define XXH_IMPLEM_13a8737387 + +/* ************************************* +* Tuning parameters +***************************************/ + +/*! + * @defgroup tuning Tuning parameters + * @{ + * + * Various macros to control xxHash's behavior. + */ +#ifdef XXH_DOXYGEN +/*! + * @brief Define this to disable 64-bit code. + * + * Useful if only using the @ref XXH32_family and you have a strict C90 compiler. + */ +# define XXH_NO_LONG_LONG +# undef XXH_NO_LONG_LONG /* don't actually */ +/*! + * @brief Controls how unaligned memory is accessed. + * + * By default, access to unaligned memory is controlled by `memcpy()`, which is + * safe and portable. + * + * Unfortunately, on some target/compiler combinations, the generated assembly + * is sub-optimal. + * + * The below switch allow selection of a different access method + * in the search for improved performance. + * + * @par Possible options: + * + * - `XXH_FORCE_MEMORY_ACCESS=0` (default): `memcpy` + * @par + * Use `memcpy()`. Safe and portable. Note that most modern compilers will + * eliminate the function call and treat it as an unaligned access. + * + * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((aligned(1)))` + * @par + * Depends on compiler extensions and is therefore not portable. + * This method is safe _if_ your compiler supports it, + * and *generally* as fast or faster than `memcpy`. + * + * - `XXH_FORCE_MEMORY_ACCESS=2`: Direct cast + * @par + * Casts directly and dereferences. This method doesn't depend on the + * compiler, but it violates the C standard as it directly dereferences an + * unaligned pointer. It can generate buggy code on targets which do not + * support unaligned memory accesses, but in some circumstances, it's the + * only known way to get the most performance. + * + * - `XXH_FORCE_MEMORY_ACCESS=3`: Byteshift + * @par + * Also portable. This can generate the best code on old compilers which don't + * inline small `memcpy()` calls, and it might also be faster on big-endian + * systems which lack a native byteswap instruction. However, some compilers + * will emit literal byteshifts even if the target supports unaligned access. + * + * + * @warning + * Methods 1 and 2 rely on implementation-defined behavior. Use these with + * care, as what works on one compiler/platform/optimization level may cause + * another to read garbage data or even crash. + * + * See https://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html for details. + * + * Prefer these methods in priority order (0 > 3 > 1 > 2) + */ +# define XXH_FORCE_MEMORY_ACCESS 0 + +/*! + * @def XXH_SIZE_OPT + * @brief Controls how much xxHash optimizes for size. + * + * xxHash, when compiled, tends to result in a rather large binary size. This + * is mostly due to heavy usage to forced inlining and constant folding of the + * @ref XXH3_family to increase performance. + * + * However, some developers prefer size over speed. This option can + * significantly reduce the size of the generated code. When using the `-Os` + * or `-Oz` options on GCC or Clang, this is defined to 1 by default, + * otherwise it is defined to 0. + * + * Most of these size optimizations can be controlled manually. + * + * This is a number from 0-2. + * - `XXH_SIZE_OPT` == 0: Default. xxHash makes no size optimizations. Speed + * comes first. + * - `XXH_SIZE_OPT` == 1: Default for `-Os` and `-Oz`. xxHash is more + * conservative and disables hacks that increase code size. It implies the + * options @ref XXH_NO_INLINE_HINTS == 1, @ref XXH_FORCE_ALIGN_CHECK == 0, + * and @ref XXH3_NEON_LANES == 8 if they are not already defined. + * - `XXH_SIZE_OPT` == 2: xxHash tries to make itself as small as possible. + * Performance may cry. For example, the single shot functions just use the + * streaming API. + */ +# define XXH_SIZE_OPT 0 + +/*! + * @def XXH_FORCE_ALIGN_CHECK + * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32() + * and XXH64() only). + * + * This is an important performance trick for architectures without decent + * unaligned memory access performance. + * + * It checks for input alignment, and when conditions are met, uses a "fast + * path" employing direct 32-bit/64-bit reads, resulting in _dramatically + * faster_ read speed. + * + * The check costs one initial branch per hash, which is generally negligible, + * but not zero. + * + * Moreover, it's not useful to generate an additional code path if memory + * access uses the same instruction for both aligned and unaligned + * addresses (e.g. x86 and aarch64). + * + * In these cases, the alignment check can be removed by setting this macro to 0. + * Then the code will always use unaligned memory access. + * Align check is automatically disabled on x86, x64, ARM64, and some ARM chips + * which are platforms known to offer good unaligned memory accesses performance. + * + * It is also disabled by default when @ref XXH_SIZE_OPT >= 1. + * + * This option does not affect XXH3 (only XXH32 and XXH64). + */ +# define XXH_FORCE_ALIGN_CHECK 0 + +/*! + * @def XXH_NO_INLINE_HINTS + * @brief When non-zero, sets all functions to `static`. + * + * By default, xxHash tries to force the compiler to inline almost all internal + * functions. + * + * This can usually improve performance due to reduced jumping and improved + * constant folding, but significantly increases the size of the binary which + * might not be favorable. + * + * Additionally, sometimes the forced inlining can be detrimental to performance, + * depending on the architecture. + * + * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the + * compiler full control on whether to inline or not. + * + * When not optimizing (-O0), using `-fno-inline` with GCC or Clang, or if + * @ref XXH_SIZE_OPT >= 1, this will automatically be defined. + */ +# define XXH_NO_INLINE_HINTS 0 + +/*! + * @def XXH3_INLINE_SECRET + * @brief Determines whether to inline the XXH3 withSecret code. + * + * When the secret size is known, the compiler can improve the performance + * of XXH3_64bits_withSecret() and XXH3_128bits_withSecret(). + * + * However, if the secret size is not known, it doesn't have any benefit. This + * happens when xxHash is compiled into a global symbol. Therefore, if + * @ref XXH_INLINE_ALL is *not* defined, this will be defined to 0. + * + * Additionally, this defaults to 0 on GCC 12+, which has an issue with function pointers + * that are *sometimes* force inline on -Og, and it is impossible to automatically + * detect this optimization level. + */ +# define XXH3_INLINE_SECRET 0 + +/*! + * @def XXH32_ENDJMP + * @brief Whether to use a jump for `XXH32_finalize`. + * + * For performance, `XXH32_finalize` uses multiple branches in the finalizer. + * This is generally preferable for performance, + * but depending on exact architecture, a jmp may be preferable. + * + * This setting is only possibly making a difference for very small inputs. + */ +# define XXH32_ENDJMP 0 + +/*! + * @internal + * @brief Redefines old internal names. + * + * For compatibility with code that uses xxHash's internals before the names + * were changed to improve namespacing. There is no other reason to use this. + */ +# define XXH_OLD_NAMES +# undef XXH_OLD_NAMES /* don't actually use, it is ugly. */ + +/*! + * @def XXH_NO_STREAM + * @brief Disables the streaming API. + * + * When xxHash is not inlined and the streaming functions are not used, disabling + * the streaming functions can improve code size significantly, especially with + * the @ref XXH3_family which tends to make constant folded copies of itself. + */ +# define XXH_NO_STREAM +# undef XXH_NO_STREAM /* don't actually */ +#endif /* XXH_DOXYGEN */ +/*! + * @} + */ + +#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ + /* prefer __packed__ structures (method 1) for GCC + * < ARMv7 with unaligned access (e.g. Raspbian armhf) still uses byte shifting, so we use memcpy + * which for some reason does unaligned loads. */ +# if defined(__GNUC__) && !(defined(__ARM_ARCH) && __ARM_ARCH < 7 && defined(__ARM_FEATURE_UNALIGNED)) +# define XXH_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +#ifndef XXH_SIZE_OPT + /* default to 1 for -Os or -Oz */ +# if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE_SIZE__) +# define XXH_SIZE_OPT 1 +# else +# define XXH_SIZE_OPT 0 +# endif +#endif + +#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ + /* don't check on sizeopt, x86, aarch64, or arm when unaligned access is available */ +# if XXH_SIZE_OPT >= 1 || \ + defined(__i386) || defined(__x86_64__) || defined(__aarch64__) || defined(__ARM_FEATURE_UNALIGNED) \ + || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) || defined(_M_ARM) /* visual */ +# define XXH_FORCE_ALIGN_CHECK 0 +# else +# define XXH_FORCE_ALIGN_CHECK 1 +# endif +#endif + +#ifndef XXH_NO_INLINE_HINTS +# if XXH_SIZE_OPT >= 1 || defined(__NO_INLINE__) /* -O0, -fno-inline */ +# define XXH_NO_INLINE_HINTS 1 +# else +# define XXH_NO_INLINE_HINTS 0 +# endif +#endif + +#ifndef XXH3_INLINE_SECRET +# if (defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 12) \ + || !defined(XXH_INLINE_ALL) +# define XXH3_INLINE_SECRET 0 +# else +# define XXH3_INLINE_SECRET 1 +# endif +#endif + +#ifndef XXH32_ENDJMP +/* generally preferable for performance */ +# define XXH32_ENDJMP 0 +#endif + +/*! + * @defgroup impl Implementation + * @{ + */ + +/* ************************************* +* Includes & Memory related functions +***************************************/ +#include /* memcmp, memcpy */ +#include /* ULLONG_MAX */ + +#if defined(XXH_NO_STREAM) +/* nothing */ +#elif defined(XXH_NO_STDLIB) + +/* When requesting to disable any mention of stdlib, + * the library loses the ability to invoked malloc / free. + * In practice, it means that functions like `XXH*_createState()` + * will always fail, and return NULL. + * This flag is useful in situations where + * xxhash.h is integrated into some kernel, embedded or limited environment + * without access to dynamic allocation. + */ + +#if defined (__cplusplus) +extern "C" { +#endif + +static XXH_CONSTF void* XXH_malloc(size_t s) { (void)s; return NULL; } +static void XXH_free(void* p) { (void)p; } + +#if defined (__cplusplus) +} /* extern "C" */ +#endif + +#else + +/* + * Modify the local functions below should you wish to use + * different memory routines for malloc() and free() + */ +#include + +#if defined (__cplusplus) +extern "C" { +#endif +/*! + * @internal + * @brief Modify this function to use a different routine than malloc(). + */ +static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); } + +/*! + * @internal + * @brief Modify this function to use a different routine than free(). + */ +static void XXH_free(void* p) { free(p); } + +#if defined (__cplusplus) +} /* extern "C" */ +#endif + +#endif /* XXH_NO_STDLIB */ + +#if defined (__cplusplus) +extern "C" { +#endif +/*! + * @internal + * @brief Modify this function to use a different routine than memcpy(). + */ +static void* XXH_memcpy(void* dest, const void* src, size_t size) +{ + return memcpy(dest,src,size); +} + +#if defined (__cplusplus) +} /* extern "C" */ +#endif + +/* ************************************* +* Compiler Specific Options +***************************************/ +#ifdef _MSC_VER /* Visual Studio warning fix */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#endif + +#if XXH_NO_INLINE_HINTS /* disable inlining hints */ +# if defined(__GNUC__) || defined(__clang__) +# define XXH_FORCE_INLINE static __attribute__((unused)) +# else +# define XXH_FORCE_INLINE static +# endif +# define XXH_NO_INLINE static +/* enable inlining hints */ +#elif defined(__GNUC__) || defined(__clang__) +# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) +# define XXH_NO_INLINE static __attribute__((noinline)) +#elif defined(_MSC_VER) /* Visual Studio */ +# define XXH_FORCE_INLINE static __forceinline +# define XXH_NO_INLINE static __declspec(noinline) +#elif defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */ +# define XXH_FORCE_INLINE static inline +# define XXH_NO_INLINE static +#else +# define XXH_FORCE_INLINE static +# define XXH_NO_INLINE static +#endif + +#if XXH3_INLINE_SECRET +# define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE +#else +# define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE +#endif + + +/* ************************************* +* Debug +***************************************/ +/*! + * @ingroup tuning + * @def XXH_DEBUGLEVEL + * @brief Sets the debugging level. + * + * XXH_DEBUGLEVEL is expected to be defined externally, typically via the + * compiler's command line options. The value must be a number. + */ +#ifndef XXH_DEBUGLEVEL +# ifdef DEBUGLEVEL /* backwards compat */ +# define XXH_DEBUGLEVEL DEBUGLEVEL +# else +# define XXH_DEBUGLEVEL 0 +# endif +#endif + +#if (XXH_DEBUGLEVEL>=1) +# include /* note: can still be disabled with NDEBUG */ +# define XXH_ASSERT(c) assert(c) +#else +# if defined(__INTEL_COMPILER) +# define XXH_ASSERT(c) XXH_ASSUME((unsigned char) (c)) +# else +# define XXH_ASSERT(c) XXH_ASSUME(c) +# endif +#endif + +/* note: use after variable declarations */ +#ifndef XXH_STATIC_ASSERT +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ +# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { _Static_assert((c),m); } while(0) +# elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */ +# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0) +# else +# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { struct xxh_sa { char x[(c) ? 1 : -1]; }; } while(0) +# endif +# define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c),#c) +#endif + +/*! + * @internal + * @def XXH_COMPILER_GUARD(var) + * @brief Used to prevent unwanted optimizations for @p var. + * + * It uses an empty GCC inline assembly statement with a register constraint + * which forces @p var into a general purpose register (eg eax, ebx, ecx + * on x86) and marks it as modified. + * + * This is used in a few places to avoid unwanted autovectorization (e.g. + * XXH32_round()). All vectorization we want is explicit via intrinsics, + * and _usually_ isn't wanted elsewhere. + * + * We also use it to prevent unwanted constant folding for AArch64 in + * XXH3_initCustomSecret_scalar(). + */ +#if defined(__GNUC__) || defined(__clang__) +# define XXH_COMPILER_GUARD(var) __asm__("" : "+r" (var)) +#else +# define XXH_COMPILER_GUARD(var) ((void)0) +#endif + +/* Specifically for NEON vectors which use the "w" constraint, on + * Clang. */ +#if defined(__clang__) && defined(__ARM_ARCH) && !defined(__wasm__) +# define XXH_COMPILER_GUARD_CLANG_NEON(var) __asm__("" : "+w" (var)) +#else +# define XXH_COMPILER_GUARD_CLANG_NEON(var) ((void)0) +#endif + +/* ************************************* +* Basic Types +***************************************/ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# ifdef _AIX +# include +# else +# include +# endif + typedef uint8_t xxh_u8; +#else + typedef unsigned char xxh_u8; +#endif +typedef XXH32_hash_t xxh_u32; + +#ifdef XXH_OLD_NAMES +# warning "XXH_OLD_NAMES is planned to be removed starting v0.9. If the program depends on it, consider moving away from it by employing newer type names directly" +# define BYTE xxh_u8 +# define U8 xxh_u8 +# define U32 xxh_u32 +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + +/* *** Memory access *** */ + +/*! + * @internal + * @fn xxh_u32 XXH_read32(const void* ptr) + * @brief Reads an unaligned 32-bit integer from @p ptr in native endianness. + * + * Affected by @ref XXH_FORCE_MEMORY_ACCESS. + * + * @param ptr The pointer to read from. + * @return The 32-bit native endian integer from the bytes at @p ptr. + */ + +/*! + * @internal + * @fn xxh_u32 XXH_readLE32(const void* ptr) + * @brief Reads an unaligned 32-bit little endian integer from @p ptr. + * + * Affected by @ref XXH_FORCE_MEMORY_ACCESS. + * + * @param ptr The pointer to read from. + * @return The 32-bit little endian integer from the bytes at @p ptr. + */ + +/*! + * @internal + * @fn xxh_u32 XXH_readBE32(const void* ptr) + * @brief Reads an unaligned 32-bit big endian integer from @p ptr. + * + * Affected by @ref XXH_FORCE_MEMORY_ACCESS. + * + * @param ptr The pointer to read from. + * @return The 32-bit big endian integer from the bytes at @p ptr. + */ + +/*! + * @internal + * @fn xxh_u32 XXH_readLE32_align(const void* ptr, XXH_alignment align) + * @brief Like @ref XXH_readLE32(), but has an option for aligned reads. + * + * Affected by @ref XXH_FORCE_MEMORY_ACCESS. + * Note that when @ref XXH_FORCE_ALIGN_CHECK == 0, the @p align parameter is + * always @ref XXH_alignment::XXH_unaligned. + * + * @param ptr The pointer to read from. + * @param align Whether @p ptr is aligned. + * @pre + * If @p align == @ref XXH_alignment::XXH_aligned, @p ptr must be 4 byte + * aligned. + * @return The 32-bit little endian integer from the bytes at @p ptr. + */ + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) +/* + * Manual byteshift. Best for old compilers which don't inline memcpy. + * We actually directly use XXH_readLE32 and XXH_readBE32. + */ +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* + * Force direct memory access. Only works on CPU which support unaligned memory + * access in hardware. + */ +static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* + * __attribute__((aligned(1))) is supported by gcc and clang. Originally the + * documentation claimed that it only increased the alignment, but actually it + * can decrease it on gcc, clang, and icc: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69502, + * https://gcc.godbolt.org/z/xYez1j67Y. + */ +#ifdef XXH_OLD_NAMES +typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; +#endif +static xxh_u32 XXH_read32(const void* ptr) +{ + typedef __attribute__((aligned(1))) xxh_u32 xxh_unalign32; + return *((const xxh_unalign32*)ptr); +} + +#else + +/* + * Portable and safe solution. Generally efficient. + * see: https://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html + */ +static xxh_u32 XXH_read32(const void* memPtr) +{ + xxh_u32 val; + XXH_memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + + +/* *** Endianness *** */ + +/*! + * @ingroup tuning + * @def XXH_CPU_LITTLE_ENDIAN + * @brief Whether the target is little endian. + * + * Defined to 1 if the target is little endian, or 0 if it is big endian. + * It can be defined externally, for example on the compiler command line. + * + * If it is not defined, + * a runtime check (which is usually constant folded) is used instead. + * + * @note + * This is not necessarily defined to an integer constant. + * + * @see XXH_isLittleEndian() for the runtime check. + */ +#ifndef XXH_CPU_LITTLE_ENDIAN +/* + * Try to detect endianness automatically, to avoid the nonstandard behavior + * in `XXH_isLittleEndian()` + */ +# if defined(_WIN32) /* Windows is always little endian */ \ + || defined(__LITTLE_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +# define XXH_CPU_LITTLE_ENDIAN 1 +# elif defined(__BIG_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define XXH_CPU_LITTLE_ENDIAN 0 +# else +/*! + * @internal + * @brief Runtime check for @ref XXH_CPU_LITTLE_ENDIAN. + * + * Most compilers will constant fold this. + */ +static int XXH_isLittleEndian(void) +{ + /* + * Portable and well-defined behavior. + * Don't use static: it is detrimental to performance. + */ + const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 }; + return one.c[0]; +} +# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian() +# endif +#endif + + + + +/* **************************************** +* Compiler-specific Functions and Macros +******************************************/ +#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +#ifdef __has_builtin +# define XXH_HAS_BUILTIN(x) __has_builtin(x) +#else +# define XXH_HAS_BUILTIN(x) 0 +#endif + + + +/* + * C23 and future versions have standard "unreachable()". + * Once it has been implemented reliably we can add it as an + * additional case: + * + * ``` + * #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= XXH_C23_VN) + * # include + * # ifdef unreachable + * # define XXH_UNREACHABLE() unreachable() + * # endif + * #endif + * ``` + * + * Note C++23 also has std::unreachable() which can be detected + * as follows: + * ``` + * #if defined(__cpp_lib_unreachable) && (__cpp_lib_unreachable >= 202202L) + * # include + * # define XXH_UNREACHABLE() std::unreachable() + * #endif + * ``` + * NB: `__cpp_lib_unreachable` is defined in the `` header. + * We don't use that as including `` in `extern "C"` blocks + * doesn't work on GCC12 + */ + +#if XXH_HAS_BUILTIN(__builtin_unreachable) +# define XXH_UNREACHABLE() __builtin_unreachable() + +#elif defined(_MSC_VER) +# define XXH_UNREACHABLE() __assume(0) + +#else +# define XXH_UNREACHABLE() +#endif + +#if XXH_HAS_BUILTIN(__builtin_assume) +# define XXH_ASSUME(c) __builtin_assume(c) +#else +# define XXH_ASSUME(c) if (!(c)) { XXH_UNREACHABLE(); } +#endif + +/*! + * @internal + * @def XXH_rotl32(x,r) + * @brief 32-bit rotate left. + * + * @param x The 32-bit integer to be rotated. + * @param r The number of bits to rotate. + * @pre + * @p r > 0 && @p r < 32 + * @note + * @p x and @p r may be evaluated multiple times. + * @return The rotated result. + */ +#if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \ + && XXH_HAS_BUILTIN(__builtin_rotateleft64) +# define XXH_rotl32 __builtin_rotateleft32 +# define XXH_rotl64 __builtin_rotateleft64 +/* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ +#elif defined(_MSC_VER) +# define XXH_rotl32(x,r) _rotl(x,r) +# define XXH_rotl64(x,r) _rotl64(x,r) +#else +# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r)))) +#endif + +/*! + * @internal + * @fn xxh_u32 XXH_swap32(xxh_u32 x) + * @brief A 32-bit byteswap. + * + * @param x The 32-bit integer to byteswap. + * @return @p x, byteswapped. + */ +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap32 _byteswap_ulong +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap32 __builtin_bswap32 +#else +static xxh_u32 XXH_swap32 (xxh_u32 x) +{ + return ((x << 24) & 0xff000000 ) | + ((x << 8) & 0x00ff0000 ) | + ((x >> 8) & 0x0000ff00 ) | + ((x >> 24) & 0x000000ff ); +} +#endif + + +/* *************************** +* Memory reads +*****************************/ + +/*! + * @internal + * @brief Enum to indicate whether a pointer is aligned. + */ +typedef enum { + XXH_aligned, /*!< Aligned */ + XXH_unaligned /*!< Possibly unaligned */ +} XXH_alignment; + +/* + * XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. + * + * This is ideal for older compilers which don't inline memcpy. + */ +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) + +XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[0] + | ((xxh_u32)bytePtr[1] << 8) + | ((xxh_u32)bytePtr[2] << 16) + | ((xxh_u32)bytePtr[3] << 24); +} + +XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[3] + | ((xxh_u32)bytePtr[2] << 8) + | ((xxh_u32)bytePtr[1] << 16) + | ((xxh_u32)bytePtr[0] << 24); +} + +#else +XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); +} + +static xxh_u32 XXH_readBE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); +} +#endif + +XXH_FORCE_INLINE xxh_u32 +XXH_readLE32_align(const void* ptr, XXH_alignment align) +{ + if (align==XXH_unaligned) { + return XXH_readLE32(ptr); + } else { + return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr); + } +} + + +/* ************************************* +* Misc +***************************************/ +/*! @ingroup public */ +XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } + + +/* ******************************************************************* +* 32-bit hash functions +*********************************************************************/ +/*! + * @} + * @defgroup XXH32_impl XXH32 implementation + * @ingroup impl + * + * Details on the XXH32 implementation. + * @{ + */ + /* #define instead of static const, to be used as initializers */ +#define XXH_PRIME32_1 0x9E3779B1U /*!< 0b10011110001101110111100110110001 */ +#define XXH_PRIME32_2 0x85EBCA77U /*!< 0b10000101111010111100101001110111 */ +#define XXH_PRIME32_3 0xC2B2AE3DU /*!< 0b11000010101100101010111000111101 */ +#define XXH_PRIME32_4 0x27D4EB2FU /*!< 0b00100111110101001110101100101111 */ +#define XXH_PRIME32_5 0x165667B1U /*!< 0b00010110010101100110011110110001 */ + +#ifdef XXH_OLD_NAMES +# define PRIME32_1 XXH_PRIME32_1 +# define PRIME32_2 XXH_PRIME32_2 +# define PRIME32_3 XXH_PRIME32_3 +# define PRIME32_4 XXH_PRIME32_4 +# define PRIME32_5 XXH_PRIME32_5 +#endif + +/*! + * @internal + * @brief Normal stripe processing routine. + * + * This shuffles the bits so that any bit from @p input impacts several bits in + * @p acc. + * + * @param acc The accumulator lane. + * @param input The stripe of input to mix. + * @return The mixed accumulator lane. + */ +static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) +{ + acc += input * XXH_PRIME32_2; + acc = XXH_rotl32(acc, 13); + acc *= XXH_PRIME32_1; +#if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * UGLY HACK: + * A compiler fence is the only thing that prevents GCC and Clang from + * autovectorizing the XXH32 loop (pragmas and attributes don't work for some + * reason) without globally disabling SSE4.1. + * + * The reason we want to avoid vectorization is because despite working on + * 4 integers at a time, there are multiple factors slowing XXH32 down on + * SSE4: + * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on + * newer chips!) making it slightly slower to multiply four integers at + * once compared to four integers independently. Even when pmulld was + * fastest, Sandy/Ivy Bridge, it is still not worth it to go into SSE + * just to multiply unless doing a long operation. + * + * - Four instructions are required to rotate, + * movqda tmp, v // not required with VEX encoding + * pslld tmp, 13 // tmp <<= 13 + * psrld v, 19 // x >>= 19 + * por v, tmp // x |= tmp + * compared to one for scalar: + * roll v, 13 // reliably fast across the board + * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason + * + * - Instruction level parallelism is actually more beneficial here because + * the SIMD actually serializes this operation: While v1 is rotating, v2 + * can load data, while v3 can multiply. SSE forces them to operate + * together. + * + * This is also enabled on AArch64, as Clang is *very aggressive* in vectorizing + * the loop. NEON is only faster on the A53, and with the newer cores, it is less + * than half the speed. + * + * Additionally, this is used on WASM SIMD128 because it JITs to the same + * SIMD instructions and has the same issue. + */ + XXH_COMPILER_GUARD(acc); +#endif + return acc; +} + +/*! + * @internal + * @brief Mixes all bits to finalize the hash. + * + * The final mix ensures that all input bits have a chance to impact any bit in + * the output digest, resulting in an unbiased distribution. + * + * @param hash The hash to avalanche. + * @return The avalanched hash. + */ +static xxh_u32 XXH32_avalanche(xxh_u32 hash) +{ + hash ^= hash >> 15; + hash *= XXH_PRIME32_2; + hash ^= hash >> 13; + hash *= XXH_PRIME32_3; + hash ^= hash >> 16; + return hash; +} + +#define XXH_get32bits(p) XXH_readLE32_align(p, align) + +/*! + * @internal + * @brief Processes the last 0-15 bytes of @p ptr. + * + * There may be up to 15 bytes remaining to consume from the input. + * This final stage will digest them to ensure that all input bytes are present + * in the final mix. + * + * @param hash The hash to finalize. + * @param ptr The pointer to the remaining input. + * @param len The remaining length, modulo 16. + * @param align Whether @p ptr is aligned. + * @return The finalized hash. + * @see XXH64_finalize(). + */ +static XXH_PUREF xxh_u32 +XXH32_finalize(xxh_u32 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) +{ +#define XXH_PROCESS1 do { \ + hash += (*ptr++) * XXH_PRIME32_5; \ + hash = XXH_rotl32(hash, 11) * XXH_PRIME32_1; \ +} while (0) + +#define XXH_PROCESS4 do { \ + hash += XXH_get32bits(ptr) * XXH_PRIME32_3; \ + ptr += 4; \ + hash = XXH_rotl32(hash, 17) * XXH_PRIME32_4; \ +} while (0) + + if (ptr==NULL) XXH_ASSERT(len == 0); + + /* Compact rerolled version; generally faster */ + if (!XXH32_ENDJMP) { + len &= 15; + while (len >= 4) { + XXH_PROCESS4; + len -= 4; + } + while (len > 0) { + XXH_PROCESS1; + --len; + } + return XXH32_avalanche(hash); + } else { + switch(len&15) /* or switch(bEnd - p) */ { + case 12: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 8: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 4: XXH_PROCESS4; + return XXH32_avalanche(hash); + + case 13: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 9: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 5: XXH_PROCESS4; + XXH_PROCESS1; + return XXH32_avalanche(hash); + + case 14: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 10: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 6: XXH_PROCESS4; + XXH_PROCESS1; + XXH_PROCESS1; + return XXH32_avalanche(hash); + + case 15: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 11: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 7: XXH_PROCESS4; + XXH_FALLTHROUGH; /* fallthrough */ + case 3: XXH_PROCESS1; + XXH_FALLTHROUGH; /* fallthrough */ + case 2: XXH_PROCESS1; + XXH_FALLTHROUGH; /* fallthrough */ + case 1: XXH_PROCESS1; + XXH_FALLTHROUGH; /* fallthrough */ + case 0: return XXH32_avalanche(hash); + } + XXH_ASSERT(0); + return hash; /* reaching this point is deemed impossible */ + } +} + +#ifdef XXH_OLD_NAMES +# define PROCESS1 XXH_PROCESS1 +# define PROCESS4 XXH_PROCESS4 +#else +# undef XXH_PROCESS1 +# undef XXH_PROCESS4 +#endif + +/*! + * @internal + * @brief The implementation for @ref XXH32(). + * + * @param input , len , seed Directly passed from @ref XXH32(). + * @param align Whether @p input is aligned. + * @return The calculated hash. + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u32 +XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align) +{ + xxh_u32 h32; + + if (input==NULL) XXH_ASSERT(len == 0); + + if (len>=16) { + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 15; + xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + xxh_u32 v2 = seed + XXH_PRIME32_2; + xxh_u32 v3 = seed + 0; + xxh_u32 v4 = seed - XXH_PRIME32_1; + + do { + v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; + v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; + v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; + v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; + } while (input < limit); + + h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + } else { + h32 = seed + XXH_PRIME32_5; + } + + h32 += (xxh_u32)len; + + return XXH32_finalize(h32, input, len&15, align); +} + +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed) +{ +#if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH32_state_t state; + XXH32_reset(&state, seed); + XXH32_update(&state, (const xxh_u8*)input, len); + return XXH32_digest(&state); +#else + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ + return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned); + } } + + return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned); +#endif +} + + + +/******* Hash streaming *******/ +#ifndef XXH_NO_STREAM +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) +{ + return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); +} +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) +{ + XXH_memcpy(dstState, srcState, sizeof(*dstState)); +} + +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed) +{ + XXH_ASSERT(statePtr != NULL); + memset(statePtr, 0, sizeof(*statePtr)); + statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + statePtr->v[1] = seed + XXH_PRIME32_2; + statePtr->v[2] = seed + 0; + statePtr->v[3] = seed - XXH_PRIME32_1; + return XXH_OK; +} + + +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API XXH_errorcode +XXH32_update(XXH32_state_t* state, const void* input, size_t len) +{ + if (input==NULL) { + XXH_ASSERT(len == 0); + return XXH_OK; + } + + { const xxh_u8* p = (const xxh_u8*)input; + const xxh_u8* const bEnd = p + len; + + state->total_len_32 += (XXH32_hash_t)len; + state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); + + if (state->memsize + len < 16) { /* fill in tmp buffer */ + XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); + state->memsize += (XXH32_hash_t)len; + return XXH_OK; + } + + if (state->memsize) { /* some data left from previous update */ + XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); + { const xxh_u32* p32 = state->mem32; + state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++; + state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++; + state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++; + state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32)); + } + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= bEnd-16) { + const xxh_u8* const limit = bEnd - 16; + + do { + state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4; + state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4; + state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4; + state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4; + } while (p<=limit); + + } + + if (p < bEnd) { + XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + } + + return XXH_OK; +} + + +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) +{ + xxh_u32 h32; + + if (state->large_len) { + h32 = XXH_rotl32(state->v[0], 1) + + XXH_rotl32(state->v[1], 7) + + XXH_rotl32(state->v[2], 12) + + XXH_rotl32(state->v[3], 18); + } else { + h32 = state->v[2] /* == seed */ + XXH_PRIME32_5; + } + + h32 += state->total_len_32; + + return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); +} +#endif /* !XXH_NO_STREAM */ + +/******* Canonical representation *******/ + +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); + XXH_memcpy(dst, &hash, sizeof(*dst)); +} +/*! @ingroup XXH32_family */ +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) +{ + return XXH_readBE32(src); +} + + +#ifndef XXH_NO_LONG_LONG + +/* ******************************************************************* +* 64-bit hash functions +*********************************************************************/ +/*! + * @} + * @ingroup impl + * @{ + */ +/******* Memory access *******/ + +typedef XXH64_hash_t xxh_u64; + +#ifdef XXH_OLD_NAMES +# define U64 xxh_u64 +#endif + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) +/* + * Manual byteshift. Best for old compilers which don't inline memcpy. + * We actually directly use XXH_readLE64 and XXH_readBE64. + */ +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static xxh_u64 XXH_read64(const void* memPtr) +{ + return *(const xxh_u64*) memPtr; +} + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* + * __attribute__((aligned(1))) is supported by gcc and clang. Originally the + * documentation claimed that it only increased the alignment, but actually it + * can decrease it on gcc, clang, and icc: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69502, + * https://gcc.godbolt.org/z/xYez1j67Y. + */ +#ifdef XXH_OLD_NAMES +typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; +#endif +static xxh_u64 XXH_read64(const void* ptr) +{ + typedef __attribute__((aligned(1))) xxh_u64 xxh_unalign64; + return *((const xxh_unalign64*)ptr); +} + +#else + +/* + * Portable and safe solution. Generally efficient. + * see: https://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html + */ +static xxh_u64 XXH_read64(const void* memPtr) +{ + xxh_u64 val; + XXH_memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap64 _byteswap_uint64 +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap64 __builtin_bswap64 +#else +static xxh_u64 XXH_swap64(xxh_u64 x) +{ + return ((x << 56) & 0xff00000000000000ULL) | + ((x << 40) & 0x00ff000000000000ULL) | + ((x << 24) & 0x0000ff0000000000ULL) | + ((x << 8) & 0x000000ff00000000ULL) | + ((x >> 8) & 0x00000000ff000000ULL) | + ((x >> 24) & 0x0000000000ff0000ULL) | + ((x >> 40) & 0x000000000000ff00ULL) | + ((x >> 56) & 0x00000000000000ffULL); +} +#endif + + +/* XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. */ +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) + +XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[0] + | ((xxh_u64)bytePtr[1] << 8) + | ((xxh_u64)bytePtr[2] << 16) + | ((xxh_u64)bytePtr[3] << 24) + | ((xxh_u64)bytePtr[4] << 32) + | ((xxh_u64)bytePtr[5] << 40) + | ((xxh_u64)bytePtr[6] << 48) + | ((xxh_u64)bytePtr[7] << 56); +} + +XXH_FORCE_INLINE xxh_u64 XXH_readBE64(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[7] + | ((xxh_u64)bytePtr[6] << 8) + | ((xxh_u64)bytePtr[5] << 16) + | ((xxh_u64)bytePtr[4] << 24) + | ((xxh_u64)bytePtr[3] << 32) + | ((xxh_u64)bytePtr[2] << 40) + | ((xxh_u64)bytePtr[1] << 48) + | ((xxh_u64)bytePtr[0] << 56); +} + +#else +XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); +} + +static xxh_u64 XXH_readBE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); +} +#endif + +XXH_FORCE_INLINE xxh_u64 +XXH_readLE64_align(const void* ptr, XXH_alignment align) +{ + if (align==XXH_unaligned) + return XXH_readLE64(ptr); + else + return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr); +} + + +/******* xxh64 *******/ +/*! + * @} + * @defgroup XXH64_impl XXH64 implementation + * @ingroup impl + * + * Details on the XXH64 implementation. + * @{ + */ +/* #define rather that static const, to be used as initializers */ +#define XXH_PRIME64_1 0x9E3779B185EBCA87ULL /*!< 0b1001111000110111011110011011000110000101111010111100101010000111 */ +#define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL /*!< 0b1100001010110010101011100011110100100111110101001110101101001111 */ +#define XXH_PRIME64_3 0x165667B19E3779F9ULL /*!< 0b0001011001010110011001111011000110011110001101110111100111111001 */ +#define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL /*!< 0b1000010111101011110010100111011111000010101100101010111001100011 */ +#define XXH_PRIME64_5 0x27D4EB2F165667C5ULL /*!< 0b0010011111010100111010110010111100010110010101100110011111000101 */ + +#ifdef XXH_OLD_NAMES +# define PRIME64_1 XXH_PRIME64_1 +# define PRIME64_2 XXH_PRIME64_2 +# define PRIME64_3 XXH_PRIME64_3 +# define PRIME64_4 XXH_PRIME64_4 +# define PRIME64_5 XXH_PRIME64_5 +#endif + +/*! @copydoc XXH32_round */ +static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) +{ + acc += input * XXH_PRIME64_2; + acc = XXH_rotl64(acc, 31); + acc *= XXH_PRIME64_1; +#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * DISABLE AUTOVECTORIZATION: + * A compiler fence is used to prevent GCC and Clang from + * autovectorizing the XXH64 loop (pragmas and attributes don't work for some + * reason) without globally disabling AVX512. + * + * Autovectorization of XXH64 tends to be detrimental, + * though the exact outcome may change depending on exact cpu and compiler version. + * For information, it has been reported as detrimental for Skylake-X, + * but possibly beneficial for Zen4. + * + * The default is to disable auto-vectorization, + * but you can select to enable it instead using `XXH_ENABLE_AUTOVECTORIZE` build variable. + */ + XXH_COMPILER_GUARD(acc); +#endif + return acc; +} + +static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val) +{ + val = XXH64_round(0, val); + acc ^= val; + acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4; + return acc; +} + +/*! @copydoc XXH32_avalanche */ +static xxh_u64 XXH64_avalanche(xxh_u64 hash) +{ + hash ^= hash >> 33; + hash *= XXH_PRIME64_2; + hash ^= hash >> 29; + hash *= XXH_PRIME64_3; + hash ^= hash >> 32; + return hash; +} + + +#define XXH_get64bits(p) XXH_readLE64_align(p, align) + +/*! + * @internal + * @brief Processes the last 0-31 bytes of @p ptr. + * + * There may be up to 31 bytes remaining to consume from the input. + * This final stage will digest them to ensure that all input bytes are present + * in the final mix. + * + * @param hash The hash to finalize. + * @param ptr The pointer to the remaining input. + * @param len The remaining length, modulo 32. + * @param align Whether @p ptr is aligned. + * @return The finalized hash + * @see XXH32_finalize(). + */ +static XXH_PUREF xxh_u64 +XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) +{ + if (ptr==NULL) XXH_ASSERT(len == 0); + len &= 31; + while (len >= 8) { + xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr)); + ptr += 8; + hash ^= k1; + hash = XXH_rotl64(hash,27) * XXH_PRIME64_1 + XXH_PRIME64_4; + len -= 8; + } + if (len >= 4) { + hash ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1; + ptr += 4; + hash = XXH_rotl64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3; + len -= 4; + } + while (len > 0) { + hash ^= (*ptr++) * XXH_PRIME64_5; + hash = XXH_rotl64(hash, 11) * XXH_PRIME64_1; + --len; + } + return XXH64_avalanche(hash); +} + +#ifdef XXH_OLD_NAMES +# define PROCESS1_64 XXH_PROCESS1_64 +# define PROCESS4_64 XXH_PROCESS4_64 +# define PROCESS8_64 XXH_PROCESS8_64 +#else +# undef XXH_PROCESS1_64 +# undef XXH_PROCESS4_64 +# undef XXH_PROCESS8_64 +#endif + +/*! + * @internal + * @brief The implementation for @ref XXH64(). + * + * @param input , len , seed Directly passed from @ref XXH64(). + * @param align Whether @p input is aligned. + * @return The calculated hash. + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u64 +XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align) +{ + xxh_u64 h64; + if (input==NULL) XXH_ASSERT(len == 0); + + if (len>=32) { + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 31; + xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + xxh_u64 v2 = seed + XXH_PRIME64_2; + xxh_u64 v3 = seed + 0; + xxh_u64 v4 = seed - XXH_PRIME64_1; + + do { + v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; + v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; + v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; + v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; + } while (input= 2 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH64_state_t state; + XXH64_reset(&state, seed); + XXH64_update(&state, (const xxh_u8*)input, len); + return XXH64_digest(&state); +#else + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ + return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_aligned); + } } + + return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned); + +#endif +} + +/******* Hash Streaming *******/ +#ifndef XXH_NO_STREAM +/*! @ingroup XXH64_family*/ +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) +{ + return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); +} +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dstState, const XXH64_state_t* srcState) +{ + XXH_memcpy(dstState, srcState, sizeof(*dstState)); +} + +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed) +{ + XXH_ASSERT(statePtr != NULL); + memset(statePtr, 0, sizeof(*statePtr)); + statePtr->v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + statePtr->v[1] = seed + XXH_PRIME64_2; + statePtr->v[2] = seed + 0; + statePtr->v[3] = seed - XXH_PRIME64_1; + return XXH_OK; +} + +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH_errorcode +XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, size_t len) +{ + if (input==NULL) { + XXH_ASSERT(len == 0); + return XXH_OK; + } + + { const xxh_u8* p = (const xxh_u8*)input; + const xxh_u8* const bEnd = p + len; + + state->total_len += len; + + if (state->memsize + len < 32) { /* fill in tmp buffer */ + XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); + state->memsize += (xxh_u32)len; + return XXH_OK; + } + + if (state->memsize) { /* tmp buffer is full */ + XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); + state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0)); + state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1)); + state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2)); + state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3)); + p += 32 - state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) { + const xxh_u8* const limit = bEnd - 32; + + do { + state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8; + state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8; + state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8; + state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8; + } while (p<=limit); + + } + + if (p < bEnd) { + XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + } + + return XXH_OK; +} + + +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state) +{ + xxh_u64 h64; + + if (state->total_len >= 32) { + h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18); + h64 = XXH64_mergeRound(h64, state->v[0]); + h64 = XXH64_mergeRound(h64, state->v[1]); + h64 = XXH64_mergeRound(h64, state->v[2]); + h64 = XXH64_mergeRound(h64, state->v[3]); + } else { + h64 = state->v[2] /*seed*/ + XXH_PRIME64_5; + } + + h64 += (xxh_u64) state->total_len; + + return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); +} +#endif /* !XXH_NO_STREAM */ + +/******* Canonical representation *******/ + +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); + XXH_memcpy(dst, &hash, sizeof(*dst)); +} + +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src) +{ + return XXH_readBE64(src); +} + +#if defined (__cplusplus) +} +#endif + +#ifndef XXH_NO_XXH3 + +/* ********************************************************************* +* XXH3 +* New generation hash designed for speed on small keys and vectorization +************************************************************************ */ +/*! + * @} + * @defgroup XXH3_impl XXH3 implementation + * @ingroup impl + * @{ + */ + +/* === Compiler specifics === */ + +#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ +# define XXH_RESTRICT /* disable */ +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined (__clang__)) \ + || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ + || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) +/* + * There are a LOT more compilers that recognize __restrict but this + * covers the major ones. + */ +# define XXH_RESTRICT __restrict +#else +# define XXH_RESTRICT /* disable */ +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 3)) \ + || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ + || defined(__clang__) +# define XXH_likely(x) __builtin_expect(x, 1) +# define XXH_unlikely(x) __builtin_expect(x, 0) +#else +# define XXH_likely(x) (x) +# define XXH_unlikely(x) (x) +#endif + +#ifndef XXH_HAS_INCLUDE +# ifdef __has_include +/* + * Not defined as XXH_HAS_INCLUDE(x) (function-like) because + * this causes segfaults in Apple Clang 4.2 (on Mac OS X 10.7 Lion) + */ +# define XXH_HAS_INCLUDE __has_include +# else +# define XXH_HAS_INCLUDE(x) 0 +# endif +#endif + +#if defined(__GNUC__) || defined(__clang__) +# if defined(__ARM_FEATURE_SVE) +# include +# endif +# if defined(__ARM_NEON__) || defined(__ARM_NEON) \ + || (defined(_M_ARM) && _M_ARM >= 7) \ + || defined(_M_ARM64) || defined(_M_ARM64EC) \ + || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE()) /* WASM SIMD128 via SIMDe */ +# define inline __inline__ /* circumvent a clang bug */ +# include +# undef inline +# elif defined(__AVX2__) +# include +# elif defined(__SSE2__) +# include +# endif +#endif + +#if defined(_MSC_VER) +# include +#endif + +/* + * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while + * remaining a true 64-bit/128-bit hash function. + * + * This is done by prioritizing a subset of 64-bit operations that can be + * emulated without too many steps on the average 32-bit machine. + * + * For example, these two lines seem similar, and run equally fast on 64-bit: + * + * xxh_u64 x; + * x ^= (x >> 47); // good + * x ^= (x >> 13); // bad + * + * However, to a 32-bit machine, there is a major difference. + * + * x ^= (x >> 47) looks like this: + * + * x.lo ^= (x.hi >> (47 - 32)); + * + * while x ^= (x >> 13) looks like this: + * + * // note: funnel shifts are not usually cheap. + * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13)); + * x.hi ^= (x.hi >> 13); + * + * The first one is significantly faster than the second, simply because the + * shift is larger than 32. This means: + * - All the bits we need are in the upper 32 bits, so we can ignore the lower + * 32 bits in the shift. + * - The shift result will always fit in the lower 32 bits, and therefore, + * we can ignore the upper 32 bits in the xor. + * + * Thanks to this optimization, XXH3 only requires these features to be efficient: + * + * - Usable unaligned access + * - A 32-bit or 64-bit ALU + * - If 32-bit, a decent ADC instruction + * - A 32 or 64-bit multiply with a 64-bit result + * - For the 128-bit variant, a decent byteswap helps short inputs. + * + * The first two are already required by XXH32, and almost all 32-bit and 64-bit + * platforms which can run XXH32 can run XXH3 efficiently. + * + * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one + * notable exception. + * + * First of all, Thumb-1 lacks support for the UMULL instruction which + * performs the important long multiply. This means numerous __aeabi_lmul + * calls. + * + * Second of all, the 8 functional registers are just not enough. + * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need + * Lo registers, and this shuffling results in thousands more MOVs than A32. + * + * A32 and T32 don't have this limitation. They can access all 14 registers, + * do a 32->64 multiply with UMULL, and the flexible operand allowing free + * shifts is helpful, too. + * + * Therefore, we do a quick sanity check. + * + * If compiling Thumb-1 for a target which supports ARM instructions, we will + * emit a warning, as it is not a "sane" platform to compile for. + * + * Usually, if this happens, it is because of an accident and you probably need + * to specify -march, as you likely meant to compile for a newer architecture. + * + * Credit: large sections of the vectorial and asm source code paths + * have been contributed by @easyaspi314 + */ +#if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM) +# warning "XXH3 is highly inefficient without ARM or Thumb-2." +#endif + +/* ========================================== + * Vectorization detection + * ========================================== */ + +#ifdef XXH_DOXYGEN +/*! + * @ingroup tuning + * @brief Overrides the vectorization implementation chosen for XXH3. + * + * Can be defined to 0 to disable SIMD or any of the values mentioned in + * @ref XXH_VECTOR_TYPE. + * + * If this is not defined, it uses predefined macros to determine the best + * implementation. + */ +# define XXH_VECTOR XXH_SCALAR +/*! + * @ingroup tuning + * @brief Possible values for @ref XXH_VECTOR. + * + * Note that these are actually implemented as macros. + * + * If this is not defined, it is detected automatically. + * internal macro XXH_X86DISPATCH overrides this. + */ +enum XXH_VECTOR_TYPE /* fake enum */ { + XXH_SCALAR = 0, /*!< Portable scalar version */ + XXH_SSE2 = 1, /*!< + * SSE2 for Pentium 4, Opteron, all x86_64. + * + * @note SSE2 is also guaranteed on Windows 10, macOS, and + * Android x86. + */ + XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ + XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ + XXH_NEON = 4, /*!< + * NEON for most ARMv7-A, all AArch64, and WASM SIMD128 + * via the SIMDeverywhere polyfill provided with the + * Emscripten SDK. + */ + XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ + XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */ +}; +/*! + * @ingroup tuning + * @brief Selects the minimum alignment for XXH3's accumulators. + * + * When using SIMD, this should match the alignment required for said vector + * type, so, for example, 32 for AVX2. + * + * Default: Auto detected. + */ +# define XXH_ACC_ALIGN 8 +#endif + +/* Actual definition */ +#ifndef XXH_DOXYGEN +# define XXH_SCALAR 0 +# define XXH_SSE2 1 +# define XXH_AVX2 2 +# define XXH_AVX512 3 +# define XXH_NEON 4 +# define XXH_VSX 5 +# define XXH_SVE 6 +#endif + +#ifndef XXH_VECTOR /* can be defined on command line */ +# if defined(__ARM_FEATURE_SVE) +# define XXH_VECTOR XXH_SVE +# elif ( \ + defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \ + || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) /* msvc */ \ + || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE()) /* wasm simd128 via SIMDe */ \ + ) && ( \ + defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ + ) +# define XXH_VECTOR XXH_NEON +# elif defined(__AVX512F__) +# define XXH_VECTOR XXH_AVX512 +# elif defined(__AVX2__) +# define XXH_VECTOR XXH_AVX2 +# elif defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) +# define XXH_VECTOR XXH_SSE2 +# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \ + || (defined(__s390x__) && defined(__VEC__)) \ + && defined(__GNUC__) /* TODO: IBM XL */ +# define XXH_VECTOR XXH_VSX +# else +# define XXH_VECTOR XXH_SCALAR +# endif +#endif + +/* __ARM_FEATURE_SVE is only supported by GCC & Clang. */ +#if (XXH_VECTOR == XXH_SVE) && !defined(__ARM_FEATURE_SVE) +# ifdef _MSC_VER +# pragma warning(once : 4606) +# else +# warning "__ARM_FEATURE_SVE isn't supported. Use SCALAR instead." +# endif +# undef XXH_VECTOR +# define XXH_VECTOR XXH_SCALAR +#endif + +/* + * Controls the alignment of the accumulator, + * for compatibility with aligned vector loads, which are usually faster. + */ +#ifndef XXH_ACC_ALIGN +# if defined(XXH_X86DISPATCH) +# define XXH_ACC_ALIGN 64 /* for compatibility with avx512 */ +# elif XXH_VECTOR == XXH_SCALAR /* scalar */ +# define XXH_ACC_ALIGN 8 +# elif XXH_VECTOR == XXH_SSE2 /* sse2 */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_AVX2 /* avx2 */ +# define XXH_ACC_ALIGN 32 +# elif XXH_VECTOR == XXH_NEON /* neon */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_VSX /* vsx */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_AVX512 /* avx512 */ +# define XXH_ACC_ALIGN 64 +# elif XXH_VECTOR == XXH_SVE /* sve */ +# define XXH_ACC_ALIGN 64 +# endif +#endif + +#if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \ + || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512 +# define XXH_SEC_ALIGN XXH_ACC_ALIGN +#elif XXH_VECTOR == XXH_SVE +# define XXH_SEC_ALIGN XXH_ACC_ALIGN +#else +# define XXH_SEC_ALIGN 8 +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define XXH_ALIASING __attribute__((may_alias)) +#else +# define XXH_ALIASING /* nothing */ +#endif + +/* + * UGLY HACK: + * GCC usually generates the best code with -O3 for xxHash. + * + * However, when targeting AVX2, it is overzealous in its unrolling resulting + * in code roughly 3/4 the speed of Clang. + * + * There are other issues, such as GCC splitting _mm256_loadu_si256 into + * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which + * only applies to Sandy and Ivy Bridge... which don't even support AVX2. + * + * That is why when compiling the AVX2 version, it is recommended to use either + * -O2 -mavx2 -march=haswell + * or + * -O2 -mavx2 -mno-avx256-split-unaligned-load + * for decent performance, or to use Clang instead. + * + * Fortunately, we can control the first one with a pragma that forces GCC into + * -O2, but the other one we can't control without "failed to inline always + * inline function due to target mismatch" warnings. + */ +#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ + && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0 /* respect -O0 and -Os */ +# pragma GCC push_options +# pragma GCC optimize("-O2") +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + +#if XXH_VECTOR == XXH_NEON + +/* + * UGLY HACK: While AArch64 GCC on Linux does not seem to care, on macOS, GCC -O3 + * optimizes out the entire hashLong loop because of the aliasing violation. + * + * However, GCC is also inefficient at load-store optimization with vld1q/vst1q, + * so the only option is to mark it as aliasing. + */ +typedef uint64x2_t xxh_aliasing_uint64x2_t XXH_ALIASING; + +/*! + * @internal + * @brief `vld1q_u64` but faster and alignment-safe. + * + * On AArch64, unaligned access is always safe, but on ARMv7-a, it is only + * *conditionally* safe (`vld1` has an alignment bit like `movdq[ua]` in x86). + * + * GCC for AArch64 sees `vld1q_u8` as an intrinsic instead of a load, so it + * prohibits load-store optimizations. Therefore, a direct dereference is used. + * + * Otherwise, `vld1q_u8` is used with `vreinterpretq_u8_u64` to do a safe + * unaligned load. + */ +#if defined(__aarch64__) && defined(__GNUC__) && !defined(__clang__) +XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr) /* silence -Wcast-align */ +{ + return *(xxh_aliasing_uint64x2_t const *)ptr; +} +#else +XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr) +{ + return vreinterpretq_u64_u8(vld1q_u8((uint8_t const*)ptr)); +} +#endif + +/*! + * @internal + * @brief `vmlal_u32` on low and high halves of a vector. + * + * This is a workaround for AArch64 GCC < 11 which implemented arm_neon.h with + * inline assembly and were therefore incapable of merging the `vget_{low, high}_u32` + * with `vmlal_u32`. + */ +#if defined(__aarch64__) && defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 11 +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_low_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + /* Inline assembly is the only way */ + __asm__("umlal %0.2d, %1.2s, %2.2s" : "+w" (acc) : "w" (lhs), "w" (rhs)); + return acc; +} +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + /* This intrinsic works as expected */ + return vmlal_high_u32(acc, lhs, rhs); +} +#else +/* Portable intrinsic versions */ +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_low_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + return vmlal_u32(acc, vget_low_u32(lhs), vget_low_u32(rhs)); +} +/*! @copydoc XXH_vmlal_low_u32 + * Assume the compiler converts this to vmlal_high_u32 on aarch64 */ +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + return vmlal_u32(acc, vget_high_u32(lhs), vget_high_u32(rhs)); +} +#endif + +/*! + * @ingroup tuning + * @brief Controls the NEON to scalar ratio for XXH3 + * + * This can be set to 2, 4, 6, or 8. + * + * ARM Cortex CPUs are _very_ sensitive to how their pipelines are used. + * + * For example, the Cortex-A73 can dispatch 3 micro-ops per cycle, but only 2 of those + * can be NEON. If you are only using NEON instructions, you are only using 2/3 of the CPU + * bandwidth. + * + * This is even more noticeable on the more advanced cores like the Cortex-A76 which + * can dispatch 8 micro-ops per cycle, but still only 2 NEON micro-ops at once. + * + * Therefore, to make the most out of the pipeline, it is beneficial to run 6 NEON lanes + * and 2 scalar lanes, which is chosen by default. + * + * This does not apply to Apple processors or 32-bit processors, which run better with + * full NEON. These will default to 8. Additionally, size-optimized builds run 8 lanes. + * + * This change benefits CPUs with large micro-op buffers without negatively affecting + * most other CPUs: + * + * | Chipset | Dispatch type | NEON only | 6:2 hybrid | Diff. | + * |:----------------------|:--------------------|----------:|-----------:|------:| + * | Snapdragon 730 (A76) | 2 NEON/8 micro-ops | 8.8 GB/s | 10.1 GB/s | ~16% | + * | Snapdragon 835 (A73) | 2 NEON/3 micro-ops | 5.1 GB/s | 5.3 GB/s | ~5% | + * | Marvell PXA1928 (A53) | In-order dual-issue | 1.9 GB/s | 1.9 GB/s | 0% | + * | Apple M1 | 4 NEON/8 micro-ops | 37.3 GB/s | 36.1 GB/s | ~-3% | + * + * It also seems to fix some bad codegen on GCC, making it almost as fast as clang. + * + * When using WASM SIMD128, if this is 2 or 6, SIMDe will scalarize 2 of the lanes meaning + * it effectively becomes worse 4. + * + * @see XXH3_accumulate_512_neon() + */ +# ifndef XXH3_NEON_LANES +# if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \ + && !defined(__APPLE__) && XXH_SIZE_OPT <= 0 +# define XXH3_NEON_LANES 6 +# else +# define XXH3_NEON_LANES XXH_ACC_NB +# endif +# endif +#endif /* XXH_VECTOR == XXH_NEON */ + +#if defined (__cplusplus) +} /* extern "C" */ +#endif + +/* + * VSX and Z Vector helpers. + * + * This is very messy, and any pull requests to clean this up are welcome. + * + * There are a lot of problems with supporting VSX and s390x, due to + * inconsistent intrinsics, spotty coverage, and multiple endiannesses. + */ +#if XXH_VECTOR == XXH_VSX +/* Annoyingly, these headers _may_ define three macros: `bool`, `vector`, + * and `pixel`. This is a problem for obvious reasons. + * + * These keywords are unnecessary; the spec literally says they are + * equivalent to `__bool`, `__vector`, and `__pixel` and may be undef'd + * after including the header. + * + * We use pragma push_macro/pop_macro to keep the namespace clean. */ +# pragma push_macro("bool") +# pragma push_macro("vector") +# pragma push_macro("pixel") +/* silence potential macro redefined warnings */ +# undef bool +# undef vector +# undef pixel + +# if defined(__s390x__) +# include +# else +# include +# endif + +/* Restore the original macro values, if applicable. */ +# pragma pop_macro("pixel") +# pragma pop_macro("vector") +# pragma pop_macro("bool") + +typedef __vector unsigned long long xxh_u64x2; +typedef __vector unsigned char xxh_u8x16; +typedef __vector unsigned xxh_u32x4; + +/* + * UGLY HACK: Similar to aarch64 macOS GCC, s390x GCC has the same aliasing issue. + */ +typedef xxh_u64x2 xxh_aliasing_u64x2 XXH_ALIASING; + +# ifndef XXH_VSX_BE +# if defined(__BIG_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define XXH_VSX_BE 1 +# elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__ +# warning "-maltivec=be is not recommended. Please use native endianness." +# define XXH_VSX_BE 1 +# else +# define XXH_VSX_BE 0 +# endif +# endif /* !defined(XXH_VSX_BE) */ + +# if XXH_VSX_BE +# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__)) +# define XXH_vec_revb vec_revb +# else +#if defined (__cplusplus) +extern "C" { +#endif +/*! + * A polyfill for POWER9's vec_revb(). + */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val) +{ + xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 }; + return vec_perm(val, val, vByteSwap); +} +#if defined (__cplusplus) +} /* extern "C" */ +#endif +# endif +# endif /* XXH_VSX_BE */ + +#if defined (__cplusplus) +extern "C" { +#endif +/*! + * Performs an unaligned vector load and byte swaps it on big endian. + */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr) +{ + xxh_u64x2 ret; + XXH_memcpy(&ret, ptr, sizeof(xxh_u64x2)); +# if XXH_VSX_BE + ret = XXH_vec_revb(ret); +# endif + return ret; +} + +/* + * vec_mulo and vec_mule are very problematic intrinsics on PowerPC + * + * These intrinsics weren't added until GCC 8, despite existing for a while, + * and they are endian dependent. Also, their meaning swap depending on version. + * */ +# if defined(__s390x__) + /* s390x is always big endian, no issue on this platform */ +# define XXH_vec_mulo vec_mulo +# define XXH_vec_mule vec_mule +# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) && !defined(__ibmxl__) +/* Clang has a better way to control this, we can just use the builtin which doesn't swap. */ + /* The IBM XL Compiler (which defined __clang__) only implements the vec_* operations */ +# define XXH_vec_mulo __builtin_altivec_vmulouw +# define XXH_vec_mule __builtin_altivec_vmuleuw +# else +/* gcc needs inline assembly */ +/* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b) +{ + xxh_u64x2 result; + __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); + return result; +} +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b) +{ + xxh_u64x2 result; + __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); + return result; +} +# endif /* XXH_vec_mulo, XXH_vec_mule */ + +#if defined (__cplusplus) +} /* extern "C" */ +#endif + +#endif /* XXH_VECTOR == XXH_VSX */ + +#if XXH_VECTOR == XXH_SVE +#define ACCRND(acc, offset) \ +do { \ + svuint64_t input_vec = svld1_u64(mask, xinput + offset); \ + svuint64_t secret_vec = svld1_u64(mask, xsecret + offset); \ + svuint64_t mixed = sveor_u64_x(mask, secret_vec, input_vec); \ + svuint64_t swapped = svtbl_u64(input_vec, kSwap); \ + svuint64_t mixed_lo = svextw_u64_x(mask, mixed); \ + svuint64_t mixed_hi = svlsr_n_u64_x(mask, mixed, 32); \ + svuint64_t mul = svmad_u64_x(mask, mixed_lo, mixed_hi, swapped); \ + acc = svadd_u64_x(mask, acc, mul); \ +} while (0) +#endif /* XXH_VECTOR == XXH_SVE */ + +/* prefetch + * can be disabled, by declaring XXH_NO_PREFETCH build macro */ +#if defined(XXH_NO_PREFETCH) +# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ +#else +# if XXH_SIZE_OPT >= 1 +# define XXH_PREFETCH(ptr) (void)(ptr) +# elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */ +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) +# else +# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ +# endif +#endif /* XXH_NO_PREFETCH */ + +#if defined (__cplusplus) +extern "C" { +#endif +/* ========================================== + * XXH3 default settings + * ========================================== */ + +#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */ + +#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN) +# error "default keyset is not large enough" +#endif + +/*! Pseudorandom secret taken directly from FARSH. */ +XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = { + 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, + 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, + 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, + 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, + 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, + 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, + 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, + 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, + 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, + 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, + 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, + 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, +}; + +static const xxh_u64 PRIME_MX1 = 0x165667919E3779F9ULL; /*!< 0b0001011001010110011001111001000110011110001101110111100111111001 */ +static const xxh_u64 PRIME_MX2 = 0x9FB21C651E98DF25ULL; /*!< 0b1001111110110010000111000110010100011110100110001101111100100101 */ + +#ifdef XXH_OLD_NAMES +# define kSecret XXH3_kSecret +#endif + +#ifdef XXH_DOXYGEN +/*! + * @brief Calculates a 32-bit to 64-bit long multiply. + * + * Implemented as a macro. + * + * Wraps `__emulu` on MSVC x86 because it tends to call `__allmul` when it doesn't + * need to (but it shouldn't need to anyways, it is about 7 instructions to do + * a 64x64 multiply...). Since we know that this will _always_ emit `MULL`, we + * use that instead of the normal method. + * + * If you are compiling for platforms like Thumb-1 and don't have a better option, + * you may also want to write your own long multiply routine here. + * + * @param x, y Numbers to be multiplied + * @return 64-bit product of the low 32 bits of @p x and @p y. + */ +XXH_FORCE_INLINE xxh_u64 +XXH_mult32to64(xxh_u64 x, xxh_u64 y) +{ + return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF); +} +#elif defined(_MSC_VER) && defined(_M_IX86) +# define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y)) +#else +/* + * Downcast + upcast is usually better than masking on older compilers like + * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers. + * + * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands + * and perform a full 64x64 multiply -- entirely redundant on 32-bit. + */ +# define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y)) +#endif + +/*! + * @brief Calculates a 64->128-bit long multiply. + * + * Uses `__uint128_t` and `_umul128` if available, otherwise uses a scalar + * version. + * + * @param lhs , rhs The 64-bit integers to be multiplied + * @return The 128-bit result represented in an @ref XXH128_hash_t. + */ +static XXH128_hash_t +XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs) +{ + /* + * GCC/Clang __uint128_t method. + * + * On most 64-bit targets, GCC and Clang define a __uint128_t type. + * This is usually the best way as it usually uses a native long 64-bit + * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64. + * + * Usually. + * + * Despite being a 32-bit platform, Clang (and emscripten) define this type + * despite not having the arithmetic for it. This results in a laggy + * compiler builtin call which calculates a full 128-bit multiply. + * In that case it is best to use the portable one. + * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677 + */ +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__wasm__) \ + && defined(__SIZEOF_INT128__) \ + || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) + + __uint128_t const product = (__uint128_t)lhs * (__uint128_t)rhs; + XXH128_hash_t r128; + r128.low64 = (xxh_u64)(product); + r128.high64 = (xxh_u64)(product >> 64); + return r128; + + /* + * MSVC for x64's _umul128 method. + * + * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct); + * + * This compiles to single operand MUL on x64. + */ +#elif (defined(_M_X64) || defined(_M_IA64)) && !defined(_M_ARM64EC) + +#ifndef _MSC_VER +# pragma intrinsic(_umul128) +#endif + xxh_u64 product_high; + xxh_u64 const product_low = _umul128(lhs, rhs, &product_high); + XXH128_hash_t r128; + r128.low64 = product_low; + r128.high64 = product_high; + return r128; + + /* + * MSVC for ARM64's __umulh method. + * + * This compiles to the same MUL + UMULH as GCC/Clang's __uint128_t method. + */ +#elif defined(_M_ARM64) || defined(_M_ARM64EC) + +#ifndef _MSC_VER +# pragma intrinsic(__umulh) +#endif + XXH128_hash_t r128; + r128.low64 = lhs * rhs; + r128.high64 = __umulh(lhs, rhs); + return r128; + +#else + /* + * Portable scalar method. Optimized for 32-bit and 64-bit ALUs. + * + * This is a fast and simple grade school multiply, which is shown below + * with base 10 arithmetic instead of base 0x100000000. + * + * 9 3 // D2 lhs = 93 + * x 7 5 // D2 rhs = 75 + * ---------- + * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15 + * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45 + * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21 + * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63 + * --------- + * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27 + * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67 + * --------- + * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975 + * + * The reasons for adding the products like this are: + * 1. It avoids manual carry tracking. Just like how + * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX. + * This avoids a lot of complexity. + * + * 2. It hints for, and on Clang, compiles to, the powerful UMAAL + * instruction available in ARM's Digital Signal Processing extension + * in 32-bit ARMv6 and later, which is shown below: + * + * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm) + * { + * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm; + * *RdLo = (xxh_u32)(product & 0xFFFFFFFF); + * *RdHi = (xxh_u32)(product >> 32); + * } + * + * This instruction was designed for efficient long multiplication, and + * allows this to be calculated in only 4 instructions at speeds + * comparable to some 64-bit ALUs. + * + * 3. It isn't terrible on other platforms. Usually this will be a couple + * of 32-bit ADD/ADCs. + */ + + /* First calculate all of the cross products. */ + xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF); + xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF); + xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32); + xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32); + + /* Now add the products together. These will never overflow. */ + xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi; + xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi; + xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF); + + XXH128_hash_t r128; + r128.low64 = lower; + r128.high64 = upper; + return r128; +#endif +} + +/*! + * @brief Calculates a 64-bit to 128-bit multiply, then XOR folds it. + * + * The reason for the separate function is to prevent passing too many structs + * around by value. This will hopefully inline the multiply, but we don't force it. + * + * @param lhs , rhs The 64-bit integers to multiply + * @return The low 64 bits of the product XOR'd by the high 64 bits. + * @see XXH_mult64to128() + */ +static xxh_u64 +XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs) +{ + XXH128_hash_t product = XXH_mult64to128(lhs, rhs); + return product.low64 ^ product.high64; +} + +/*! Seems to produce slightly better code on GCC for some reason. */ +XXH_FORCE_INLINE XXH_CONSTF xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) +{ + XXH_ASSERT(0 <= shift && shift < 64); + return v64 ^ (v64 >> shift); +} + +/* + * This is a fast avalanche stage, + * suitable when input bits are already partially mixed + */ +static XXH64_hash_t XXH3_avalanche(xxh_u64 h64) +{ + h64 = XXH_xorshift64(h64, 37); + h64 *= PRIME_MX1; + h64 = XXH_xorshift64(h64, 32); + return h64; +} + +/* + * This is a stronger avalanche, + * inspired by Pelle Evensen's rrmxmx + * preferable when input has not been previously mixed + */ +static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len) +{ + /* this mix is inspired by Pelle Evensen's rrmxmx */ + h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24); + h64 *= PRIME_MX2; + h64 ^= (h64 >> 35) + len ; + h64 *= PRIME_MX2; + return XXH_xorshift64(h64, 28); +} + + +/* ========================================== + * Short keys + * ========================================== + * One of the shortcomings of XXH32 and XXH64 was that their performance was + * sub-optimal on short lengths. It used an iterative algorithm which strongly + * favored lengths that were a multiple of 4 or 8. + * + * Instead of iterating over individual inputs, we use a set of single shot + * functions which piece together a range of lengths and operate in constant time. + * + * Additionally, the number of multiplies has been significantly reduced. This + * reduces latency, especially when emulating 64-bit multiplies on 32-bit. + * + * Depending on the platform, this may or may not be faster than XXH32, but it + * is almost guaranteed to be faster than XXH64. + */ + +/* + * At very short lengths, there isn't enough input to fully hide secrets, or use + * the entire secret. + * + * There is also only a limited amount of mixing we can do before significantly + * impacting performance. + * + * Therefore, we use different sections of the secret and always mix two secret + * samples with an XOR. This should have no effect on performance on the + * seedless or withSeed variants because everything _should_ be constant folded + * by modern compilers. + * + * The XOR mixing hides individual parts of the secret and increases entropy. + * + * This adds an extra layer of strength for custom secrets. + */ +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t +XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(1 <= len && len <= 3); + XXH_ASSERT(secret != NULL); + /* + * len = 1: combined = { input[0], 0x01, input[0], input[0] } + * len = 2: combined = { input[1], 0x02, input[0], input[1] } + * len = 3: combined = { input[2], 0x03, input[0], input[1] } + */ + { xxh_u8 const c1 = input[0]; + xxh_u8 const c2 = input[len >> 1]; + xxh_u8 const c3 = input[len - 1]; + xxh_u32 const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24) + | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8); + xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; + xxh_u64 const keyed = (xxh_u64)combined ^ bitflip; + return XXH64_avalanche(keyed); + } +} + +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t +XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(4 <= len && len <= 8); + seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; + { xxh_u32 const input1 = XXH_readLE32(input); + xxh_u32 const input2 = XXH_readLE32(input + len - 4); + xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed; + xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32); + xxh_u64 const keyed = input64 ^ bitflip; + return XXH3_rrmxmx(keyed, len); + } +} + +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t +XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(9 <= len && len <= 16); + { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed; + xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed; + xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1; + xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2; + xxh_u64 const acc = len + + XXH_swap64(input_lo) + input_hi + + XXH3_mul128_fold64(input_lo, input_hi); + return XXH3_avalanche(acc); + } +} + +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t +XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(len <= 16); + { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed); + if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed); + if (len) return XXH3_len_1to3_64b(input, len, secret, seed); + return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64))); + } +} + +/* + * DISCLAIMER: There are known *seed-dependent* multicollisions here due to + * multiplication by zero, affecting hashes of lengths 17 to 240. + * + * However, they are very unlikely. + * + * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all + * unseeded non-cryptographic hashes, it does not attempt to defend itself + * against specially crafted inputs, only random inputs. + * + * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes + * cancelling out the secret is taken an arbitrary number of times (addressed + * in XXH3_accumulate_512), this collision is very unlikely with random inputs + * and/or proper seeding: + * + * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a + * function that is only called up to 16 times per hash with up to 240 bytes of + * input. + * + * This is not too bad for a non-cryptographic hash function, especially with + * only 64 bit outputs. + * + * The 128-bit variant (which trades some speed for strength) is NOT affected + * by this, although it is always a good idea to use a proper seed if you care + * about strength. + */ +XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64) +{ +#if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */ + /* + * UGLY HACK: + * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in + * slower code. + * + * By forcing seed64 into a register, we disrupt the cost model and + * cause it to scalarize. See `XXH32_round()` + * + * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600, + * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on + * GCC 9.2, despite both emitting scalar code. + * + * GCC generates much better scalar code than Clang for the rest of XXH3, + * which is why finding a more optimal codepath is an interest. + */ + XXH_COMPILER_GUARD(seed64); +#endif + { xxh_u64 const input_lo = XXH_readLE64(input); + xxh_u64 const input_hi = XXH_readLE64(input+8); + return XXH3_mul128_fold64( + input_lo ^ (XXH_readLE64(secret) + seed64), + input_hi ^ (XXH_readLE64(secret+8) - seed64) + ); + } +} + +/* For mid range keys, XXH3 uses a Mum-hash variant. */ +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t +XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(16 < len && len <= 128); + + { xxh_u64 acc = len * XXH_PRIME64_1; +#if XXH_SIZE_OPT >= 1 + /* Smaller and cleaner, but slightly slower. */ + unsigned int i = (unsigned int)(len - 1) / 32; + do { + acc += XXH3_mix16B(input+16 * i, secret+32*i, seed); + acc += XXH3_mix16B(input+len-16*(i+1), secret+32*i+16, seed); + } while (i-- != 0); +#else + if (len > 32) { + if (len > 64) { + if (len > 96) { + acc += XXH3_mix16B(input+48, secret+96, seed); + acc += XXH3_mix16B(input+len-64, secret+112, seed); + } + acc += XXH3_mix16B(input+32, secret+64, seed); + acc += XXH3_mix16B(input+len-48, secret+80, seed); + } + acc += XXH3_mix16B(input+16, secret+32, seed); + acc += XXH3_mix16B(input+len-32, secret+48, seed); + } + acc += XXH3_mix16B(input+0, secret+0, seed); + acc += XXH3_mix16B(input+len-16, secret+16, seed); +#endif + return XXH3_avalanche(acc); + } +} + +/*! + * @brief Maximum size of "short" key in bytes. + */ +#define XXH3_MIDSIZE_MAX 240 + +XXH_NO_INLINE XXH_PUREF XXH64_hash_t +XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + + #define XXH3_MIDSIZE_STARTOFFSET 3 + #define XXH3_MIDSIZE_LASTOFFSET 17 + + { xxh_u64 acc = len * XXH_PRIME64_1; + xxh_u64 acc_end; + unsigned int const nbRounds = (unsigned int)len / 16; + unsigned int i; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + for (i=0; i<8; i++) { + acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed); + } + /* last bytes */ + acc_end = XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); + XXH_ASSERT(nbRounds >= 8); + acc = XXH3_avalanche(acc); +#if defined(__clang__) /* Clang */ \ + && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ + /* + * UGLY HACK: + * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86. + * In everywhere else, it uses scalar code. + * + * For 64->128-bit multiplies, even if the NEON was 100% optimal, it + * would still be slower than UMAAL (see XXH_mult64to128). + * + * Unfortunately, Clang doesn't handle the long multiplies properly and + * converts them to the nonexistent "vmulq_u64" intrinsic, which is then + * scalarized into an ugly mess of VMOV.32 instructions. + * + * This mess is difficult to avoid without turning autovectorization + * off completely, but they are usually relatively minor and/or not + * worth it to fix. + * + * This loop is the easiest to fix, as unlike XXH32, this pragma + * _actually works_ because it is a loop vectorization instead of an + * SLP vectorization. + */ + #pragma clang loop vectorize(disable) +#endif + for (i=8 ; i < nbRounds; i++) { + /* + * Prevents clang for unrolling the acc loop and interleaving with this one. + */ + XXH_COMPILER_GUARD(acc); + acc_end += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); + } + return XXH3_avalanche(acc + acc_end); + } +} + + +/* ======= Long Keys ======= */ + +#define XXH_STRIPE_LEN 64 +#define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */ +#define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64)) + +#ifdef XXH_OLD_NAMES +# define STRIPE_LEN XXH_STRIPE_LEN +# define ACC_NB XXH_ACC_NB +#endif + +#ifndef XXH_PREFETCH_DIST +# ifdef __clang__ +# define XXH_PREFETCH_DIST 320 +# else +# if (XXH_VECTOR == XXH_AVX512) +# define XXH_PREFETCH_DIST 512 +# else +# define XXH_PREFETCH_DIST 384 +# endif +# endif /* __clang__ */ +#endif /* XXH_PREFETCH_DIST */ + +/* + * These macros are to generate an XXH3_accumulate() function. + * The two arguments select the name suffix and target attribute. + * + * The name of this symbol is XXH3_accumulate_() and it calls + * XXH3_accumulate_512_(). + * + * It may be useful to hand implement this function if the compiler fails to + * optimize the inline function. + */ +#define XXH3_ACCUMULATE_TEMPLATE(name) \ +void \ +XXH3_accumulate_##name(xxh_u64* XXH_RESTRICT acc, \ + const xxh_u8* XXH_RESTRICT input, \ + const xxh_u8* XXH_RESTRICT secret, \ + size_t nbStripes) \ +{ \ + size_t n; \ + for (n = 0; n < nbStripes; n++ ) { \ + const xxh_u8* const in = input + n*XXH_STRIPE_LEN; \ + XXH_PREFETCH(in + XXH_PREFETCH_DIST); \ + XXH3_accumulate_512_##name( \ + acc, \ + in, \ + secret + n*XXH_SECRET_CONSUME_RATE); \ + } \ +} + + +XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64) +{ + if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64); + XXH_memcpy(dst, &v64, sizeof(v64)); +} + +/* Several intrinsic functions below are supposed to accept __int64 as argument, + * as documented in https://software.intel.com/sites/landingpage/IntrinsicsGuide/ . + * However, several environments do not define __int64 type, + * requiring a workaround. + */ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) + typedef int64_t xxh_i64; +#else + /* the following type must have a width of 64-bit */ + typedef long long xxh_i64; +#endif + + +/* + * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized. + * + * It is a hardened version of UMAC, based off of FARSH's implementation. + * + * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD + * implementations, and it is ridiculously fast. + * + * We harden it by mixing the original input to the accumulators as well as the product. + * + * This means that in the (relatively likely) case of a multiply by zero, the + * original input is preserved. + * + * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve + * cross-pollination, as otherwise the upper and lower halves would be + * essentially independent. + * + * This doesn't matter on 64-bit hashes since they all get merged together in + * the end, so we skip the extra step. + * + * Both XXH3_64bits and XXH3_128bits use this subroutine. + */ + +#if (XXH_VECTOR == XXH_AVX512) \ + || (defined(XXH_DISPATCH_AVX512) && XXH_DISPATCH_AVX512 != 0) + +#ifndef XXH_TARGET_AVX512 +# define XXH_TARGET_AVX512 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + __m512i* const xacc = (__m512i *) acc; + XXH_ASSERT((((size_t)acc) & 63) == 0); + XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i)); + + { + /* data_vec = input[0]; */ + __m512i const data_vec = _mm512_loadu_si512 (input); + /* key_vec = secret[0]; */ + __m512i const key_vec = _mm512_loadu_si512 (secret); + /* data_key = data_vec ^ key_vec; */ + __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m512i const data_key_lo = _mm512_srli_epi64 (data_key, 32); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo); + /* xacc[0] += swap(data_vec); */ + __m512i const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2)); + __m512i const sum = _mm512_add_epi64(*xacc, data_swap); + /* xacc[0] += product; */ + *xacc = _mm512_add_epi64(product, sum); + } +} +XXH_FORCE_INLINE XXH_TARGET_AVX512 XXH3_ACCUMULATE_TEMPLATE(avx512) + +/* + * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing. + * + * Multiplication isn't perfect, as explained by Google in HighwayHash: + * + * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to + * // varying degrees. In descending order of goodness, bytes + * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32. + * // As expected, the upper and lower bytes are much worse. + * + * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291 + * + * Since our algorithm uses a pseudorandom secret to add some variance into the + * mix, we don't need to (or want to) mix as often or as much as HighwayHash does. + * + * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid + * extraction. + * + * Both XXH3_64bits and XXH3_128bits use this subroutine. + */ + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 63) == 0); + XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i)); + { __m512i* const xacc = (__m512i*) acc; + const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1); + + /* xacc[0] ^= (xacc[0] >> 47) */ + __m512i const acc_vec = *xacc; + __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47); + /* xacc[0] ^= secret; */ + __m512i const key_vec = _mm512_loadu_si512 (secret); + __m512i const data_key = _mm512_ternarylogic_epi32(key_vec, acc_vec, shifted, 0x96 /* key_vec ^ acc_vec ^ shifted */); + + /* xacc[0] *= XXH_PRIME32_1; */ + __m512i const data_key_hi = _mm512_srli_epi64 (data_key, 32); + __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32); + __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32); + *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32)); + } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0); + XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64); + XXH_ASSERT(((size_t)customSecret & 63) == 0); + (void)(&XXH_writeLE64); + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i); + __m512i const seed_pos = _mm512_set1_epi64((xxh_i64)seed64); + __m512i const seed = _mm512_mask_sub_epi64(seed_pos, 0xAA, _mm512_set1_epi8(0), seed_pos); + + const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret); + __m512i* const dest = ( __m512i*) customSecret; + int i; + XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */ + XXH_ASSERT(((size_t)dest & 63) == 0); + for (i=0; i < nbRounds; ++i) { + dest[i] = _mm512_add_epi64(_mm512_load_si512(src + i), seed); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_AVX2) \ + || (defined(XXH_DISPATCH_AVX2) && XXH_DISPATCH_AVX2 != 0) + +#ifndef XXH_TARGET_AVX2 +# define XXH_TARGET_AVX2 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void +XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 31) == 0); + { __m256i* const xacc = (__m256i *) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xinput = (const __m256i *) input; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xsecret = (const __m256i *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) { + /* data_vec = xinput[i]; */ + __m256i const data_vec = _mm256_loadu_si256 (xinput+i); + /* key_vec = xsecret[i]; */ + __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); + /* data_key = data_vec ^ key_vec; */ + __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m256i const data_key_lo = _mm256_srli_epi64 (data_key, 32); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2)); + __m256i const sum = _mm256_add_epi64(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = _mm256_add_epi64(product, sum); + } } +} +XXH_FORCE_INLINE XXH_TARGET_AVX2 XXH3_ACCUMULATE_TEMPLATE(avx2) + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void +XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 31) == 0); + { __m256i* const xacc = (__m256i*) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xsecret = (const __m256i *) secret; + const __m256i prime32 = _mm256_set1_epi32((int)XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m256i const acc_vec = xacc[i]; + __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47); + __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted); + /* xacc[i] ^= xsecret; */ + __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); + __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m256i const data_key_hi = _mm256_srli_epi64 (data_key, 32); + __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32); + __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32); + xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32)); + } + } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0); + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE / sizeof(__m256i)) == 6); + XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64); + (void)(&XXH_writeLE64); + XXH_PREFETCH(customSecret); + { __m256i const seed = _mm256_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64, (xxh_i64)(0U - seed64), (xxh_i64)seed64); + + const __m256i* const src = (const __m256i*) ((const void*) XXH3_kSecret); + __m256i* dest = ( __m256i*) customSecret; + +# if defined(__GNUC__) || defined(__clang__) + /* + * On GCC & Clang, marking 'dest' as modified will cause the compiler: + * - do not extract the secret from sse registers in the internal loop + * - use less common registers, and avoid pushing these reg into stack + */ + XXH_COMPILER_GUARD(dest); +# endif + XXH_ASSERT(((size_t)src & 31) == 0); /* control alignment */ + XXH_ASSERT(((size_t)dest & 31) == 0); + + /* GCC -O2 need unroll loop manually */ + dest[0] = _mm256_add_epi64(_mm256_load_si256(src+0), seed); + dest[1] = _mm256_add_epi64(_mm256_load_si256(src+1), seed); + dest[2] = _mm256_add_epi64(_mm256_load_si256(src+2), seed); + dest[3] = _mm256_add_epi64(_mm256_load_si256(src+3), seed); + dest[4] = _mm256_add_epi64(_mm256_load_si256(src+4), seed); + dest[5] = _mm256_add_epi64(_mm256_load_si256(src+5), seed); + } +} + +#endif + +/* x86dispatch always generates SSE2 */ +#if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH) + +#ifndef XXH_TARGET_SSE2 +# define XXH_TARGET_SSE2 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void +XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + /* SSE2 is just a half-scale version of the AVX2 version. */ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { __m128i* const xacc = (__m128i *) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xinput = (const __m128i *) input; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xsecret = (const __m128i *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = _mm_loadu_si128 (xinput+i); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = _mm_loadu_si128 (xsecret+i); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = _mm_mul_epu32 (data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2)); + __m128i const sum = _mm_add_epi64(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = _mm_add_epi64(product, sum); + } } +} +XXH_FORCE_INLINE XXH_TARGET_SSE2 XXH3_ACCUMULATE_TEMPLATE(sse2) + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void +XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { __m128i* const xacc = (__m128i*) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = _mm_set1_epi32((int)XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = _mm_srli_epi64 (acc_vec, 47); + __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = _mm_loadu_si128 (xsecret+i); + __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32); + __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32); + xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32)); + } + } +} + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); + (void)(&XXH_writeLE64); + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i); + +# if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900 + /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */ + XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) }; + __m128i const seed = _mm_load_si128((__m128i const*)seed64x2); +# else + __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64); +# endif + int i; + + const void* const src16 = XXH3_kSecret; + __m128i* dst16 = (__m128i*) customSecret; +# if defined(__GNUC__) || defined(__clang__) + /* + * On GCC & Clang, marking 'dest' as modified will cause the compiler: + * - do not extract the secret from sse registers in the internal loop + * - use less common registers, and avoid pushing these reg into stack + */ + XXH_COMPILER_GUARD(dst16); +# endif + XXH_ASSERT(((size_t)src16 & 15) == 0); /* control alignment */ + XXH_ASSERT(((size_t)dst16 & 15) == 0); + + for (i=0; i < nbRounds; ++i) { + dst16[i] = _mm_add_epi64(_mm_load_si128((const __m128i *)src16+i), seed); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_NEON) + +/* forward declarations for the scalar routines */ +XXH_FORCE_INLINE void +XXH3_scalarRound(void* XXH_RESTRICT acc, void const* XXH_RESTRICT input, + void const* XXH_RESTRICT secret, size_t lane); + +XXH_FORCE_INLINE void +XXH3_scalarScrambleRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT secret, size_t lane); + +/*! + * @internal + * @brief The bulk processing loop for NEON and WASM SIMD128. + * + * The NEON code path is actually partially scalar when running on AArch64. This + * is to optimize the pipelining and can have up to 15% speedup depending on the + * CPU, and it also mitigates some GCC codegen issues. + * + * @see XXH3_NEON_LANES for configuring this and details about this optimization. + * + * NEON's 32-bit to 64-bit long multiply takes a half vector of 32-bit + * integers instead of the other platforms which mask full 64-bit vectors, + * so the setup is more complicated than just shifting right. + * + * Additionally, there is an optimization for 4 lanes at once noted below. + * + * Since, as stated, the most optimal amount of lanes for Cortexes is 6, + * there needs to be *three* versions of the accumulate operation used + * for the remaining 2 lanes. + * + * WASM's SIMD128 uses SIMDe's arm_neon.h polyfill because the intrinsics overlap + * nearly perfectly. + */ + +XXH_FORCE_INLINE void +XXH3_accumulate_512_neon( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + XXH_STATIC_ASSERT(XXH3_NEON_LANES > 0 && XXH3_NEON_LANES <= XXH_ACC_NB && XXH3_NEON_LANES % 2 == 0); + { /* GCC for darwin arm64 does not like aliasing here */ + xxh_aliasing_uint64x2_t* const xacc = (xxh_aliasing_uint64x2_t*) acc; + /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */ + uint8_t const* xinput = (const uint8_t *) input; + uint8_t const* xsecret = (const uint8_t *) secret; + + size_t i; +#ifdef __wasm_simd128__ + /* + * On WASM SIMD128, Clang emits direct address loads when XXH3_kSecret + * is constant propagated, which results in it converting it to this + * inside the loop: + * + * a = v128.load(XXH3_kSecret + 0 + $secret_offset, offset = 0) + * b = v128.load(XXH3_kSecret + 16 + $secret_offset, offset = 0) + * ... + * + * This requires a full 32-bit address immediate (and therefore a 6 byte + * instruction) as well as an add for each offset. + * + * Putting an asm guard prevents it from folding (at the cost of losing + * the alignment hint), and uses the free offset in `v128.load` instead + * of adding secret_offset each time which overall reduces code size by + * about a kilobyte and improves performance. + */ + XXH_COMPILER_GUARD(xsecret); +#endif + /* Scalar lanes use the normal scalarRound routine */ + for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) { + XXH3_scalarRound(acc, input, secret, i); + } + i = 0; + /* 4 NEON lanes at a time. */ + for (; i+1 < XXH3_NEON_LANES / 2; i+=2) { + /* data_vec = xinput[i]; */ + uint64x2_t data_vec_1 = XXH_vld1q_u64(xinput + (i * 16)); + uint64x2_t data_vec_2 = XXH_vld1q_u64(xinput + ((i+1) * 16)); + /* key_vec = xsecret[i]; */ + uint64x2_t key_vec_1 = XXH_vld1q_u64(xsecret + (i * 16)); + uint64x2_t key_vec_2 = XXH_vld1q_u64(xsecret + ((i+1) * 16)); + /* data_swap = swap(data_vec) */ + uint64x2_t data_swap_1 = vextq_u64(data_vec_1, data_vec_1, 1); + uint64x2_t data_swap_2 = vextq_u64(data_vec_2, data_vec_2, 1); + /* data_key = data_vec ^ key_vec; */ + uint64x2_t data_key_1 = veorq_u64(data_vec_1, key_vec_1); + uint64x2_t data_key_2 = veorq_u64(data_vec_2, key_vec_2); + + /* + * If we reinterpret the 64x2 vectors as 32x4 vectors, we can use a + * de-interleave operation for 4 lanes in 1 step with `vuzpq_u32` to + * get one vector with the low 32 bits of each lane, and one vector + * with the high 32 bits of each lane. + * + * The intrinsic returns a double vector because the original ARMv7-a + * instruction modified both arguments in place. AArch64 and SIMD128 emit + * two instructions from this intrinsic. + * + * [ dk11L | dk11H | dk12L | dk12H ] -> [ dk11L | dk12L | dk21L | dk22L ] + * [ dk21L | dk21H | dk22L | dk22H ] -> [ dk11H | dk12H | dk21H | dk22H ] + */ + uint32x4x2_t unzipped = vuzpq_u32( + vreinterpretq_u32_u64(data_key_1), + vreinterpretq_u32_u64(data_key_2) + ); + /* data_key_lo = data_key & 0xFFFFFFFF */ + uint32x4_t data_key_lo = unzipped.val[0]; + /* data_key_hi = data_key >> 32 */ + uint32x4_t data_key_hi = unzipped.val[1]; + /* + * Then, we can split the vectors horizontally and multiply which, as for most + * widening intrinsics, have a variant that works on both high half vectors + * for free on AArch64. A similar instruction is available on SIMD128. + * + * sum = data_swap + (u64x2) data_key_lo * (u64x2) data_key_hi + */ + uint64x2_t sum_1 = XXH_vmlal_low_u32(data_swap_1, data_key_lo, data_key_hi); + uint64x2_t sum_2 = XXH_vmlal_high_u32(data_swap_2, data_key_lo, data_key_hi); + /* + * Clang reorders + * a += b * c; // umlal swap.2d, dkl.2s, dkh.2s + * c += a; // add acc.2d, acc.2d, swap.2d + * to + * c += a; // add acc.2d, acc.2d, swap.2d + * c += b * c; // umlal acc.2d, dkl.2s, dkh.2s + * + * While it would make sense in theory since the addition is faster, + * for reasons likely related to umlal being limited to certain NEON + * pipelines, this is worse. A compiler guard fixes this. + */ + XXH_COMPILER_GUARD_CLANG_NEON(sum_1); + XXH_COMPILER_GUARD_CLANG_NEON(sum_2); + /* xacc[i] = acc_vec + sum; */ + xacc[i] = vaddq_u64(xacc[i], sum_1); + xacc[i+1] = vaddq_u64(xacc[i+1], sum_2); + } + /* Operate on the remaining NEON lanes 2 at a time. */ + for (; i < XXH3_NEON_LANES / 2; i++) { + /* data_vec = xinput[i]; */ + uint64x2_t data_vec = XXH_vld1q_u64(xinput + (i * 16)); + /* key_vec = xsecret[i]; */ + uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16)); + /* acc_vec_2 = swap(data_vec) */ + uint64x2_t data_swap = vextq_u64(data_vec, data_vec, 1); + /* data_key = data_vec ^ key_vec; */ + uint64x2_t data_key = veorq_u64(data_vec, key_vec); + /* For two lanes, just use VMOVN and VSHRN. */ + /* data_key_lo = data_key & 0xFFFFFFFF; */ + uint32x2_t data_key_lo = vmovn_u64(data_key); + /* data_key_hi = data_key >> 32; */ + uint32x2_t data_key_hi = vshrn_n_u64(data_key, 32); + /* sum = data_swap + (u64x2) data_key_lo * (u64x2) data_key_hi; */ + uint64x2_t sum = vmlal_u32(data_swap, data_key_lo, data_key_hi); + /* Same Clang workaround as before */ + XXH_COMPILER_GUARD_CLANG_NEON(sum); + /* xacc[i] = acc_vec + sum; */ + xacc[i] = vaddq_u64 (xacc[i], sum); + } + } +} +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(neon) + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + + { xxh_aliasing_uint64x2_t* xacc = (xxh_aliasing_uint64x2_t*) acc; + uint8_t const* xsecret = (uint8_t const*) secret; + + size_t i; + /* WASM uses operator overloads and doesn't need these. */ +#ifndef __wasm_simd128__ + /* { prime32_1, prime32_1 } */ + uint32x2_t const kPrimeLo = vdup_n_u32(XXH_PRIME32_1); + /* { 0, prime32_1, 0, prime32_1 } */ + uint32x4_t const kPrimeHi = vreinterpretq_u32_u64(vdupq_n_u64((xxh_u64)XXH_PRIME32_1 << 32)); +#endif + + /* AArch64 uses both scalar and neon at the same time */ + for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) { + XXH3_scalarScrambleRound(acc, secret, i); + } + for (i=0; i < XXH3_NEON_LANES / 2; i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + uint64x2_t acc_vec = xacc[i]; + uint64x2_t shifted = vshrq_n_u64(acc_vec, 47); + uint64x2_t data_vec = veorq_u64(acc_vec, shifted); + + /* xacc[i] ^= xsecret[i]; */ + uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16)); + uint64x2_t data_key = veorq_u64(data_vec, key_vec); + /* xacc[i] *= XXH_PRIME32_1 */ +#ifdef __wasm_simd128__ + /* SIMD128 has multiply by u64x2, use it instead of expanding and scalarizing */ + xacc[i] = data_key * XXH_PRIME32_1; +#else + /* + * Expanded version with portable NEON intrinsics + * + * lo(x) * lo(y) + (hi(x) * lo(y) << 32) + * + * prod_hi = hi(data_key) * lo(prime) << 32 + * + * Since we only need 32 bits of this multiply a trick can be used, reinterpreting the vector + * as a uint32x4_t and multiplying by { 0, prime, 0, prime } to cancel out the unwanted bits + * and avoid the shift. + */ + uint32x4_t prod_hi = vmulq_u32 (vreinterpretq_u32_u64(data_key), kPrimeHi); + /* Extract low bits for vmlal_u32 */ + uint32x2_t data_key_lo = vmovn_u64(data_key); + /* xacc[i] = prod_hi + lo(data_key) * XXH_PRIME32_1; */ + xacc[i] = vmlal_u32(vreinterpretq_u64_u32(prod_hi), data_key_lo, kPrimeLo); +#endif + } + } +} +#endif + +#if (XXH_VECTOR == XXH_VSX) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + /* presumed aligned */ + xxh_aliasing_u64x2* const xacc = (xxh_aliasing_u64x2*) acc; + xxh_u8 const* const xinput = (xxh_u8 const*) input; /* no alignment restriction */ + xxh_u8 const* const xsecret = (xxh_u8 const*) secret; /* no alignment restriction */ + xxh_u64x2 const v32 = { 32, 32 }; + size_t i; + for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { + /* data_vec = xinput[i]; */ + xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + 16*i); + /* key_vec = xsecret[i]; */ + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + 16*i); + xxh_u64x2 const data_key = data_vec ^ key_vec; + /* shuffled = (data_key << 32) | (data_key >> 32); */ + xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32); + /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */ + xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled); + /* acc_vec = xacc[i]; */ + xxh_u64x2 acc_vec = xacc[i]; + acc_vec += product; + + /* swap high and low halves */ +#ifdef __s390x__ + acc_vec += vec_permi(data_vec, data_vec, 2); +#else + acc_vec += vec_xxpermdi(data_vec, data_vec, 2); +#endif + xacc[i] = acc_vec; + } +} +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(vsx) + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + + { xxh_aliasing_u64x2* const xacc = (xxh_aliasing_u64x2*) acc; + const xxh_u8* const xsecret = (const xxh_u8*) secret; + /* constants */ + xxh_u64x2 const v32 = { 32, 32 }; + xxh_u64x2 const v47 = { 47, 47 }; + xxh_u32x4 const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 }; + size_t i; + for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + xxh_u64x2 const acc_vec = xacc[i]; + xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47); + + /* xacc[i] ^= xsecret[i]; */ + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + 16*i); + xxh_u64x2 const data_key = data_vec ^ key_vec; + + /* xacc[i] *= XXH_PRIME32_1 */ + /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */ + xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime); + /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */ + xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime); + xacc[i] = prod_odd + (prod_even << v32); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_SVE) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_sve( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + uint64_t *xacc = (uint64_t *)acc; + const uint64_t *xinput = (const uint64_t *)(const void *)input; + const uint64_t *xsecret = (const uint64_t *)(const void *)secret; + svuint64_t kSwap = sveor_n_u64_z(svptrue_b64(), svindex_u64(0, 1), 1); + uint64_t element_count = svcntd(); + if (element_count >= 8) { + svbool_t mask = svptrue_pat_b64(SV_VL8); + svuint64_t vacc = svld1_u64(mask, xacc); + ACCRND(vacc, 0); + svst1_u64(mask, xacc, vacc); + } else if (element_count == 2) { /* sve128 */ + svbool_t mask = svptrue_pat_b64(SV_VL2); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 2); + svuint64_t acc2 = svld1_u64(mask, xacc + 4); + svuint64_t acc3 = svld1_u64(mask, xacc + 6); + ACCRND(acc0, 0); + ACCRND(acc1, 2); + ACCRND(acc2, 4); + ACCRND(acc3, 6); + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 2, acc1); + svst1_u64(mask, xacc + 4, acc2); + svst1_u64(mask, xacc + 6, acc3); + } else { + svbool_t mask = svptrue_pat_b64(SV_VL4); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 4); + ACCRND(acc0, 0); + ACCRND(acc1, 4); + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 4, acc1); + } +} + +XXH_FORCE_INLINE void +XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, + size_t nbStripes) +{ + if (nbStripes != 0) { + uint64_t *xacc = (uint64_t *)acc; + const uint64_t *xinput = (const uint64_t *)(const void *)input; + const uint64_t *xsecret = (const uint64_t *)(const void *)secret; + svuint64_t kSwap = sveor_n_u64_z(svptrue_b64(), svindex_u64(0, 1), 1); + uint64_t element_count = svcntd(); + if (element_count >= 8) { + svbool_t mask = svptrue_pat_b64(SV_VL8); + svuint64_t vacc = svld1_u64(mask, xacc + 0); + do { + /* svprfd(svbool_t, void *, enum svfprop); */ + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(vacc, 0); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, vacc); + } else if (element_count == 2) { /* sve128 */ + svbool_t mask = svptrue_pat_b64(SV_VL2); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 2); + svuint64_t acc2 = svld1_u64(mask, xacc + 4); + svuint64_t acc3 = svld1_u64(mask, xacc + 6); + do { + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(acc0, 0); + ACCRND(acc1, 2); + ACCRND(acc2, 4); + ACCRND(acc3, 6); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 2, acc1); + svst1_u64(mask, xacc + 4, acc2); + svst1_u64(mask, xacc + 6, acc3); + } else { + svbool_t mask = svptrue_pat_b64(SV_VL4); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 4); + do { + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(acc0, 0); + ACCRND(acc1, 4); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 4, acc1); + } + } +} + +#endif + +/* scalar variants - universal */ + +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) +/* + * In XXH3_scalarRound(), GCC and Clang have a similar codegen issue, where they + * emit an excess mask and a full 64-bit multiply-add (MADD X-form). + * + * While this might not seem like much, as AArch64 is a 64-bit architecture, only + * big Cortex designs have a full 64-bit multiplier. + * + * On the little cores, the smaller 32-bit multiplier is used, and full 64-bit + * multiplies expand to 2-3 multiplies in microcode. This has a major penalty + * of up to 4 latency cycles and 2 stall cycles in the multiply pipeline. + * + * Thankfully, AArch64 still provides the 32-bit long multiply-add (UMADDL) which does + * not have this penalty and does the mask automatically. + */ +XXH_FORCE_INLINE xxh_u64 +XXH_mult32to64_add64(xxh_u64 lhs, xxh_u64 rhs, xxh_u64 acc) +{ + xxh_u64 ret; + /* note: %x = 64-bit register, %w = 32-bit register */ + __asm__("umaddl %x0, %w1, %w2, %x3" : "=r" (ret) : "r" (lhs), "r" (rhs), "r" (acc)); + return ret; +} +#else +XXH_FORCE_INLINE xxh_u64 +XXH_mult32to64_add64(xxh_u64 lhs, xxh_u64 rhs, xxh_u64 acc) +{ + return XXH_mult32to64((xxh_u32)lhs, (xxh_u32)rhs) + acc; +} +#endif + +/*! + * @internal + * @brief Scalar round for @ref XXH3_accumulate_512_scalar(). + * + * This is extracted to its own function because the NEON path uses a combination + * of NEON and scalar. + */ +XXH_FORCE_INLINE void +XXH3_scalarRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT input, + void const* XXH_RESTRICT secret, + size_t lane) +{ + xxh_u64* xacc = (xxh_u64*) acc; + xxh_u8 const* xinput = (xxh_u8 const*) input; + xxh_u8 const* xsecret = (xxh_u8 const*) secret; + XXH_ASSERT(lane < XXH_ACC_NB); + XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0); + { + xxh_u64 const data_val = XXH_readLE64(xinput + lane * 8); + xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + lane * 8); + xacc[lane ^ 1] += data_val; /* swap adjacent lanes */ + xacc[lane] = XXH_mult32to64_add64(data_key /* & 0xFFFFFFFF */, data_key >> 32, xacc[lane]); + } +} + +/*! + * @internal + * @brief Processes a 64 byte block of data using the scalar path. + */ +XXH_FORCE_INLINE void +XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + size_t i; + /* ARM GCC refuses to unroll this loop, resulting in a 24% slowdown on ARMv6. */ +#if defined(__GNUC__) && !defined(__clang__) \ + && (defined(__arm__) || defined(__thumb2__)) \ + && defined(__ARM_FEATURE_UNALIGNED) /* no unaligned access just wastes bytes */ \ + && XXH_SIZE_OPT <= 0 +# pragma GCC unroll 8 +#endif + for (i=0; i < XXH_ACC_NB; i++) { + XXH3_scalarRound(acc, input, secret, i); + } +} +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(scalar) + +/*! + * @internal + * @brief Scalar scramble step for @ref XXH3_scrambleAcc_scalar(). + * + * This is extracted to its own function because the NEON path uses a combination + * of NEON and scalar. + */ +XXH_FORCE_INLINE void +XXH3_scalarScrambleRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT secret, + size_t lane) +{ + xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ + const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ + XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0); + XXH_ASSERT(lane < XXH_ACC_NB); + { + xxh_u64 const key64 = XXH_readLE64(xsecret + lane * 8); + xxh_u64 acc64 = xacc[lane]; + acc64 = XXH_xorshift64(acc64, 47); + acc64 ^= key64; + acc64 *= XXH_PRIME32_1; + xacc[lane] = acc64; + } +} + +/*! + * @internal + * @brief Scrambles the accumulators after a large chunk has been read + */ +XXH_FORCE_INLINE void +XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + size_t i; + for (i=0; i < XXH_ACC_NB; i++) { + XXH3_scalarScrambleRound(acc, secret, i); + } +} + +XXH_FORCE_INLINE void +XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + /* + * We need a separate pointer for the hack below, + * which requires a non-const pointer. + * Any decent compiler will optimize this out otherwise. + */ + const xxh_u8* kSecretPtr = XXH3_kSecret; + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); + +#if defined(__GNUC__) && defined(__aarch64__) + /* + * UGLY HACK: + * GCC and Clang generate a bunch of MOV/MOVK pairs for aarch64, and they are + * placed sequentially, in order, at the top of the unrolled loop. + * + * While MOVK is great for generating constants (2 cycles for a 64-bit + * constant compared to 4 cycles for LDR), it fights for bandwidth with + * the arithmetic instructions. + * + * I L S + * MOVK + * MOVK + * MOVK + * MOVK + * ADD + * SUB STR + * STR + * By forcing loads from memory (as the asm line causes the compiler to assume + * that XXH3_kSecretPtr has been changed), the pipelines are used more + * efficiently: + * I L S + * LDR + * ADD LDR + * SUB STR + * STR + * + * See XXH3_NEON_LANES for details on the pipsline. + * + * XXH3_64bits_withSeed, len == 256, Snapdragon 835 + * without hack: 2654.4 MB/s + * with hack: 3202.9 MB/s + */ + XXH_COMPILER_GUARD(kSecretPtr); +#endif + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16; + int i; + for (i=0; i < nbRounds; i++) { + /* + * The asm hack causes the compiler to assume that kSecretPtr aliases with + * customSecret, and on aarch64, this prevented LDP from merging two + * loads together for free. Putting the loads together before the stores + * properly generates LDP. + */ + xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64; + xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64; + XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo); + XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi); + } } +} + + +typedef void (*XXH3_f_accumulate)(xxh_u64* XXH_RESTRICT, const xxh_u8* XXH_RESTRICT, const xxh_u8* XXH_RESTRICT, size_t); +typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*); +typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); + + +#if (XXH_VECTOR == XXH_AVX512) + +#define XXH3_accumulate_512 XXH3_accumulate_512_avx512 +#define XXH3_accumulate XXH3_accumulate_avx512 +#define XXH3_scrambleAcc XXH3_scrambleAcc_avx512 +#define XXH3_initCustomSecret XXH3_initCustomSecret_avx512 + +#elif (XXH_VECTOR == XXH_AVX2) + +#define XXH3_accumulate_512 XXH3_accumulate_512_avx2 +#define XXH3_accumulate XXH3_accumulate_avx2 +#define XXH3_scrambleAcc XXH3_scrambleAcc_avx2 +#define XXH3_initCustomSecret XXH3_initCustomSecret_avx2 + +#elif (XXH_VECTOR == XXH_SSE2) + +#define XXH3_accumulate_512 XXH3_accumulate_512_sse2 +#define XXH3_accumulate XXH3_accumulate_sse2 +#define XXH3_scrambleAcc XXH3_scrambleAcc_sse2 +#define XXH3_initCustomSecret XXH3_initCustomSecret_sse2 + +#elif (XXH_VECTOR == XXH_NEON) + +#define XXH3_accumulate_512 XXH3_accumulate_512_neon +#define XXH3_accumulate XXH3_accumulate_neon +#define XXH3_scrambleAcc XXH3_scrambleAcc_neon +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#elif (XXH_VECTOR == XXH_VSX) + +#define XXH3_accumulate_512 XXH3_accumulate_512_vsx +#define XXH3_accumulate XXH3_accumulate_vsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_vsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#elif (XXH_VECTOR == XXH_SVE) +#define XXH3_accumulate_512 XXH3_accumulate_512_sve +#define XXH3_accumulate XXH3_accumulate_sve +#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#else /* scalar */ + +#define XXH3_accumulate_512 XXH3_accumulate_512_scalar +#define XXH3_accumulate XXH3_accumulate_scalar +#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#endif + +#if XXH_SIZE_OPT >= 1 /* don't do SIMD for initialization */ +# undef XXH3_initCustomSecret +# define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#endif + +XXH_FORCE_INLINE void +XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate f_acc, + XXH3_f_scrambleAcc f_scramble) +{ + size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; + size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock; + size_t const nb_blocks = (len - 1) / block_len; + + size_t n; + + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); + + for (n = 0; n < nb_blocks; n++) { + f_acc(acc, input + n*block_len, secret, nbStripesPerBlock); + f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN); + } + + /* last partial block */ + XXH_ASSERT(len > XXH_STRIPE_LEN); + { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN; + XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE)); + f_acc(acc, input + nb_blocks*block_len, secret, nbStripes); + + /* last stripe */ + { const xxh_u8* const p = input + len - XXH_STRIPE_LEN; +#define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */ + XXH3_accumulate_512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); + } } +} + +XXH_FORCE_INLINE xxh_u64 +XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret) +{ + return XXH3_mul128_fold64( + acc[0] ^ XXH_readLE64(secret), + acc[1] ^ XXH_readLE64(secret+8) ); +} + +static XXH64_hash_t +XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) +{ + xxh_u64 result64 = start; + size_t i = 0; + + for (i = 0; i < 4; i++) { + result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i); +#if defined(__clang__) /* Clang */ \ + && (defined(__arm__) || defined(__thumb__)) /* ARMv7 */ \ + && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ + /* + * UGLY HACK: + * Prevent autovectorization on Clang ARMv7-a. Exact same problem as + * the one in XXH3_len_129to240_64b. Speeds up shorter keys > 240b. + * XXH3_64bits, len == 256, Snapdragon 835: + * without hack: 2063.7 MB/s + * with hack: 2560.7 MB/s + */ + XXH_COMPILER_GUARD(result64); +#endif + } + + return XXH3_avalanche(result64); +} + +#define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ + XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, + const void* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate f_acc, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; + + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc, f_scramble); + + /* converge into final hash */ + XXH_STATIC_ASSERT(sizeof(acc) == 64); + /* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); +} + +/* + * It's important for performance to transmit secret's size (when it's static) + * so that the compiler can properly optimize the vectorized loop. + * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set. + * When the secret size is unknown, or on GCC 12 where the mix of NO_INLINE and FORCE_INLINE + * breaks -Og, this is XXH_NO_INLINE. + */ +XXH3_WITH_SECRET_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; + return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate, XXH3_scrambleAcc); +} + +/* + * It's preferable for performance that XXH3_hashLong is not inlined, + * as it results in a smaller function for small data, easier to the instruction cache. + * Note that inside this no_inline function, we do inline the internal loop, + * and provide a statically defined secret size to allow optimization of vector loop. + */ +XXH_NO_INLINE XXH_PUREF XXH64_hash_t +XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; (void)secret; (void)secretLen; + return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate, XXH3_scrambleAcc); +} + +/* + * XXH3_hashLong_64b_withSeed(): + * Generate a custom key based on alteration of default XXH3_kSecret with the seed, + * and then use this key for long mode hashing. + * + * This operation is decently fast but nonetheless costs a little bit of time. + * Try to avoid it whenever possible (typically when seed==0). + * + * It's important for performance that XXH3_hashLong is not inlined. Not sure + * why (uop cache maybe?), but the difference is large and easily measurable. + */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len, + XXH64_hash_t seed, + XXH3_f_accumulate f_acc, + XXH3_f_scrambleAcc f_scramble, + XXH3_f_initCustomSecret f_initSec) +{ +#if XXH_SIZE_OPT <= 0 + if (seed == 0) + return XXH3_hashLong_64b_internal(input, len, + XXH3_kSecret, sizeof(XXH3_kSecret), + f_acc, f_scramble); +#endif + { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; + f_initSec(secret, seed); + return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret), + f_acc, f_scramble); + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSeed(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)secret; (void)secretLen; + return XXH3_hashLong_64b_withSeed_internal(input, len, seed, + XXH3_accumulate, XXH3_scrambleAcc, XXH3_initCustomSecret); +} + + +typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t, + XXH64_hash_t, const xxh_u8* XXH_RESTRICT, size_t); + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen, + XXH3_hashLong64_f f_hashLong) +{ + XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN); + /* + * If an action is to be taken if `secretLen` condition is not respected, + * it should be done here. + * For now, it's a contract pre-condition. + * Adding a check and a branch here would cost performance at every hash. + * Also, note that function signature doesn't offer room to return an error. + */ + if (len <= 16) + return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64); + if (len <= 128) + return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + return f_hashLong(input, len, seed64, (const xxh_u8*)secret, secretLen); +} + + +/* === Public entry point === */ + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length) +{ + return XXH3_64bits_internal(input, length, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSecret(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize) +{ + return XXH3_64bits_internal(input, length, 0, secret, secretSize, XXH3_hashLong_64b_withSecret); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed) +{ + return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed); +} + +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) +{ + if (length <= XXH3_MIDSIZE_MAX) + return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); + return XXH3_hashLong_64b_withSecret(input, length, seed, (const xxh_u8*)secret, secretSize); +} + + +/* === XXH3 streaming === */ +#ifndef XXH_NO_STREAM +/* + * Malloc's a pointer that is always aligned to align. + * + * This must be freed with `XXH_alignedFree()`. + * + * malloc typically guarantees 16 byte alignment on 64-bit systems and 8 byte + * alignment on 32-bit. This isn't enough for the 32 byte aligned loads in AVX2 + * or on 32-bit, the 16 byte aligned loads in SSE2 and NEON. + * + * This underalignment previously caused a rather obvious crash which went + * completely unnoticed due to XXH3_createState() not actually being tested. + * Credit to RedSpah for noticing this bug. + * + * The alignment is done manually: Functions like posix_memalign or _mm_malloc + * are avoided: To maintain portability, we would have to write a fallback + * like this anyways, and besides, testing for the existence of library + * functions without relying on external build tools is impossible. + * + * The method is simple: Overallocate, manually align, and store the offset + * to the original behind the returned pointer. + * + * Align must be a power of 2 and 8 <= align <= 128. + */ +static XXH_MALLOCF void* XXH_alignedMalloc(size_t s, size_t align) +{ + XXH_ASSERT(align <= 128 && align >= 8); /* range check */ + XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */ + XXH_ASSERT(s != 0 && s < (s + align)); /* empty/overflow */ + { /* Overallocate to make room for manual realignment and an offset byte */ + xxh_u8* base = (xxh_u8*)XXH_malloc(s + align); + if (base != NULL) { + /* + * Get the offset needed to align this pointer. + * + * Even if the returned pointer is aligned, there will always be + * at least one byte to store the offset to the original pointer. + */ + size_t offset = align - ((size_t)base & (align - 1)); /* base % align */ + /* Add the offset for the now-aligned pointer */ + xxh_u8* ptr = base + offset; + + XXH_ASSERT((size_t)ptr % align == 0); + + /* Store the offset immediately before the returned pointer. */ + ptr[-1] = (xxh_u8)offset; + return ptr; + } + return NULL; + } +} +/* + * Frees an aligned pointer allocated by XXH_alignedMalloc(). Don't pass + * normal malloc'd pointers, XXH_alignedMalloc has a specific data layout. + */ +static void XXH_alignedFree(void* p) +{ + if (p != NULL) { + xxh_u8* ptr = (xxh_u8*)p; + /* Get the offset byte we added in XXH_malloc. */ + xxh_u8 offset = ptr[-1]; + /* Free the original malloc'd pointer */ + xxh_u8* base = ptr - offset; + XXH_free(base); + } +} +/*! @ingroup XXH3_family */ +/*! + * @brief Allocate an @ref XXH3_state_t. + * + * @return An allocated pointer of @ref XXH3_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH3_freeState(). + */ +XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) +{ + XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64); + if (state==NULL) return NULL; + XXH3_INITSTATE(state); + return state; +} + +/*! @ingroup XXH3_family */ +/*! + * @brief Frees an @ref XXH3_state_t. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * + * @return @ref XXH_OK. + * + * @note Must be allocated with XXH3_createState(). + */ +XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) +{ + XXH_alignedFree(statePtr); + return XXH_OK; +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API void +XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOESCAPE const XXH3_state_t* src_state) +{ + XXH_memcpy(dst_state, src_state, sizeof(*dst_state)); +} + +static void +XXH3_reset_internal(XXH3_state_t* statePtr, + XXH64_hash_t seed, + const void* secret, size_t secretSize) +{ + size_t const initStart = offsetof(XXH3_state_t, bufferedSize); + size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart; + XXH_ASSERT(offsetof(XXH3_state_t, nbStripesPerBlock) > initStart); + XXH_ASSERT(statePtr != NULL); + /* set members from bufferedSize to nbStripesPerBlock (excluded) to 0 */ + memset((char*)statePtr + initStart, 0, initLength); + statePtr->acc[0] = XXH_PRIME32_3; + statePtr->acc[1] = XXH_PRIME64_1; + statePtr->acc[2] = XXH_PRIME64_2; + statePtr->acc[3] = XXH_PRIME64_3; + statePtr->acc[4] = XXH_PRIME64_4; + statePtr->acc[5] = XXH_PRIME32_2; + statePtr->acc[6] = XXH_PRIME64_5; + statePtr->acc[7] = XXH_PRIME32_1; + statePtr->seed = seed; + statePtr->useSeed = (seed != 0); + statePtr->extSecret = (const unsigned char*)secret; + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); + statePtr->secretLimit = secretSize - XXH_STRIPE_LEN; + statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE; +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_reset_internal(statePtr, 0, secret, secretSize); + if (secret == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; + return XXH_OK; +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed) +{ + if (statePtr == NULL) return XXH_ERROR; + if (seed==0) return XXH3_64bits_reset(statePtr); + if ((seed != statePtr->seed) || (statePtr->extSecret != NULL)) + XXH3_initCustomSecret(statePtr->customSecret, seed); + XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64) +{ + if (statePtr == NULL) return XXH_ERROR; + if (secret == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; + XXH3_reset_internal(statePtr, seed64, secret, secretSize); + statePtr->useSeed = 1; /* always, even if seed64==0 */ + return XXH_OK; +} + +/*! + * @internal + * @brief Processes a large input for XXH3_update() and XXH3_digest_long(). + * + * Unlike XXH3_hashLong_internal_loop(), this can process data that overlaps a block. + * + * @param acc Pointer to the 8 accumulator lanes + * @param nbStripesSoFarPtr In/out pointer to the number of leftover stripes in the block* + * @param nbStripesPerBlock Number of stripes in a block + * @param input Input pointer + * @param nbStripes Number of stripes to process + * @param secret Secret pointer + * @param secretLimit Offset of the last block in @p secret + * @param f_acc Pointer to an XXH3_accumulate implementation + * @param f_scramble Pointer to an XXH3_scrambleAcc implementation + * @return Pointer past the end of @p input after processing + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc, + size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock, + const xxh_u8* XXH_RESTRICT input, size_t nbStripes, + const xxh_u8* XXH_RESTRICT secret, size_t secretLimit, + XXH3_f_accumulate f_acc, + XXH3_f_scrambleAcc f_scramble) +{ + const xxh_u8* initialSecret = secret + *nbStripesSoFarPtr * XXH_SECRET_CONSUME_RATE; + /* Process full blocks */ + if (nbStripes >= (nbStripesPerBlock - *nbStripesSoFarPtr)) { + /* Process the initial partial block... */ + size_t nbStripesThisIter = nbStripesPerBlock - *nbStripesSoFarPtr; + + do { + /* Accumulate and scramble */ + f_acc(acc, input, initialSecret, nbStripesThisIter); + f_scramble(acc, secret + secretLimit); + input += nbStripesThisIter * XXH_STRIPE_LEN; + nbStripes -= nbStripesThisIter; + /* Then continue the loop with the full block size */ + nbStripesThisIter = nbStripesPerBlock; + initialSecret = secret; + } while (nbStripes >= nbStripesPerBlock); + *nbStripesSoFarPtr = 0; + } + /* Process a partial block */ + if (nbStripes > 0) { + f_acc(acc, input, initialSecret, nbStripes); + input += nbStripes * XXH_STRIPE_LEN; + *nbStripesSoFarPtr += nbStripes; + } + /* Return end pointer */ + return input; +} + +#ifndef XXH3_STREAM_USE_STACK +# if XXH_SIZE_OPT <= 0 && !defined(__clang__) /* clang doesn't need additional stack space */ +# define XXH3_STREAM_USE_STACK 1 +# endif +#endif +/* + * Both XXH3_64bits_update and XXH3_128bits_update use this routine. + */ +XXH_FORCE_INLINE XXH_errorcode +XXH3_update(XXH3_state_t* XXH_RESTRICT const state, + const xxh_u8* XXH_RESTRICT input, size_t len, + XXH3_f_accumulate f_acc, + XXH3_f_scrambleAcc f_scramble) +{ + if (input==NULL) { + XXH_ASSERT(len == 0); + return XXH_OK; + } + + XXH_ASSERT(state != NULL); + { const xxh_u8* const bEnd = input + len; + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; +#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1 + /* For some reason, gcc and MSVC seem to suffer greatly + * when operating accumulators directly into state. + * Operating into stack space seems to enable proper optimization. + * clang, on the other hand, doesn't seem to need this trick */ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; + XXH_memcpy(acc, state->acc, sizeof(acc)); +#else + xxh_u64* XXH_RESTRICT const acc = state->acc; +#endif + state->totalLen += len; + XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE); + + /* small input : just fill in tmp buffer */ + if (len <= XXH3_INTERNALBUFFER_SIZE - state->bufferedSize) { + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } + + /* total input is now > XXH3_INTERNALBUFFER_SIZE */ + #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN) + XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */ + + /* + * Internal buffer is partially filled (always, except at beginning) + * Complete it, then consume it. + */ + if (state->bufferedSize) { + size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize; + XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize); + input += loadSize; + XXH3_consumeStripes(acc, + &state->nbStripesSoFar, state->nbStripesPerBlock, + state->buffer, XXH3_INTERNALBUFFER_STRIPES, + secret, state->secretLimit, + f_acc, f_scramble); + state->bufferedSize = 0; + } + XXH_ASSERT(input < bEnd); + if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) { + size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN; + input = XXH3_consumeStripes(acc, + &state->nbStripesSoFar, state->nbStripesPerBlock, + input, nbStripes, + secret, state->secretLimit, + f_acc, f_scramble); + XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); + + } + /* Some remaining input (always) : buffer it */ + XXH_ASSERT(input < bEnd); + XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE); + XXH_ASSERT(state->bufferedSize == 0); + XXH_memcpy(state->buffer, input, (size_t)(bEnd-input)); + state->bufferedSize = (XXH32_hash_t)(bEnd-input); +#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1 + /* save stack accumulators into state */ + XXH_memcpy(state->acc, acc, sizeof(acc)); +#endif + } + + return XXH_OK; +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_update(XXH_NOESCAPE XXH3_state_t* state, XXH_NOESCAPE const void* input, size_t len) +{ + return XXH3_update(state, (const xxh_u8*)input, len, + XXH3_accumulate, XXH3_scrambleAcc); +} + + +XXH_FORCE_INLINE void +XXH3_digest_long (XXH64_hash_t* acc, + const XXH3_state_t* state, + const unsigned char* secret) +{ + xxh_u8 lastStripe[XXH_STRIPE_LEN]; + const xxh_u8* lastStripePtr; + + /* + * Digest on a local copy. This way, the state remains unaltered, and it can + * continue ingesting more input afterwards. + */ + XXH_memcpy(acc, state->acc, sizeof(state->acc)); + if (state->bufferedSize >= XXH_STRIPE_LEN) { + /* Consume remaining stripes then point to remaining data in buffer */ + size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN; + size_t nbStripesSoFar = state->nbStripesSoFar; + XXH3_consumeStripes(acc, + &nbStripesSoFar, state->nbStripesPerBlock, + state->buffer, nbStripes, + secret, state->secretLimit, + XXH3_accumulate, XXH3_scrambleAcc); + lastStripePtr = state->buffer + state->bufferedSize - XXH_STRIPE_LEN; + } else { /* bufferedSize < XXH_STRIPE_LEN */ + /* Copy to temp buffer */ + size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize; + XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */ + XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize); + XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize); + lastStripePtr = lastStripe; + } + /* Last stripe */ + XXH3_accumulate_512(acc, + lastStripePtr, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* state) +{ + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + if (state->totalLen > XXH3_MIDSIZE_MAX) { + XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; + XXH3_digest_long(acc, state, secret); + return XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)state->totalLen * XXH_PRIME64_1); + } + /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ + if (state->useSeed) + return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); + return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), + secret, state->secretLimit + XXH_STRIPE_LEN); +} +#endif /* !XXH_NO_STREAM */ + + +/* ========================================== + * XXH3 128 bits (a.k.a XXH128) + * ========================================== + * XXH3's 128-bit variant has better mixing and strength than the 64-bit variant, + * even without counting the significantly larger output size. + * + * For example, extra steps are taken to avoid the seed-dependent collisions + * in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B). + * + * This strength naturally comes at the cost of some speed, especially on short + * lengths. Note that longer hashes are about as fast as the 64-bit version + * due to it using only a slight modification of the 64-bit loop. + * + * XXH128 is also more oriented towards 64-bit machines. It is still extremely + * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64). + */ + +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t +XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + /* A doubled version of 1to3_64b with different constants. */ + XXH_ASSERT(input != NULL); + XXH_ASSERT(1 <= len && len <= 3); + XXH_ASSERT(secret != NULL); + /* + * len = 1: combinedl = { input[0], 0x01, input[0], input[0] } + * len = 2: combinedl = { input[1], 0x02, input[0], input[1] } + * len = 3: combinedl = { input[2], 0x03, input[0], input[1] } + */ + { xxh_u8 const c1 = input[0]; + xxh_u8 const c2 = input[len >> 1]; + xxh_u8 const c3 = input[len - 1]; + xxh_u32 const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24) + | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8); + xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13); + xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; + xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed; + xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl; + xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph; + XXH128_hash_t h128; + h128.low64 = XXH64_avalanche(keyed_lo); + h128.high64 = XXH64_avalanche(keyed_hi); + return h128; + } +} + +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t +XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(4 <= len && len <= 8); + seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; + { xxh_u32 const input_lo = XXH_readLE32(input); + xxh_u32 const input_hi = XXH_readLE32(input + len - 4); + xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32); + xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed; + xxh_u64 const keyed = input_64 ^ bitflip; + + /* Shift len to the left to ensure it is even, this avoids even multiplies. */ + XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2)); + + m128.high64 += (m128.low64 << 1); + m128.low64 ^= (m128.high64 >> 3); + + m128.low64 = XXH_xorshift64(m128.low64, 35); + m128.low64 *= PRIME_MX2; + m128.low64 = XXH_xorshift64(m128.low64, 28); + m128.high64 = XXH3_avalanche(m128.high64); + return m128; + } +} + +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t +XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(9 <= len && len <= 16); + { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed; + xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed; + xxh_u64 const input_lo = XXH_readLE64(input); + xxh_u64 input_hi = XXH_readLE64(input + len - 8); + XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1); + /* + * Put len in the middle of m128 to ensure that the length gets mixed to + * both the low and high bits in the 128x64 multiply below. + */ + m128.low64 += (xxh_u64)(len - 1) << 54; + input_hi ^= bitfliph; + /* + * Add the high 32 bits of input_hi to the high 32 bits of m128, then + * add the long product of the low 32 bits of input_hi and XXH_PRIME32_2 to + * the high 64 bits of m128. + * + * The best approach to this operation is different on 32-bit and 64-bit. + */ + if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */ + /* + * 32-bit optimized version, which is more readable. + * + * On 32-bit, it removes an ADC and delays a dependency between the two + * halves of m128.high64, but it generates an extra mask on 64-bit. + */ + m128.high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2); + } else { + /* + * 64-bit optimized (albeit more confusing) version. + * + * Uses some properties of addition and multiplication to remove the mask: + * + * Let: + * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF) + * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000) + * c = XXH_PRIME32_2 + * + * a + (b * c) + * Inverse Property: x + y - x == y + * a + (b * (1 + c - 1)) + * Distributive Property: x * (y + z) == (x * y) + (x * z) + * a + (b * 1) + (b * (c - 1)) + * Identity Property: x * 1 == x + * a + b + (b * (c - 1)) + * + * Substitute a, b, and c: + * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1)) + * + * Since input_hi.hi + input_hi.lo == input_hi, we get this: + * input_hi + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1)) + */ + m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1); + } + /* m128 ^= XXH_swap64(m128 >> 64); */ + m128.low64 ^= XXH_swap64(m128.high64); + + { /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */ + XXH128_hash_t h128 = XXH_mult64to128(m128.low64, XXH_PRIME64_2); + h128.high64 += m128.high64 * XXH_PRIME64_2; + + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = XXH3_avalanche(h128.high64); + return h128; + } } +} + +/* + * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN + */ +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t +XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(len <= 16); + { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed); + if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed); + if (len) return XXH3_len_1to3_128b(input, len, secret, seed); + { XXH128_hash_t h128; + xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72); + xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88); + h128.low64 = XXH64_avalanche(seed ^ bitflipl); + h128.high64 = XXH64_avalanche( seed ^ bitfliph); + return h128; + } } +} + +/* + * A bit slower than XXH3_mix16B, but handles multiply by zero better. + */ +XXH_FORCE_INLINE XXH128_hash_t +XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2, + const xxh_u8* secret, XXH64_hash_t seed) +{ + acc.low64 += XXH3_mix16B (input_1, secret+0, seed); + acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8); + acc.high64 += XXH3_mix16B (input_2, secret+16, seed); + acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8); + return acc; +} + + +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t +XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(16 < len && len <= 128); + + { XXH128_hash_t acc; + acc.low64 = len * XXH_PRIME64_1; + acc.high64 = 0; + +#if XXH_SIZE_OPT >= 1 + { + /* Smaller, but slightly slower. */ + unsigned int i = (unsigned int)(len - 1) / 32; + do { + acc = XXH128_mix32B(acc, input+16*i, input+len-16*(i+1), secret+32*i, seed); + } while (i-- != 0); + } +#else + if (len > 32) { + if (len > 64) { + if (len > 96) { + acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed); + } + acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed); + } + acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed); + } + acc = XXH128_mix32B(acc, input, input+len-16, secret, seed); +#endif + { XXH128_hash_t h128; + h128.low64 = acc.low64 + acc.high64; + h128.high64 = (acc.low64 * XXH_PRIME64_1) + + (acc.high64 * XXH_PRIME64_4) + + ((len - seed) * XXH_PRIME64_2); + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64); + return h128; + } + } +} + +XXH_NO_INLINE XXH_PUREF XXH128_hash_t +XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + + { XXH128_hash_t acc; + unsigned i; + acc.low64 = len * XXH_PRIME64_1; + acc.high64 = 0; + /* + * We set as `i` as offset + 32. We do this so that unchanged + * `len` can be used as upper bound. This reaches a sweet spot + * where both x86 and aarch64 get simple agen and good codegen + * for the loop. + */ + for (i = 32; i < 160; i += 32) { + acc = XXH128_mix32B(acc, + input + i - 32, + input + i - 16, + secret + i - 32, + seed); + } + acc.low64 = XXH3_avalanche(acc.low64); + acc.high64 = XXH3_avalanche(acc.high64); + /* + * NB: `i <= len` will duplicate the last 32-bytes if + * len % 32 was zero. This is an unfortunate necessity to keep + * the hash result stable. + */ + for (i=160; i <= len; i += 32) { + acc = XXH128_mix32B(acc, + input + i - 32, + input + i - 16, + secret + XXH3_MIDSIZE_STARTOFFSET + i - 160, + seed); + } + /* last bytes */ + acc = XXH128_mix32B(acc, + input + len - 16, + input + len - 32, + secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16, + (XXH64_hash_t)0 - seed); + + { XXH128_hash_t h128; + h128.low64 = acc.low64 + acc.high64; + h128.high64 = (acc.low64 * XXH_PRIME64_1) + + (acc.high64 * XXH_PRIME64_4) + + ((len - seed) * XXH_PRIME64_2); + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64); + return h128; + } + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate f_acc, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; + + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc, f_scramble); + + /* converge into final hash */ + XXH_STATIC_ASSERT(sizeof(acc) == 64); + XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + { XXH128_hash_t h128; + h128.low64 = XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)len * XXH_PRIME64_1); + h128.high64 = XXH3_mergeAccs(acc, + secret + secretSize + - sizeof(acc) - XXH_SECRET_MERGEACCS_START, + ~((xxh_u64)len * XXH_PRIME64_2)); + return h128; + } +} + +/* + * It's important for performance that XXH3_hashLong() is not inlined. + */ +XXH_NO_INLINE XXH_PUREF XXH128_hash_t +XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; (void)secret; (void)secretLen; + return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_accumulate, XXH3_scrambleAcc); +} + +/* + * It's important for performance to pass @p secretLen (when it's static) + * to the compiler, so that it can properly optimize the vectorized loop. + * + * When the secret size is unknown, or on GCC 12 where the mix of NO_INLINE and FORCE_INLINE + * breaks -Og, this is XXH_NO_INLINE. + */ +XXH3_WITH_SECRET_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; + return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen, + XXH3_accumulate, XXH3_scrambleAcc); +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + XXH3_f_accumulate f_acc, + XXH3_f_scrambleAcc f_scramble, + XXH3_f_initCustomSecret f_initSec) +{ + if (seed64 == 0) + return XXH3_hashLong_128b_internal(input, len, + XXH3_kSecret, sizeof(XXH3_kSecret), + f_acc, f_scramble); + { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; + f_initSec(secret, seed64); + return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret), + f_acc, f_scramble); + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSeed(const void* input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)secret; (void)secretLen; + return XXH3_hashLong_128b_withSeed_internal(input, len, seed64, + XXH3_accumulate, XXH3_scrambleAcc, XXH3_initCustomSecret); +} + +typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t, + XXH64_hash_t, const void* XXH_RESTRICT, size_t); + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_128bits_internal(const void* input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen, + XXH3_hashLong128_f f_hl128) +{ + XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN); + /* + * If an action is to be taken if `secret` conditions are not respected, + * it should be done here. + * For now, it's a contract pre-condition. + * Adding a check and a branch here would cost performance at every hash. + */ + if (len <= 16) + return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64); + if (len <= 128) + return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + return f_hl128(input, len, seed64, secret, secretLen); +} + + +/* === Public XXH128 API === */ + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* input, size_t len) +{ + return XXH3_128bits_internal(input, len, 0, + XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_hashLong_128b_default); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSecret(XXH_NOESCAPE const void* input, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize) +{ + return XXH3_128bits_internal(input, len, 0, + (const xxh_u8*)secret, secretSize, + XXH3_hashLong_128b_withSecret); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSeed(XXH_NOESCAPE const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_128bits_internal(input, len, seed, + XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_hashLong_128b_withSeed); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) +{ + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); + return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH128(XXH_NOESCAPE const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_128bits_withSeed(input, len, seed); +} + + +/* === XXH3 128-bit streaming === */ +#ifndef XXH_NO_STREAM +/* + * All initialization and update functions are identical to 64-bit streaming variant. + * The only difference is the finalization routine. + */ + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr) +{ + return XXH3_64bits_reset(statePtr); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize) +{ + return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed) +{ + return XXH3_64bits_reset_withSeed(statePtr, seed); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) +{ + return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_update(XXH_NOESCAPE XXH3_state_t* state, XXH_NOESCAPE const void* input, size_t len) +{ + return XXH3_64bits_update(state, input, len); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* state) +{ + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + if (state->totalLen > XXH3_MIDSIZE_MAX) { + XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; + XXH3_digest_long(acc, state, secret); + XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + { XXH128_hash_t h128; + h128.low64 = XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)state->totalLen * XXH_PRIME64_1); + h128.high64 = XXH3_mergeAccs(acc, + secret + state->secretLimit + XXH_STRIPE_LEN + - sizeof(acc) - XXH_SECRET_MERGEACCS_START, + ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); + return h128; + } + } + /* len <= XXH3_MIDSIZE_MAX : short code */ + if (state->seed) + return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); + return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), + secret, state->secretLimit + XXH_STRIPE_LEN); +} +#endif /* !XXH_NO_STREAM */ +/* 128-bit utility functions */ + +/* return : 1 is equal, 0 if different */ +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) +{ + /* note : XXH128_hash_t is compact, it has no padding byte */ + return !(memcmp(&h1, &h2, sizeof(h1))); +} + +/* This prototype is compatible with stdlib's qsort(). + * @return : >0 if *h128_1 > *h128_2 + * <0 if *h128_1 < *h128_2 + * =0 if *h128_1 == *h128_2 */ +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2) +{ + XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1; + XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2; + int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64); + /* note : bets that, in most cases, hash values are different */ + if (hcmp) return hcmp; + return (h1.low64 > h2.low64) - (h2.low64 > h1.low64); +} + + +/*====== Canonical representation ======*/ +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API void +XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) { + hash.high64 = XXH_swap64(hash.high64); + hash.low64 = XXH_swap64(hash.low64); + } + XXH_memcpy(dst, &hash.high64, sizeof(hash.high64)); + XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64)); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src) +{ + XXH128_hash_t h; + h.high64 = XXH_readBE64(src); + h.low64 = XXH_readBE64(src->digest + 8); + return h; +} + + + +/* ========================================== + * Secret generators + * ========================================== + */ +#define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x)) + +XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128) +{ + XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.low64 ); + XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 ); +} + +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer, size_t secretSize, XXH_NOESCAPE const void* customSeed, size_t customSeedSize) +{ +#if (XXH_DEBUGLEVEL >= 1) + XXH_ASSERT(secretBuffer != NULL); + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); +#else + /* production mode, assert() are disabled */ + if (secretBuffer == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; +#endif + + if (customSeedSize == 0) { + customSeed = XXH3_kSecret; + customSeedSize = XXH_SECRET_DEFAULT_SIZE; + } +#if (XXH_DEBUGLEVEL >= 1) + XXH_ASSERT(customSeed != NULL); +#else + if (customSeed == NULL) return XXH_ERROR; +#endif + + /* Fill secretBuffer with a copy of customSeed - repeat as needed */ + { size_t pos = 0; + while (pos < secretSize) { + size_t const toCopy = XXH_MIN((secretSize - pos), customSeedSize); + memcpy((char*)secretBuffer + pos, customSeed, toCopy); + pos += toCopy; + } } + + { size_t const nbSeg16 = secretSize / 16; + size_t n; + XXH128_canonical_t scrambler; + XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0)); + for (n=0; n +#include +#include + +#if defined(__GNUC__) && __GNUC__ >= 4 +# define ZSTD_memcpy(d,s,l) __builtin_memcpy((d),(s),(l)) +# define ZSTD_memmove(d,s,l) __builtin_memmove((d),(s),(l)) +# define ZSTD_memset(p,v,l) __builtin_memset((p),(v),(l)) +#else +# define ZSTD_memcpy(d,s,l) memcpy((d),(s),(l)) +# define ZSTD_memmove(d,s,l) memmove((d),(s),(l)) +# define ZSTD_memset(p,v,l) memset((p),(v),(l)) +#endif + +#endif /* ZSTD_DEPS_COMMON */ + +/* Need: + * ZSTD_malloc() + * ZSTD_free() + * ZSTD_calloc() + */ +#ifdef ZSTD_DEPS_NEED_MALLOC +#ifndef ZSTD_DEPS_MALLOC +#define ZSTD_DEPS_MALLOC + +#include + +#define ZSTD_malloc(s) malloc(s) +#define ZSTD_calloc(n,s) calloc((n), (s)) +#define ZSTD_free(p) free((p)) + +#endif /* ZSTD_DEPS_MALLOC */ +#endif /* ZSTD_DEPS_NEED_MALLOC */ + +/* + * Provides 64-bit math support. + * Need: + * U64 ZSTD_div64(U64 dividend, U32 divisor) + */ +#ifdef ZSTD_DEPS_NEED_MATH64 +#ifndef ZSTD_DEPS_MATH64 +#define ZSTD_DEPS_MATH64 + +#define ZSTD_div64(dividend, divisor) ((dividend) / (divisor)) + +#endif /* ZSTD_DEPS_MATH64 */ +#endif /* ZSTD_DEPS_NEED_MATH64 */ + +/* Need: + * assert() + */ +#ifdef ZSTD_DEPS_NEED_ASSERT +#ifndef ZSTD_DEPS_ASSERT +#define ZSTD_DEPS_ASSERT + +#include + +#endif /* ZSTD_DEPS_ASSERT */ +#endif /* ZSTD_DEPS_NEED_ASSERT */ + +/* Need: + * ZSTD_DEBUG_PRINT() + */ +#ifdef ZSTD_DEPS_NEED_IO +#ifndef ZSTD_DEPS_IO +#define ZSTD_DEPS_IO + +#include +#define ZSTD_DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__) + +#endif /* ZSTD_DEPS_IO */ +#endif /* ZSTD_DEPS_NEED_IO */ + +/* Only requested when is known to be present. + * Need: + * intptr_t + */ +#ifdef ZSTD_DEPS_NEED_STDINT +#ifndef ZSTD_DEPS_STDINT +#define ZSTD_DEPS_STDINT + +#include + +#endif /* ZSTD_DEPS_STDINT */ +#endif /* ZSTD_DEPS_NEED_STDINT */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/zstd_internal.h b/cpp/third_party/zstd-1.5.7/lib/common/zstd_internal.h new file mode 100644 index 000000000..2789a3591 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/zstd_internal.h @@ -0,0 +1,324 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CCOMMON_H_MODULE +#define ZSTD_CCOMMON_H_MODULE + +/* this module contains definitions which must be identical + * across compression, decompression and dictBuilder. + * It also contains a few functions useful to at least 2 of them + * and which benefit from being inlined */ + +/*-************************************* +* Dependencies +***************************************/ +#include "compiler.h" +#include "cpu.h" +#include "mem.h" +#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */ +#include "error_private.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "../zstd.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "huf.h" +#ifndef XXH_STATIC_LINKING_ONLY +# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */ +#endif +#include "xxhash.h" /* XXH_reset, update, digest */ +#ifndef ZSTD_NO_TRACE +# include "zstd_trace.h" +#else +# define ZSTD_TRACE 0 +#endif + +/* ---- static assert (debug) --- */ +#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) +#define ZSTD_isError ERR_isError /* for inlining */ +#define FSE_isError ERR_isError +#define HUF_isError ERR_isError + + +/*-************************************* +* shared macros +***************************************/ +#undef MIN +#undef MAX +#define MIN(a,b) ((a)<(b) ? (a) : (b)) +#define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define BOUNDED(min,val,max) (MAX(min,MIN(val,max))) + + +/*-************************************* +* Common constants +***************************************/ +#define ZSTD_OPT_NUM (1<<12) + +#define ZSTD_REP_NUM 3 /* number of repcodes */ +static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 }; + +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +#define BIT7 128 +#define BIT6 64 +#define BIT5 32 +#define BIT4 16 +#define BIT1 2 +#define BIT0 1 + +#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10 +static UNUSED_ATTR const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 }; +static UNUSED_ATTR const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 }; + +#define ZSTD_FRAMEIDSIZE 4 /* magic number size */ + +#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */ +static UNUSED_ATTR const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE; +typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; + +#define ZSTD_FRAMECHECKSUMSIZE 4 + +#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ +#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */) /* for a non-null block */ +#define MIN_LITERALS_FOR_4_STREAMS 6 + +typedef enum { set_basic, set_rle, set_compressed, set_repeat } SymbolEncodingType_e; + +#define LONGNBSEQ 0x7F00 + +#define MINMATCH 3 + +#define Litbits 8 +#define LitHufLog 11 +#define MaxLit ((1<= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN); + /* Separate out the first COPY16() call because the copy length is + * almost certain to be short, so the branches have different + * probabilities. Since it is almost certain to be short, only do + * one COPY16() in the first call. Then, do two calls per loop since + * at that point it is more likely to have a high trip count. + */ + ZSTD_copy16(op, ip); + if (16 >= length) return; + op += 16; + ip += 16; + do { + COPY16(op, ip); + COPY16(op, ip); + } + while (op < oend); + } +} + +MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + size_t const length = MIN(dstCapacity, srcSize); + if (length > 0) { + ZSTD_memcpy(dst, src, length); + } + return length; +} + +/* define "workspace is too large" as this number of times larger than needed */ +#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 + +/* when workspace is continuously too large + * during at least this number of times, + * context's memory usage is considered wasteful, + * because it's sized to handle a worst case scenario which rarely happens. + * In which case, resize it down to free some memory */ +#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 + +/* Controls whether the input/output buffer is buffered or stable. */ +typedef enum { + ZSTD_bm_buffered = 0, /* Buffer the input/output */ + ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */ +} ZSTD_bufferMode_e; + + +/*-******************************************* +* Private declarations +*********************************************/ + +/** + * Contains the compressed frame size and an upper-bound for the decompressed frame size. + * Note: before using `compressedSize`, check for errors using ZSTD_isError(). + * similarly, before using `decompressedBound`, check for errors using: + * `decompressedBound != ZSTD_CONTENTSIZE_ERROR` + */ +typedef struct { + size_t nbBlocks; + size_t compressedSize; + unsigned long long decompressedBound; +} ZSTD_frameSizeInfo; /* decompress & legacy */ + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */ + + +typedef struct { + blockType_e blockType; + U32 lastBlock; + U32 origSize; +} blockProperties_t; /* declared here for decompress and fullbench */ + +/*! ZSTD_getcBlockSize() : + * Provides the size of compressed block from block header `src` */ +/* Used by: decompress, fullbench */ +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, + blockProperties_t* bpPtr); + +/*! ZSTD_decodeSeqHeaders() : + * decode sequence header from src */ +/* Used by: zstd_decompress_block, fullbench */ +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, + const void* src, size_t srcSize); + +/** + * @returns true iff the CPU supports dynamic BMI2 dispatch. + */ +MEM_STATIC int ZSTD_cpuSupportsBmi2(void) +{ + ZSTD_cpuid_t cpuid = ZSTD_cpuid(); + return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid); +} + +#endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/cpp/third_party/zstd-1.5.7/lib/common/zstd_trace.h b/cpp/third_party/zstd-1.5.7/lib/common/zstd_trace.h new file mode 100644 index 000000000..d8eec1007 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/common/zstd_trace.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_TRACE_H +#define ZSTD_TRACE_H + +#include + +/* weak symbol support + * For now, enable conservatively: + * - Only GNUC + * - Only ELF + * - Only x86-64, i386, aarch64 and risc-v. + * Also, explicitly disable on platforms known not to work so they aren't + * forgotten in the future. + */ +#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \ + defined(__GNUC__) && defined(__ELF__) && \ + (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ + defined(_M_IX86) || defined(__aarch64__) || defined(__riscv)) && \ + !defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \ + !defined(__CYGWIN__) && !defined(_AIX) +# define ZSTD_HAVE_WEAK_SYMBOLS 1 +#else +# define ZSTD_HAVE_WEAK_SYMBOLS 0 +#endif +#if ZSTD_HAVE_WEAK_SYMBOLS +# define ZSTD_WEAK_ATTR __attribute__((__weak__)) +#else +# define ZSTD_WEAK_ATTR +#endif + +/* Only enable tracing when weak symbols are available. */ +#ifndef ZSTD_TRACE +# define ZSTD_TRACE ZSTD_HAVE_WEAK_SYMBOLS +#endif + +#if ZSTD_TRACE + +struct ZSTD_CCtx_s; +struct ZSTD_DCtx_s; +struct ZSTD_CCtx_params_s; + +typedef struct { + /** + * ZSTD_VERSION_NUMBER + * + * This is guaranteed to be the first member of ZSTD_trace. + * Otherwise, this struct is not stable between versions. If + * the version number does not match your expectation, you + * should not interpret the rest of the struct. + */ + unsigned version; + /** + * Non-zero if streaming (de)compression is used. + */ + int streaming; + /** + * The dictionary ID. + */ + unsigned dictionaryID; + /** + * Is the dictionary cold? + * Only set on decompression. + */ + int dictionaryIsCold; + /** + * The dictionary size or zero if no dictionary. + */ + size_t dictionarySize; + /** + * The uncompressed size of the data. + */ + size_t uncompressedSize; + /** + * The compressed size of the data. + */ + size_t compressedSize; + /** + * The fully resolved CCtx parameters (NULL on decompression). + */ + struct ZSTD_CCtx_params_s const* params; + /** + * The ZSTD_CCtx pointer (NULL on decompression). + */ + struct ZSTD_CCtx_s const* cctx; + /** + * The ZSTD_DCtx pointer (NULL on compression). + */ + struct ZSTD_DCtx_s const* dctx; +} ZSTD_Trace; + +/** + * A tracing context. It must be 0 when tracing is disabled. + * Otherwise, any non-zero value returned by a tracing begin() + * function is presented to any subsequent calls to end(). + * + * Any non-zero value is treated as tracing is enabled and not + * interpreted by the library. + * + * Two possible uses are: + * * A timestamp for when the begin() function was called. + * * A unique key identifying the (de)compression, like the + * address of the [dc]ctx pointer if you need to track + * more information than just a timestamp. + */ +typedef unsigned long long ZSTD_TraceCtx; + +/** + * Trace the beginning of a compression call. + * @param cctx The dctx pointer for the compression. + * It can be used as a key to map begin() to end(). + * @returns Non-zero if tracing is enabled. The return value is + * passed to ZSTD_trace_compress_end(). + */ +ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_compress_begin( + struct ZSTD_CCtx_s const* cctx); + +/** + * Trace the end of a compression call. + * @param ctx The return value of ZSTD_trace_compress_begin(). + * @param trace The zstd tracing info. + */ +ZSTD_WEAK_ATTR void ZSTD_trace_compress_end( + ZSTD_TraceCtx ctx, + ZSTD_Trace const* trace); + +/** + * Trace the beginning of a decompression call. + * @param dctx The dctx pointer for the decompression. + * It can be used as a key to map begin() to end(). + * @returns Non-zero if tracing is enabled. The return value is + * passed to ZSTD_trace_compress_end(). + */ +ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_decompress_begin( + struct ZSTD_DCtx_s const* dctx); + +/** + * Trace the end of a decompression call. + * @param ctx The return value of ZSTD_trace_decompress_begin(). + * @param trace The zstd tracing info. + */ +ZSTD_WEAK_ATTR void ZSTD_trace_decompress_end( + ZSTD_TraceCtx ctx, + ZSTD_Trace const* trace); + +#endif /* ZSTD_TRACE */ + +#endif /* ZSTD_TRACE_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/clevels.h b/cpp/third_party/zstd-1.5.7/lib/compress/clevels.h new file mode 100644 index 000000000..c18da465f --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/clevels.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CLEVELS_H +#define ZSTD_CLEVELS_H + +#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */ +#include "../zstd.h" + +/*-===== Pre-defined compression levels =====-*/ + +#define ZSTD_MAX_CLEVEL 22 + +#ifdef __GNUC__ +__attribute__((__unused__)) +#endif + +static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { +{ /* "default" - for any srcSize > 256 KB */ + /* W, C, H, S, L, TL, strat */ + { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */ + { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */ + { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */ + { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */ + { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */ + { 21, 18, 19, 3, 5, 2, ZSTD_greedy }, /* level 5 */ + { 21, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6 */ + { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */ + { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 8 */ + { 22, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ + { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 10 */ + { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 11 */ + { 22, 22, 23, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */ + { 22, 22, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */ + { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ + { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ + { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */ + { 23, 23, 22, 5, 4, 64, ZSTD_btopt }, /* level 17 */ + { 23, 23, 22, 6, 3, 64, ZSTD_btultra }, /* level 18 */ + { 23, 24, 22, 7, 3,256, ZSTD_btultra2}, /* level 19 */ + { 25, 25, 23, 7, 3,256, ZSTD_btultra2}, /* level 20 */ + { 26, 26, 24, 7, 3,512, ZSTD_btultra2}, /* level 21 */ + { 27, 27, 25, 9, 3,999, ZSTD_btultra2}, /* level 22 */ +}, +{ /* for srcSize <= 256 KB */ + /* W, C, H, S, L, T, strat */ + { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */ + { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */ + { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */ + { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/ + { 18, 17, 18, 5, 5, 2, ZSTD_greedy }, /* level 5.*/ + { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/ + { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */ + { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/ + { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/ + { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */ + { 18, 18, 19, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ + { 18, 18, 19, 6, 3,128, ZSTD_btopt }, /* level 15.*/ + { 18, 19, 19, 6, 3,128, ZSTD_btultra }, /* level 16.*/ + { 18, 19, 19, 8, 3,256, ZSTD_btultra }, /* level 17.*/ + { 18, 19, 19, 6, 3,128, ZSTD_btultra2}, /* level 18.*/ + { 18, 19, 19, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 18, 19, 19, 10, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 18, 19, 19, 12, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 18, 19, 19, 13, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +{ /* for srcSize <= 128 KB */ + /* W, C, H, S, L, T, strat */ + { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */ + { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */ + { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */ + { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */ + { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */ + { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */ + { 17, 16, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 17, 16, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */ + { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */ + { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/ + { 17, 18, 17, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ + { 17, 18, 17, 6, 3,256, ZSTD_btopt }, /* level 15.*/ + { 17, 18, 17, 6, 3,128, ZSTD_btultra }, /* level 16.*/ + { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 17.*/ + { 17, 18, 17, 10, 3,512, ZSTD_btultra }, /* level 18.*/ + { 17, 18, 17, 5, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 17, 18, 17, 7, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 17, 18, 17, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 17, 18, 17, 11, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +{ /* for srcSize <= 16 KB */ + /* W, C, H, S, L, T, strat */ + { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */ + { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */ + { 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */ + { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */ + { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/ + { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */ + { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/ + { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/ + { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/ + { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/ + { 14, 15, 14, 4, 3, 24, ZSTD_btopt }, /* level 12.*/ + { 14, 15, 14, 5, 3, 32, ZSTD_btultra }, /* level 13.*/ + { 14, 15, 15, 6, 3, 64, ZSTD_btultra }, /* level 14.*/ + { 14, 15, 15, 7, 3,256, ZSTD_btultra }, /* level 15.*/ + { 14, 15, 15, 5, 3, 48, ZSTD_btultra2}, /* level 16.*/ + { 14, 15, 15, 6, 3,128, ZSTD_btultra2}, /* level 17.*/ + { 14, 15, 15, 7, 3,256, ZSTD_btultra2}, /* level 18.*/ + { 14, 15, 15, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 14, 15, 15, 8, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 14, 15, 15, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 14, 15, 15, 10, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +}; + + + +#endif /* ZSTD_CLEVELS_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/fse_compress.c b/cpp/third_party/zstd-1.5.7/lib/compress/fse_compress.c new file mode 100644 index 000000000..1ce3cf16a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/fse_compress.c @@ -0,0 +1,625 @@ +/* ****************************************************************** + * FSE : Finite State Entropy encoder + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Includes +****************************************************************/ +#include "../common/compiler.h" +#include "../common/mem.h" /* U32, U16, etc. */ +#include "../common/debug.h" /* assert, DEBUGLOG */ +#include "hist.h" /* HIST_count_wksp */ +#include "../common/bitstream.h" +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/error_private.h" +#define ZSTD_DEPS_NEED_MALLOC +#define ZSTD_DEPS_NEED_MATH64 +#include "../common/zstd_deps.h" /* ZSTD_memset */ +#include "../common/bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + + +/* Function templates */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * wkspSize should be sized to handle worst case situation, which is `1<>1 : 1) ; + FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); + U32 const step = FSE_TABLESTEP(tableSize); + U32 const maxSV1 = maxSymbolValue+1; + + U16* cumul = (U16*)workSpace; /* size = maxSV1 */ + FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */ + + U32 highThreshold = tableSize-1; + + assert(((size_t)workSpace & 1) == 0); /* Must be 2 bytes-aligned */ + if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge); + /* CTable header */ + tableU16[-2] = (U16) tableLog; + tableU16[-1] = (U16) maxSymbolValue; + assert(tableLog < 16); /* required for threshold strategy to work */ + + /* For explanations on how to distribute symbol values over the table : + * https://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */ + + #ifdef __clang_analyzer__ + ZSTD_memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */ + #endif + + /* symbol start positions */ + { U32 u; + cumul[0] = 0; + for (u=1; u <= maxSV1; u++) { + if (normalizedCounter[u-1]==-1) { /* Low proba symbol */ + cumul[u] = cumul[u-1] + 1; + tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1); + } else { + assert(normalizedCounter[u-1] >= 0); + cumul[u] = cumul[u-1] + (U16)normalizedCounter[u-1]; + assert(cumul[u] >= cumul[u-1]); /* no overflow */ + } } + cumul[maxSV1] = (U16)(tableSize+1); + } + + /* Spread symbols */ + if (highThreshold == tableSize - 1) { + /* Case for no low prob count symbols. Lay down 8 bytes at a time + * to reduce branch misses since we are operating on a small block + */ + BYTE* const spread = tableSymbol + tableSize; /* size = tableSize + 8 (may write beyond tableSize) */ + { U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s=0); + pos += (size_t)n; + } + } + /* Spread symbols across the table. Lack of lowprob symbols means that + * we don't need variable sized inner loop, so we can unroll the loop and + * reduce branch misses. + */ + { size_t position = 0; + size_t s; + size_t const unroll = 2; /* Experimentally determined optimal unroll */ + assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ + for (s = 0; s < (size_t)tableSize; s += unroll) { + size_t u; + for (u = 0; u < unroll; ++u) { + size_t const uPosition = (position + (u * step)) & tableMask; + tableSymbol[uPosition] = spread[s + u]; + } + position = (position + (unroll * step)) & tableMask; + } + assert(position == 0); /* Must have initialized all positions */ + } + } else { + U32 position = 0; + U32 symbol; + for (symbol=0; symbol highThreshold) + position = (position + step) & tableMask; /* Low proba area */ + } } + assert(position==0); /* Must have initialized all positions */ + } + + /* Build table */ + { U32 u; for (u=0; u 1); + { U32 const maxBitsOut = tableLog - ZSTD_highbit32 ((U32)normalizedCounter[s]-1); + U32 const minStatePlus = (U32)normalizedCounter[s] << maxBitsOut; + symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus; + symbolTT[s].deltaFindState = (int)(total - (unsigned)normalizedCounter[s]); + total += (unsigned)normalizedCounter[s]; + } } } } + +#if 0 /* debug : symbol costs */ + DEBUGLOG(5, "\n --- table statistics : "); + { U32 symbol; + for (symbol=0; symbol<=maxSymbolValue; symbol++) { + DEBUGLOG(5, "%3u: w=%3i, maxBits=%u, fracBits=%.2f", + symbol, normalizedCounter[symbol], + FSE_getMaxNbBits(symbolTT, symbol), + (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256); + } } +#endif + + return 0; +} + + + +#ifndef FSE_COMMONDEFS_ONLY + +/*-************************************************************** +* FSE NCount encoding +****************************************************************/ +size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) +{ + size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog + + 4 /* bitCount initialized at 4 */ + + 2 /* first two symbols may use one additional bit each */) / 8) + + 1 /* round up to whole nb bytes */ + + 2 /* additional two bytes for bitstream flush */; + return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ +} + +static size_t +FSE_writeNCount_generic (void* header, size_t headerBufferSize, + const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, + unsigned writeIsSafe) +{ + BYTE* const ostart = (BYTE*) header; + BYTE* out = ostart; + BYTE* const oend = ostart + headerBufferSize; + int nbBits; + const int tableSize = 1 << tableLog; + int remaining; + int threshold; + U32 bitStream = 0; + int bitCount = 0; + unsigned symbol = 0; + unsigned const alphabetSize = maxSymbolValue + 1; + int previousIs0 = 0; + + /* Table Size */ + bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount; + bitCount += 4; + + /* Init */ + remaining = tableSize+1; /* +1 for extra accuracy */ + threshold = tableSize; + nbBits = (int)tableLog+1; + + while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */ + if (previousIs0) { + unsigned start = symbol; + while ((symbol < alphabetSize) && !normalizedCounter[symbol]) symbol++; + if (symbol == alphabetSize) break; /* incorrect distribution */ + while (symbol >= start+24) { + start+=24; + bitStream += 0xFFFFU << bitCount; + if ((!writeIsSafe) && (out > oend-2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE) bitStream; + out[1] = (BYTE)(bitStream>>8); + out+=2; + bitStream>>=16; + } + while (symbol >= start+3) { + start+=3; + bitStream += 3U << bitCount; + bitCount += 2; + } + bitStream += (symbol-start) << bitCount; + bitCount += 2; + if (bitCount>16) { + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } } + { int count = normalizedCounter[symbol++]; + int const max = (2*threshold-1) - remaining; + remaining -= count < 0 ? -count : count; + count++; /* +1 for extra accuracy */ + if (count>=threshold) + count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ + bitStream += (U32)count << bitCount; + bitCount += nbBits; + bitCount -= (count>=1; } + } + if (bitCount>16) { + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } } + + if (remaining != 1) + return ERROR(GENERIC); /* incorrect normalized distribution */ + assert(symbol <= alphabetSize); + + /* flush remaining bitStream */ + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out+= (bitCount+7) /8; + + assert(out >= ostart); + return (size_t)(out-ostart); +} + + +size_t FSE_writeNCount (void* buffer, size_t bufferSize, + const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */ + if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */ + + if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog)) + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0); + + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1 /* write in buffer is safe */); +} + + +/*-************************************************************** +* FSE Compression Code +****************************************************************/ + +/* provides the minimum logSize to safely represent a distribution */ +static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) +{ + U32 minBitsSrc = ZSTD_highbit32((U32)(srcSize)) + 1; + U32 minBitsSymbols = ZSTD_highbit32(maxSymbolValue) + 2; + U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols; + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + return minBits; +} + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus) +{ + U32 maxBitsSrc = ZSTD_highbit32((U32)(srcSize - 1)) - minus; + U32 tableLog = maxTableLog; + U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue); + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; + if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */ + if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */ + if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG; + if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG; + return tableLog; +} + +unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) +{ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2); +} + +/* Secondary normalization method. + To be used when primary method fails. */ + +static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue, short lowProbCount) +{ + short const NOT_YET_ASSIGNED = -2; + U32 s; + U32 distributed = 0; + U32 ToDistribute; + + /* Init */ + U32 const lowThreshold = (U32)(total >> tableLog); + U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); + + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == 0) { + norm[s]=0; + continue; + } + if (count[s] <= lowThreshold) { + norm[s] = lowProbCount; + distributed++; + total -= count[s]; + continue; + } + if (count[s] <= lowOne) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } + + norm[s]=NOT_YET_ASSIGNED; + } + ToDistribute = (1 << tableLog) - distributed; + + if (ToDistribute == 0) + return 0; + + if ((total / ToDistribute) > lowOne) { + /* risk of rounding to zero */ + lowOne = (U32)((total * 3) / (ToDistribute * 2)); + for (s=0; s<=maxSymbolValue; s++) { + if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } } + ToDistribute = (1 << tableLog) - distributed; + } + + if (distributed == maxSymbolValue+1) { + /* all values are pretty poor; + probably incompressible data (should have already been detected); + find max, then give all remaining points to max */ + U32 maxV = 0, maxC = 0; + for (s=0; s<=maxSymbolValue; s++) + if (count[s] > maxC) { maxV=s; maxC=count[s]; } + norm[maxV] += (short)ToDistribute; + return 0; + } + + if (total == 0) { + /* all of the symbols were low enough for the lowOne or lowThreshold */ + for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1)) + if (norm[s] > 0) { ToDistribute--; norm[s]++; } + return 0; + } + + { U64 const vStepLog = 62 - tableLog; + U64 const mid = (1ULL << (vStepLog-1)) - 1; + U64 const rStep = ZSTD_div64((((U64)1<> vStepLog); + U32 const sEnd = (U32)(end >> vStepLog); + U32 const weight = sEnd - sStart; + if (weight < 1) + return ERROR(GENERIC); + norm[s] = (short)weight; + tmpTotal = end; + } } } + + return 0; +} + +size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t total, + unsigned maxSymbolValue, unsigned useLowProbCount) +{ + /* Sanity checks */ + if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; + if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */ + if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ + + { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 }; + short const lowProbCount = useLowProbCount ? -1 : 1; + U64 const scale = 62 - tableLog; + U64 const step = ZSTD_div64((U64)1<<62, (U32)total); /* <== here, one division ! */ + U64 const vStep = 1ULL<<(scale-20); + int stillToDistribute = 1<> tableLog); + + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == total) return 0; /* rle special case */ + if (count[s] == 0) { normalizedCounter[s]=0; continue; } + if (count[s] <= lowThreshold) { + normalizedCounter[s] = lowProbCount; + stillToDistribute--; + } else { + short proba = (short)((count[s]*step) >> scale); + if (proba<8) { + U64 restToBeat = vStep * rtbTable[proba]; + proba += (count[s]*step) - ((U64)proba< restToBeat; + } + if (proba > largestP) { largestP=proba; largest=s; } + normalizedCounter[s] = proba; + stillToDistribute -= proba; + } } + if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { + /* corner case, need another normalization method */ + size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount); + if (FSE_isError(errorCode)) return errorCode; + } + else normalizedCounter[largest] += (short)stillToDistribute; + } + +#if 0 + { /* Print Table (debug) */ + U32 s; + U32 nTotal = 0; + for (s=0; s<=maxSymbolValue; s++) + RAWLOG(2, "%3i: %4i \n", s, normalizedCounter[s]); + for (s=0; s<=maxSymbolValue; s++) + nTotal += abs(normalizedCounter[s]); + if (nTotal != (1U< FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) { /* test bit 2 */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + FSE_FLUSHBITS(&bitC); + } + + /* 2 or 4 encoding per loop */ + while ( ip>istart ) { + + FSE_encodeSymbol(&bitC, &CState2, *--ip); + + if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */ + FSE_FLUSHBITS(&bitC); + + FSE_encodeSymbol(&bitC, &CState1, *--ip); + + if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) { /* this test must be static */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + } + + FSE_FLUSHBITS(&bitC); + } + + FSE_flushCState(&bitC, &CState2); + FSE_flushCState(&bitC, &CState1); + return BIT_closeCStream(&bitC); +} + +size_t FSE_compress_usingCTable (void* dst, size_t dstSize, + const void* src, size_t srcSize, + const FSE_CTable* ct) +{ + unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); + + if (fast) + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1); + else + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0); +} + + +size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/hist.c b/cpp/third_party/zstd-1.5.7/lib/compress/hist.c new file mode 100644 index 000000000..4ccf9a90a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/hist.c @@ -0,0 +1,191 @@ +/* ****************************************************************** + * hist : Histogram functions + * part of Finite State Entropy project + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* --- dependencies --- */ +#include "../common/mem.h" /* U32, BYTE, etc. */ +#include "../common/debug.h" /* assert, DEBUGLOG */ +#include "../common/error_private.h" /* ERROR */ +#include "hist.h" + + +/* --- Error management --- */ +unsigned HIST_isError(size_t code) { return ERR_isError(code); } + +/*-************************************************************** + * Histogram functions + ****************************************************************/ +void HIST_add(unsigned* count, const void* src, size_t srcSize) +{ + const BYTE* ip = (const BYTE*)src; + const BYTE* const end = ip + srcSize; + + while (ip largestCount) largestCount = count[s]; + } + + return largestCount; +} + +typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e; + +/* HIST_count_parallel_wksp() : + * store histogram into 4 intermediate tables, recombined at the end. + * this design makes better use of OoO cpus, + * and is noticeably faster when some values are heavily repeated. + * But it needs some additional workspace for intermediate tables. + * `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32. + * @return : largest histogram frequency, + * or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */ +static size_t HIST_count_parallel_wksp( + unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + HIST_checkInput_e check, + U32* const workSpace) +{ + const BYTE* ip = (const BYTE*)source; + const BYTE* const iend = ip+sourceSize; + size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count); + unsigned max=0; + U32* const Counting1 = workSpace; + U32* const Counting2 = Counting1 + 256; + U32* const Counting3 = Counting2 + 256; + U32* const Counting4 = Counting3 + 256; + + /* safety checks */ + assert(*maxSymbolValuePtr <= 255); + if (!sourceSize) { + ZSTD_memset(count, 0, countSize); + *maxSymbolValuePtr = 0; + return 0; + } + ZSTD_memset(workSpace, 0, 4*256*sizeof(unsigned)); + + /* by stripes of 16 bytes */ + { U32 cached = MEM_read32(ip); ip += 4; + while (ip < iend-15) { + U32 c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + } + ip-=4; + } + + /* finish last symbols */ + while (ip max) max = Counting1[s]; + } } + + { unsigned maxSymbolValue = 255; + while (!Counting1[maxSymbolValue]) maxSymbolValue--; + if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall); + *maxSymbolValuePtr = maxSymbolValue; + ZSTD_memmove(count, Counting1, countSize); /* in case count & Counting1 are overlapping */ + } + return (size_t)max; +} + +/* HIST_countFast_wksp() : + * Same as HIST_countFast(), but using an externally provided scratch buffer. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + void* workSpace, size_t workSpaceSize) +{ + if (sourceSize < 1500) /* heuristic threshold */ + return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize); + if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ + if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall); + return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace); +} + +/* HIST_count_wksp() : + * Same as HIST_count(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ +size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + void* workSpace, size_t workSpaceSize) +{ + if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ + if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall); + if (*maxSymbolValuePtr < 255) + return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace); + *maxSymbolValuePtr = 255; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize); +} + +#ifndef ZSTD_NO_UNUSED_FUNCTIONS +/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters)); +} + +size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters)); +} +#endif diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/hist.h b/cpp/third_party/zstd-1.5.7/lib/compress/hist.h new file mode 100644 index 000000000..bea2a9ebf --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/hist.h @@ -0,0 +1,82 @@ +/* ****************************************************************** + * hist : Histogram functions + * part of Finite State Entropy project + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* --- dependencies --- */ +#include "../common/zstd_deps.h" /* size_t */ + + +/* --- simple histogram functions --- */ + +/*! HIST_count(): + * Provides the precise count of each byte within a table 'count'. + * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1). + * Updates *maxSymbolValuePtr with actual largest symbol value detected. + * @return : count of the most frequent symbol (which isn't identified). + * or an error code, which can be tested using HIST_isError(). + * note : if return == srcSize, there is only one symbol. + */ +size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +unsigned HIST_isError(size_t code); /**< tells if a return value is an error code */ + + +/* --- advanced histogram functions --- */ + +#define HIST_WKSP_SIZE_U32 1024 +#define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned)) +/** HIST_count_wksp() : + * Same as HIST_count(), but using an externally provided scratch buffer. + * Benefit is this function will use very little stack space. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize, + void* workSpace, size_t workSpaceSize); + +/** HIST_countFast() : + * same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr. + * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` + */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +/** HIST_countFast_wksp() : + * Same as HIST_countFast(), but using an externally provided scratch buffer. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize, + void* workSpace, size_t workSpaceSize); + +/*! HIST_count_simple() : + * Same as HIST_countFast(), this function is unsafe, + * and will segfault if any value within `src` is `> *maxSymbolValuePtr`. + * It is also a bit slower for large inputs. + * However, it does not need any additional memory (not even on stack). + * @return : count of the most frequent symbol. + * Note this function doesn't produce any error (i.e. it must succeed). + */ +unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +/*! HIST_add() : + * Lowest level: just add nb of occurrences of characters from @src into @count. + * @count is not reset. @count array is presumed large enough (i.e. 1 KB). + @ This function does not need any additional stack memory. + */ +void HIST_add(unsigned* count, const void* src, size_t srcSize); diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/huf_compress.c b/cpp/third_party/zstd-1.5.7/lib/compress/huf_compress.c new file mode 100644 index 000000000..ea0007232 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/huf_compress.c @@ -0,0 +1,1464 @@ +/* ****************************************************************** + * Huffman encoder, part of New Generation Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Compiler specifics +****************************************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#endif + + +/* ************************************************************** +* Includes +****************************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */ +#include "../common/compiler.h" +#include "../common/bitstream.h" +#include "hist.h" +#define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */ +#include "../common/fse.h" /* header compression */ +#include "../common/huf.h" +#include "../common/error_private.h" +#include "../common/bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_isError ERR_isError +#define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ + + +/* ************************************************************** +* Required declarations +****************************************************************/ +typedef struct nodeElt_s { + U32 count; + U16 parent; + BYTE byte; + BYTE nbBits; +} nodeElt; + + +/* ************************************************************** +* Debug Traces +****************************************************************/ + +#if DEBUGLEVEL >= 2 + +static size_t showU32(const U32* arr, size_t size) +{ + size_t u; + for (u=0; u= add) { + assert(add < align); + assert(((size_t)aligned & mask) == 0); + *workspaceSizePtr -= add; + return aligned; + } else { + *workspaceSizePtr = 0; + return NULL; + } +} + + +/* HUF_compressWeights() : + * Same as FSE_compress(), but dedicated to huff0's weights compression. + * The use case needs much less stack memory. + * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX. + */ +#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 + +typedef struct { + FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]; + U32 scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)]; + unsigned count[HUF_TABLELOG_MAX+1]; + S16 norm[HUF_TABLELOG_MAX+1]; +} HUF_CompressWeightsWksp; + +static size_t +HUF_compressWeights(void* dst, size_t dstSize, + const void* weightTable, size_t wtSize, + void* workspace, size_t workspaceSize) +{ + BYTE* const ostart = (BYTE*) dst; + BYTE* op = ostart; + BYTE* const oend = ostart + dstSize; + + unsigned maxSymbolValue = HUF_TABLELOG_MAX; + U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; + HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32)); + + if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC); + + /* init conditions */ + if (wtSize <= 1) return 0; /* Not compressible */ + + /* Scan input and build symbol stats */ + { unsigned const maxCount = HIST_count_simple(wksp->count, &maxSymbolValue, weightTable, wtSize); /* never fails */ + if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */ + if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ + } + + tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue); + CHECK_F( FSE_normalizeCount(wksp->norm, tableLog, wksp->count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) ); + + /* Write table description header */ + { CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), wksp->norm, maxSymbolValue, tableLog) ); + op += hSize; + } + + /* Compress */ + CHECK_F( FSE_buildCTable_wksp(wksp->CTable, wksp->norm, maxSymbolValue, tableLog, wksp->scratchBuffer, sizeof(wksp->scratchBuffer)) ); + { CHECK_V_F(cSize, FSE_compress_usingCTable(op, (size_t)(oend - op), weightTable, wtSize, wksp->CTable) ); + if (cSize == 0) return 0; /* not enough space for compressed data */ + op += cSize; + } + + return (size_t)(op-ostart); +} + +static size_t HUF_getNbBits(HUF_CElt elt) +{ + return elt & 0xFF; +} + +static size_t HUF_getNbBitsFast(HUF_CElt elt) +{ + return elt; +} + +static size_t HUF_getValue(HUF_CElt elt) +{ + return elt & ~(size_t)0xFF; +} + +static size_t HUF_getValueFast(HUF_CElt elt) +{ + return elt; +} + +static void HUF_setNbBits(HUF_CElt* elt, size_t nbBits) +{ + assert(nbBits <= HUF_TABLELOG_ABSOLUTEMAX); + *elt = nbBits; +} + +static void HUF_setValue(HUF_CElt* elt, size_t value) +{ + size_t const nbBits = HUF_getNbBits(*elt); + if (nbBits > 0) { + assert((value >> nbBits) == 0); + *elt |= value << (sizeof(HUF_CElt) * 8 - nbBits); + } +} + +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable) +{ + HUF_CTableHeader header; + ZSTD_memcpy(&header, ctable, sizeof(header)); + return header; +} + +static void HUF_writeCTableHeader(HUF_CElt* ctable, U32 tableLog, U32 maxSymbolValue) +{ + HUF_CTableHeader header; + HUF_STATIC_ASSERT(sizeof(ctable[0]) == sizeof(header)); + ZSTD_memset(&header, 0, sizeof(header)); + assert(tableLog < 256); + header.tableLog = (BYTE)tableLog; + assert(maxSymbolValue < 256); + header.maxSymbolValue = (BYTE)maxSymbolValue; + ZSTD_memcpy(ctable, &header, sizeof(header)); +} + +typedef struct { + HUF_CompressWeightsWksp wksp; + BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */ + BYTE huffWeight[HUF_SYMBOLVALUE_MAX]; +} HUF_WriteCTableWksp; + +size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, + const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, + void* workspace, size_t workspaceSize) +{ + HUF_CElt const* const ct = CTable + 1; + BYTE* op = (BYTE*)dst; + U32 n; + HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32)); + + HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE >= sizeof(HUF_WriteCTableWksp)); + + assert(HUF_readCTableHeader(CTable).maxSymbolValue == maxSymbolValue); + assert(HUF_readCTableHeader(CTable).tableLog == huffLog); + + /* check conditions */ + if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC); + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); + + /* convert to weight */ + wksp->bitsToWeight[0] = 0; + for (n=1; nbitsToWeight[n] = (BYTE)(huffLog + 1 - n); + for (n=0; nhuffWeight[n] = wksp->bitsToWeight[HUF_getNbBits(ct[n])]; + + /* attempt weights compression by FSE */ + if (maxDstSize < 1) return ERROR(dstSize_tooSmall); + { CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, wksp->huffWeight, maxSymbolValue, &wksp->wksp, sizeof(wksp->wksp)) ); + if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */ + op[0] = (BYTE)hSize; + return hSize+1; + } } + + /* write raw values as 4-bits (max : 15) */ + if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */ + if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */ + op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1)); + wksp->huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */ + for (n=0; nhuffWeight[n] << 4) + wksp->huffWeight[n+1]); + return ((maxSymbolValue+1)/2) + 1; +} + + +size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* hasZeroWeights) +{ + BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */ + U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ + U32 tableLog = 0; + U32 nbSymbols = 0; + HUF_CElt* const ct = CTable + 1; + + /* get symbol weights */ + CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize)); + *hasZeroWeights = (rankVal[0] > 0); + + /* check result */ + if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + if (nbSymbols > *maxSymbolValuePtr+1) return ERROR(maxSymbolValue_tooSmall); + + *maxSymbolValuePtr = nbSymbols - 1; + + HUF_writeCTableHeader(CTable, tableLog, *maxSymbolValuePtr); + + /* Prepare base value per rank */ + { U32 n, nextRankStart = 0; + for (n=1; n<=tableLog; n++) { + U32 curr = nextRankStart; + nextRankStart += (rankVal[n] << (n-1)); + rankVal[n] = curr; + } } + + /* fill nbBits */ + { U32 n; for (n=0; nn=tableLog+1 */ + U16 valPerRank[HUF_TABLELOG_MAX+2] = {0}; + { U32 n; for (n=0; n0; n--) { /* start at n=tablelog <-> w=1 */ + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } } + /* assign value within rank, symbol order */ + { U32 n; for (n=0; n HUF_readCTableHeader(CTable).maxSymbolValue) + return 0; + return (U32)HUF_getNbBits(ct[symbolValue]); +} + + +/** + * HUF_setMaxHeight(): + * Try to enforce @targetNbBits on the Huffman tree described in @huffNode. + * + * It attempts to convert all nodes with nbBits > @targetNbBits + * to employ @targetNbBits instead. Then it adjusts the tree + * so that it remains a valid canonical Huffman tree. + * + * @pre The sum of the ranks of each symbol == 2^largestBits, + * where largestBits == huffNode[lastNonNull].nbBits. + * @post The sum of the ranks of each symbol == 2^largestBits, + * where largestBits is the return value (expected <= targetNbBits). + * + * @param huffNode The Huffman tree modified in place to enforce targetNbBits. + * It's presumed sorted, from most frequent to rarest symbol. + * @param lastNonNull The symbol with the lowest count in the Huffman tree. + * @param targetNbBits The allowed number of bits, which the Huffman tree + * may not respect. After this function the Huffman tree will + * respect targetNbBits. + * @return The maximum number of bits of the Huffman tree after adjustment. + */ +static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 targetNbBits) +{ + const U32 largestBits = huffNode[lastNonNull].nbBits; + /* early exit : no elt > targetNbBits, so the tree is already valid. */ + if (largestBits <= targetNbBits) return largestBits; + + DEBUGLOG(5, "HUF_setMaxHeight (targetNbBits = %u)", targetNbBits); + + /* there are several too large elements (at least >= 2) */ + { int totalCost = 0; + const U32 baseCost = 1 << (largestBits - targetNbBits); + int n = (int)lastNonNull; + + /* Adjust any ranks > targetNbBits to targetNbBits. + * Compute totalCost, which is how far the sum of the ranks is + * we are over 2^largestBits after adjust the offending ranks. + */ + while (huffNode[n].nbBits > targetNbBits) { + totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits)); + huffNode[n].nbBits = (BYTE)targetNbBits; + n--; + } + /* n stops at huffNode[n].nbBits <= targetNbBits */ + assert(huffNode[n].nbBits <= targetNbBits); + /* n end at index of smallest symbol using < targetNbBits */ + while (huffNode[n].nbBits == targetNbBits) --n; + + /* renorm totalCost from 2^largestBits to 2^targetNbBits + * note : totalCost is necessarily a multiple of baseCost */ + assert(((U32)totalCost & (baseCost - 1)) == 0); + totalCost >>= (largestBits - targetNbBits); + assert(totalCost > 0); + + /* repay normalized cost */ + { U32 const noSymbol = 0xF0F0F0F0; + U32 rankLast[HUF_TABLELOG_MAX+2]; + + /* Get pos of last (smallest = lowest cum. count) symbol per rank */ + ZSTD_memset(rankLast, 0xF0, sizeof(rankLast)); + { U32 currentNbBits = targetNbBits; + int pos; + for (pos=n ; pos >= 0; pos--) { + if (huffNode[pos].nbBits >= currentNbBits) continue; + currentNbBits = huffNode[pos].nbBits; /* < targetNbBits */ + rankLast[targetNbBits-currentNbBits] = (U32)pos; + } } + + while (totalCost > 0) { + /* Try to reduce the next power of 2 above totalCost because we + * gain back half the rank. + */ + U32 nBitsToDecrease = ZSTD_highbit32((U32)totalCost) + 1; + for ( ; nBitsToDecrease > 1; nBitsToDecrease--) { + U32 const highPos = rankLast[nBitsToDecrease]; + U32 const lowPos = rankLast[nBitsToDecrease-1]; + if (highPos == noSymbol) continue; + /* Decrease highPos if no symbols of lowPos or if it is + * not cheaper to remove 2 lowPos than highPos. + */ + if (lowPos == noSymbol) break; + { U32 const highTotal = huffNode[highPos].count; + U32 const lowTotal = 2 * huffNode[lowPos].count; + if (highTotal <= lowTotal) break; + } } + /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */ + assert(rankLast[nBitsToDecrease] != noSymbol || nBitsToDecrease == 1); + /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */ + while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol)) + nBitsToDecrease++; + assert(rankLast[nBitsToDecrease] != noSymbol); + /* Increase the number of bits to gain back half the rank cost. */ + totalCost -= 1 << (nBitsToDecrease-1); + huffNode[rankLast[nBitsToDecrease]].nbBits++; + + /* Fix up the new rank. + * If the new rank was empty, this symbol is now its smallest. + * Otherwise, this symbol will be the largest in the new rank so no adjustment. + */ + if (rankLast[nBitsToDecrease-1] == noSymbol) + rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; + /* Fix up the old rank. + * If the symbol was at position 0, meaning it was the highest weight symbol in the tree, + * it must be the only symbol in its rank, so the old rank now has no symbols. + * Otherwise, since the Huffman nodes are sorted by count, the previous position is now + * the smallest node in the rank. If the previous position belongs to a different rank, + * then the rank is now empty. + */ + if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */ + rankLast[nBitsToDecrease] = noSymbol; + else { + rankLast[nBitsToDecrease]--; + if (huffNode[rankLast[nBitsToDecrease]].nbBits != targetNbBits-nBitsToDecrease) + rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */ + } + } /* while (totalCost > 0) */ + + /* If we've removed too much weight, then we have to add it back. + * To avoid overshooting again, we only adjust the smallest rank. + * We take the largest nodes from the lowest rank 0 and move them + * to rank 1. There's guaranteed to be enough rank 0 symbols because + * TODO. + */ + while (totalCost < 0) { /* Sometimes, cost correction overshoot */ + /* special case : no rank 1 symbol (using targetNbBits-1); + * let's create one from largest rank 0 (using targetNbBits). + */ + if (rankLast[1] == noSymbol) { + while (huffNode[n].nbBits == targetNbBits) n--; + huffNode[n+1].nbBits--; + assert(n >= 0); + rankLast[1] = (U32)(n+1); + totalCost++; + continue; + } + huffNode[ rankLast[1] + 1 ].nbBits--; + rankLast[1]++; + totalCost ++; + } + } /* repay normalized cost */ + } /* there are several too large elements (at least >= 2) */ + + return targetNbBits; +} + +typedef struct { + U16 base; + U16 curr; +} rankPos; + +typedef nodeElt huffNodeTable[2 * (HUF_SYMBOLVALUE_MAX + 1)]; + +/* Number of buckets available for HUF_sort() */ +#define RANK_POSITION_TABLE_SIZE 192 + +typedef struct { + huffNodeTable huffNodeTbl; + rankPos rankPosition[RANK_POSITION_TABLE_SIZE]; +} HUF_buildCTable_wksp_tables; + +/* RANK_POSITION_DISTINCT_COUNT_CUTOFF == Cutoff point in HUF_sort() buckets for which we use log2 bucketing. + * Strategy is to use as many buckets as possible for representing distinct + * counts while using the remainder to represent all "large" counts. + * + * To satisfy this requirement for 192 buckets, we can do the following: + * Let buckets 0-166 represent distinct counts of [0, 166] + * Let buckets 166 to 192 represent all remaining counts up to RANK_POSITION_MAX_COUNT_LOG using log2 bucketing. + */ +#define RANK_POSITION_MAX_COUNT_LOG 32 +#define RANK_POSITION_LOG_BUCKETS_BEGIN ((RANK_POSITION_TABLE_SIZE - 1) - RANK_POSITION_MAX_COUNT_LOG - 1 /* == 158 */) +#define RANK_POSITION_DISTINCT_COUNT_CUTOFF (RANK_POSITION_LOG_BUCKETS_BEGIN + ZSTD_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) /* == 166 */) + +/* Return the appropriate bucket index for a given count. See definition of + * RANK_POSITION_DISTINCT_COUNT_CUTOFF for explanation of bucketing strategy. + */ +static U32 HUF_getIndex(U32 const count) { + return (count < RANK_POSITION_DISTINCT_COUNT_CUTOFF) + ? count + : ZSTD_highbit32(count) + RANK_POSITION_LOG_BUCKETS_BEGIN; +} + +/* Helper swap function for HUF_quickSortPartition() */ +static void HUF_swapNodes(nodeElt* a, nodeElt* b) { + nodeElt tmp = *a; + *a = *b; + *b = tmp; +} + +/* Returns 0 if the huffNode array is not sorted by descending count */ +MEM_STATIC int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1) { + U32 i; + for (i = 1; i < maxSymbolValue1; ++i) { + if (huffNode[i].count > huffNode[i-1].count) { + return 0; + } + } + return 1; +} + +/* Insertion sort by descending order */ +HINT_INLINE void HUF_insertionSort(nodeElt huffNode[], int const low, int const high) { + int i; + int const size = high-low+1; + huffNode += low; + for (i = 1; i < size; ++i) { + nodeElt const key = huffNode[i]; + int j = i - 1; + while (j >= 0 && huffNode[j].count < key.count) { + huffNode[j + 1] = huffNode[j]; + j--; + } + huffNode[j + 1] = key; + } +} + +/* Pivot helper function for quicksort. */ +static int HUF_quickSortPartition(nodeElt arr[], int const low, int const high) { + /* Simply select rightmost element as pivot. "Better" selectors like + * median-of-three don't experimentally appear to have any benefit. + */ + U32 const pivot = arr[high].count; + int i = low - 1; + int j = low; + for ( ; j < high; j++) { + if (arr[j].count > pivot) { + i++; + HUF_swapNodes(&arr[i], &arr[j]); + } + } + HUF_swapNodes(&arr[i + 1], &arr[high]); + return i + 1; +} + +/* Classic quicksort by descending with partially iterative calls + * to reduce worst case callstack size. + */ +static void HUF_simpleQuickSort(nodeElt arr[], int low, int high) { + int const kInsertionSortThreshold = 8; + if (high - low < kInsertionSortThreshold) { + HUF_insertionSort(arr, low, high); + return; + } + while (low < high) { + int const idx = HUF_quickSortPartition(arr, low, high); + if (idx - low < high - idx) { + HUF_simpleQuickSort(arr, low, idx - 1); + low = idx + 1; + } else { + HUF_simpleQuickSort(arr, idx + 1, high); + high = idx - 1; + } + } +} + +/** + * HUF_sort(): + * Sorts the symbols [0, maxSymbolValue] by count[symbol] in decreasing order. + * This is a typical bucket sorting strategy that uses either quicksort or insertion sort to sort each bucket. + * + * @param[out] huffNode Sorted symbols by decreasing count. Only members `.count` and `.byte` are filled. + * Must have (maxSymbolValue + 1) entries. + * @param[in] count Histogram of the symbols. + * @param[in] maxSymbolValue Maximum symbol value. + * @param rankPosition This is a scratch workspace. Must have RANK_POSITION_TABLE_SIZE entries. + */ +static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSymbolValue, rankPos rankPosition[]) { + U32 n; + U32 const maxSymbolValue1 = maxSymbolValue+1; + + /* Compute base and set curr to base. + * For symbol s let lowerRank = HUF_getIndex(count[n]) and rank = lowerRank + 1. + * See HUF_getIndex to see bucketing strategy. + * We attribute each symbol to lowerRank's base value, because we want to know where + * each rank begins in the output, so for rank R we want to count ranks R+1 and above. + */ + ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE); + for (n = 0; n < maxSymbolValue1; ++n) { + U32 lowerRank = HUF_getIndex(count[n]); + assert(lowerRank < RANK_POSITION_TABLE_SIZE - 1); + rankPosition[lowerRank].base++; + } + + assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0); + /* Set up the rankPosition table */ + for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) { + rankPosition[n-1].base += rankPosition[n].base; + rankPosition[n-1].curr = rankPosition[n-1].base; + } + + /* Insert each symbol into their appropriate bucket, setting up rankPosition table. */ + for (n = 0; n < maxSymbolValue1; ++n) { + U32 const c = count[n]; + U32 const r = HUF_getIndex(c) + 1; + U32 const pos = rankPosition[r].curr++; + assert(pos < maxSymbolValue1); + huffNode[pos].count = c; + huffNode[pos].byte = (BYTE)n; + } + + /* Sort each bucket. */ + for (n = RANK_POSITION_DISTINCT_COUNT_CUTOFF; n < RANK_POSITION_TABLE_SIZE - 1; ++n) { + int const bucketSize = rankPosition[n].curr - rankPosition[n].base; + U32 const bucketStartIdx = rankPosition[n].base; + if (bucketSize > 1) { + assert(bucketStartIdx < maxSymbolValue1); + HUF_simpleQuickSort(huffNode + bucketStartIdx, 0, bucketSize-1); + } + } + + assert(HUF_isSorted(huffNode, maxSymbolValue1)); +} + + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as sizeof(HUF_buildCTable_wksp_tables). + */ +#define STARTNODE (HUF_SYMBOLVALUE_MAX+1) + +/* HUF_buildTree(): + * Takes the huffNode array sorted by HUF_sort() and builds an unlimited-depth Huffman tree. + * + * @param huffNode The array sorted by HUF_sort(). Builds the Huffman tree in this array. + * @param maxSymbolValue The maximum symbol value. + * @return The smallest node in the Huffman tree (by count). + */ +static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue) +{ + nodeElt* const huffNode0 = huffNode - 1; + int nonNullRank; + int lowS, lowN; + int nodeNb = STARTNODE; + int n, nodeRoot; + DEBUGLOG(5, "HUF_buildTree (alphabet size = %u)", maxSymbolValue + 1); + /* init for parents */ + nonNullRank = (int)maxSymbolValue; + while(huffNode[nonNullRank].count == 0) nonNullRank--; + lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb; + huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count; + huffNode[lowS].parent = huffNode[lowS-1].parent = (U16)nodeNb; + nodeNb++; lowS-=2; + for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30); + huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */ + + /* create parents */ + while (nodeNb <= nodeRoot) { + int const n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++; + int const n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++; + huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count; + huffNode[n1].parent = huffNode[n2].parent = (U16)nodeNb; + nodeNb++; + } + + /* distribute weights (unlimited tree height) */ + huffNode[nodeRoot].nbBits = 0; + for (n=nodeRoot-1; n>=STARTNODE; n--) + huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1; + for (n=0; n<=nonNullRank; n++) + huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1; + + DEBUGLOG(6, "Initial distribution of bits completed (%zu sorted symbols)", showHNodeBits(huffNode, maxSymbolValue+1)); + + return nonNullRank; +} + +/** + * HUF_buildCTableFromTree(): + * Build the CTable given the Huffman tree in huffNode. + * + * @param[out] CTable The output Huffman CTable. + * @param huffNode The Huffman tree. + * @param nonNullRank The last and smallest node in the Huffman tree. + * @param maxSymbolValue The maximum symbol value. + * @param maxNbBits The exact maximum number of bits used in the Huffman tree. + */ +static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits) +{ + HUF_CElt* const ct = CTable + 1; + /* fill result into ctable (val, nbBits) */ + int n; + U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0}; + U16 valPerRank[HUF_TABLELOG_MAX+1] = {0}; + int const alphabetSize = (int)(maxSymbolValue + 1); + for (n=0; n<=nonNullRank; n++) + nbPerRank[huffNode[n].nbBits]++; + /* determine starting value per rank */ + { U16 min = 0; + for (n=(int)maxNbBits; n>0; n--) { + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } } + for (n=0; nhuffNodeTbl; + nodeElt* const huffNode = huffNode0+1; + int nonNullRank; + + HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE == sizeof(HUF_buildCTable_wksp_tables)); + + DEBUGLOG(5, "HUF_buildCTable_wksp (alphabet size = %u)", maxSymbolValue+1); + + /* safety checks */ + if (wkspSize < sizeof(HUF_buildCTable_wksp_tables)) + return ERROR(workSpace_tooSmall); + if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT; + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) + return ERROR(maxSymbolValue_tooLarge); + ZSTD_memset(huffNode0, 0, sizeof(huffNodeTable)); + + /* sort, decreasing order */ + HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition); + DEBUGLOG(6, "sorted symbols completed (%zu symbols)", showHNodeSymbols(huffNode, maxSymbolValue+1)); + + /* build tree */ + nonNullRank = HUF_buildTree(huffNode, maxSymbolValue); + + /* determine and enforce maxTableLog */ + maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits); + if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */ + + HUF_buildCTableFromTree(CTable, huffNode, nonNullRank, maxSymbolValue, maxNbBits); + + return maxNbBits; +} + +size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) +{ + HUF_CElt const* ct = CTable + 1; + size_t nbBits = 0; + int s; + for (s = 0; s <= (int)maxSymbolValue; ++s) { + nbBits += HUF_getNbBits(ct[s]) * count[s]; + } + return nbBits >> 3; +} + +int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) { + HUF_CTableHeader header = HUF_readCTableHeader(CTable); + HUF_CElt const* ct = CTable + 1; + int bad = 0; + int s; + + assert(header.tableLog <= HUF_TABLELOG_ABSOLUTEMAX); + + if (header.maxSymbolValue < maxSymbolValue) + return 0; + + for (s = 0; s <= (int)maxSymbolValue; ++s) { + bad |= (count[s] != 0) & (HUF_getNbBits(ct[s]) == 0); + } + return !bad; +} + +size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); } + +/** HUF_CStream_t: + * Huffman uses its own BIT_CStream_t implementation. + * There are three major differences from BIT_CStream_t: + * 1. HUF_addBits() takes a HUF_CElt (size_t) which is + * the pair (nbBits, value) in the format: + * format: + * - Bits [0, 4) = nbBits + * - Bits [4, 64 - nbBits) = 0 + * - Bits [64 - nbBits, 64) = value + * 2. The bitContainer is built from the upper bits and + * right shifted. E.g. to add a new value of N bits + * you right shift the bitContainer by N, then or in + * the new value into the N upper bits. + * 3. The bitstream has two bit containers. You can add + * bits to the second container and merge them into + * the first container. + */ + +#define HUF_BITS_IN_CONTAINER (sizeof(size_t) * 8) + +typedef struct { + size_t bitContainer[2]; + size_t bitPos[2]; + + BYTE* startPtr; + BYTE* ptr; + BYTE* endPtr; +} HUF_CStream_t; + +/**! HUF_initCStream(): + * Initializes the bitstream. + * @returns 0 or an error code. + */ +static size_t HUF_initCStream(HUF_CStream_t* bitC, + void* startPtr, size_t dstCapacity) +{ + ZSTD_memset(bitC, 0, sizeof(*bitC)); + bitC->startPtr = (BYTE*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer[0]); + if (dstCapacity <= sizeof(bitC->bitContainer[0])) return ERROR(dstSize_tooSmall); + return 0; +} + +/*! HUF_addBits(): + * Adds the symbol stored in HUF_CElt elt to the bitstream. + * + * @param elt The element we're adding. This is a (nbBits, value) pair. + * See the HUF_CStream_t docs for the format. + * @param idx Insert into the bitstream at this idx. + * @param kFast This is a template parameter. If the bitstream is guaranteed + * to have at least 4 unused bits after this call it may be 1, + * otherwise it must be 0. HUF_addBits() is faster when fast is set. + */ +FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int idx, int kFast) +{ + assert(idx <= 1); + assert(HUF_getNbBits(elt) <= HUF_TABLELOG_ABSOLUTEMAX); + /* This is efficient on x86-64 with BMI2 because shrx + * only reads the low 6 bits of the register. The compiler + * knows this and elides the mask. When fast is set, + * every operation can use the same value loaded from elt. + */ + bitC->bitContainer[idx] >>= HUF_getNbBits(elt); + bitC->bitContainer[idx] |= kFast ? HUF_getValueFast(elt) : HUF_getValue(elt); + /* We only read the low 8 bits of bitC->bitPos[idx] so it + * doesn't matter that the high bits have noise from the value. + */ + bitC->bitPos[idx] += HUF_getNbBitsFast(elt); + assert((bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + /* The last 4-bits of elt are dirty if fast is set, + * so we must not be overwriting bits that have already been + * inserted into the bit container. + */ +#if DEBUGLEVEL >= 1 + { + size_t const nbBits = HUF_getNbBits(elt); + size_t const dirtyBits = nbBits == 0 ? 0 : ZSTD_highbit32((U32)nbBits) + 1; + (void)dirtyBits; + /* Middle bits are 0. */ + assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0); + /* We didn't overwrite any bits in the bit container. */ + assert(!kFast || (bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + (void)dirtyBits; + } +#endif +} + +FORCE_INLINE_TEMPLATE void HUF_zeroIndex1(HUF_CStream_t* bitC) +{ + bitC->bitContainer[1] = 0; + bitC->bitPos[1] = 0; +} + +/*! HUF_mergeIndex1() : + * Merges the bit container @ index 1 into the bit container @ index 0 + * and zeros the bit container @ index 1. + */ +FORCE_INLINE_TEMPLATE void HUF_mergeIndex1(HUF_CStream_t* bitC) +{ + assert((bitC->bitPos[1] & 0xFF) < HUF_BITS_IN_CONTAINER); + bitC->bitContainer[0] >>= (bitC->bitPos[1] & 0xFF); + bitC->bitContainer[0] |= bitC->bitContainer[1]; + bitC->bitPos[0] += bitC->bitPos[1]; + assert((bitC->bitPos[0] & 0xFF) <= HUF_BITS_IN_CONTAINER); +} + +/*! HUF_flushBits() : +* Flushes the bits in the bit container @ index 0. +* +* @post bitPos will be < 8. +* @param kFast If kFast is set then we must know a-priori that +* the bit container will not overflow. +*/ +FORCE_INLINE_TEMPLATE void HUF_flushBits(HUF_CStream_t* bitC, int kFast) +{ + /* The upper bits of bitPos are noisy, so we must mask by 0xFF. */ + size_t const nbBits = bitC->bitPos[0] & 0xFF; + size_t const nbBytes = nbBits >> 3; + /* The top nbBits bits of bitContainer are the ones we need. */ + size_t const bitContainer = bitC->bitContainer[0] >> (HUF_BITS_IN_CONTAINER - nbBits); + /* Mask bitPos to account for the bytes we consumed. */ + bitC->bitPos[0] &= 7; + assert(nbBits > 0); + assert(nbBits <= sizeof(bitC->bitContainer[0]) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitContainer); + bitC->ptr += nbBytes; + assert(!kFast || bitC->ptr <= bitC->endPtr); + if (!kFast && bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + /* bitContainer doesn't need to be modified because the leftover + * bits are already the top bitPos bits. And we don't care about + * noise in the lower values. + */ +} + +/*! HUF_endMark() + * @returns The Huffman stream end mark: A 1-bit value = 1. + */ +static HUF_CElt HUF_endMark(void) +{ + HUF_CElt endMark; + HUF_setNbBits(&endMark, 1); + HUF_setValue(&endMark, 1); + return endMark; +} + +/*! HUF_closeCStream() : + * @return Size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +static size_t HUF_closeCStream(HUF_CStream_t* bitC) +{ + HUF_addBits(bitC, HUF_endMark(), /* idx */ 0, /* kFast */ 0); + HUF_flushBits(bitC, /* kFast */ 0); + { + size_t const nbBits = bitC->bitPos[0] & 0xFF; + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (size_t)(bitC->ptr - bitC->startPtr) + (nbBits > 0); + } +} + +FORCE_INLINE_TEMPLATE void +HUF_encodeSymbol(HUF_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable, int idx, int fast) +{ + HUF_addBits(bitCPtr, CTable[symbol], idx, fast); +} + +FORCE_INLINE_TEMPLATE void +HUF_compress1X_usingCTable_internal_body_loop(HUF_CStream_t* bitC, + const BYTE* ip, size_t srcSize, + const HUF_CElt* ct, + int kUnroll, int kFastFlush, int kLastFast) +{ + /* Join to kUnroll */ + int n = (int)srcSize; + int rem = n % kUnroll; + if (rem > 0) { + for (; rem > 0; --rem) { + HUF_encodeSymbol(bitC, ip[--n], ct, 0, /* fast */ 0); + } + HUF_flushBits(bitC, kFastFlush); + } + assert(n % kUnroll == 0); + + /* Join to 2 * kUnroll */ + if (n % (2 * kUnroll)) { + int u; + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - u], ct, 0, 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, 0, kLastFast); + HUF_flushBits(bitC, kFastFlush); + n -= kUnroll; + } + assert(n % (2 * kUnroll) == 0); + + for (; n>0; n-= 2 * kUnroll) { + /* Encode kUnroll symbols into the bitstream @ index 0. */ + int u; + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - u], ct, /* idx */ 0, /* fast */ 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, /* idx */ 0, /* fast */ kLastFast); + HUF_flushBits(bitC, kFastFlush); + /* Encode kUnroll symbols into the bitstream @ index 1. + * This allows us to start filling the bit container + * without any data dependencies. + */ + HUF_zeroIndex1(bitC); + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - kUnroll - u], ct, /* idx */ 1, /* fast */ 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll - kUnroll], ct, /* idx */ 1, /* fast */ kLastFast); + /* Merge bitstream @ index 1 into the bitstream @ index 0 */ + HUF_mergeIndex1(bitC); + HUF_flushBits(bitC, kFastFlush); + } + assert(n == 0); + +} + +/** + * Returns a tight upper bound on the output space needed by Huffman + * with 8 bytes buffer to handle over-writes. If the output is at least + * this large we don't need to do bounds checks during Huffman encoding. + */ +static size_t HUF_tightCompressBound(size_t srcSize, size_t tableLog) +{ + return ((srcSize * tableLog) >> 3) + 8; +} + + +FORCE_INLINE_TEMPLATE size_t +HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + U32 const tableLog = HUF_readCTableHeader(CTable).tableLog; + HUF_CElt const* ct = CTable + 1; + const BYTE* ip = (const BYTE*) src; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + HUF_CStream_t bitC; + + /* init */ + if (dstSize < 8) return 0; /* not enough space to compress */ + { BYTE* op = ostart; + size_t const initErr = HUF_initCStream(&bitC, op, (size_t)(oend-op)); + if (HUF_isError(initErr)) return 0; } + + if (dstSize < HUF_tightCompressBound(srcSize, (size_t)tableLog) || tableLog > 11) + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ MEM_32bits() ? 2 : 4, /* kFast */ 0, /* kLastFast */ 0); + else { + if (MEM_32bits()) { + switch (tableLog) { + case 11: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 10: ZSTD_FALLTHROUGH; + case 9: ZSTD_FALLTHROUGH; + case 8: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + case 7: ZSTD_FALLTHROUGH; + default: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + } + } else { + switch (tableLog) { + case 11: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 10: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + case 9: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 6, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 8: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 7, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 7: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 6: ZSTD_FALLTHROUGH; + default: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + } + } + } + assert(bitC.ptr <= bitC.endPtr); + + return HUF_closeCStream(&bitC); +} + +#if DYNAMIC_BMI2 + +static BMI2_TARGET_ATTRIBUTE size_t +HUF_compress1X_usingCTable_internal_bmi2(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +static size_t +HUF_compress1X_usingCTable_internal_default(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +static size_t +HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, const int flags) +{ + if (flags & HUF_flags_bmi2) { + return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable); + } + return HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable); +} + +#else + +static size_t +HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, const int flags) +{ + (void)flags; + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +#endif + +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags) +{ + return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags); +} + +static size_t +HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, int flags) +{ + size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */ + const BYTE* ip = (const BYTE*) src; + const BYTE* const iend = ip + srcSize; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart; + + if (dstSize < 6 + 1 + 1 + 1 + 8) return 0; /* minimum space to compress successfully */ + if (srcSize < 12) return 0; /* no saving possible : too small input */ + op += 6; /* jumpTable */ + + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart+2, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart+4, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + assert(ip <= iend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + op += cSize; + } + + return (size_t)(op-ostart); +} + +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags) +{ + return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags); +} + +typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e; + +static size_t HUF_compressCTable_internal( + BYTE* const ostart, BYTE* op, BYTE* const oend, + const void* src, size_t srcSize, + HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int flags) +{ + size_t const cSize = (nbStreams==HUF_singleStream) ? + HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags) : + HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags); + if (HUF_isError(cSize)) { return cSize; } + if (cSize==0) { return 0; } /* uncompressible */ + op += cSize; + /* check compressibility */ + assert(op >= ostart); + if ((size_t)(op-ostart) >= srcSize-1) { return 0; } + return (size_t)(op-ostart); +} + +typedef struct { + unsigned count[HUF_SYMBOLVALUE_MAX + 1]; + HUF_CElt CTable[HUF_CTABLE_SIZE_ST(HUF_SYMBOLVALUE_MAX)]; + union { + HUF_buildCTable_wksp_tables buildCTable_wksp; + HUF_WriteCTableWksp writeCTable_wksp; + U32 hist_wksp[HIST_WKSP_SIZE_U32]; + } wksps; +} HUF_compress_tables_t; + +#define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE 4096 +#define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO 10 /* Must be >= 2 */ + +unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue) +{ + unsigned cardinality = 0; + unsigned i; + + for (i = 0; i < maxSymbolValue + 1; i++) { + if (count[i] != 0) cardinality += 1; + } + + return cardinality; +} + +unsigned HUF_minTableLog(unsigned symbolCardinality) +{ + U32 minBitsSymbols = ZSTD_highbit32(symbolCardinality) + 1; + return minBitsSymbols; +} + +unsigned HUF_optimalTableLog( + unsigned maxTableLog, + size_t srcSize, + unsigned maxSymbolValue, + void* workSpace, size_t wkspSize, + HUF_CElt* table, + const unsigned* count, + int flags) +{ + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + assert(wkspSize >= sizeof(HUF_buildCTable_wksp_tables)); + + if (!(flags & HUF_flags_optimalDepth)) { + /* cheap evaluation, based on FSE */ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1); + } + + { BYTE* dst = (BYTE*)workSpace + sizeof(HUF_WriteCTableWksp); + size_t dstSize = wkspSize - sizeof(HUF_WriteCTableWksp); + size_t hSize, newSize; + const unsigned symbolCardinality = HUF_cardinality(count, maxSymbolValue); + const unsigned minTableLog = HUF_minTableLog(symbolCardinality); + size_t optSize = ((size_t) ~0) - 1; + unsigned optLog = maxTableLog, optLogGuess; + + DEBUGLOG(6, "HUF_optimalTableLog: probing huf depth (srcSize=%zu)", srcSize); + + /* Search until size increases */ + for (optLogGuess = minTableLog; optLogGuess <= maxTableLog; optLogGuess++) { + DEBUGLOG(7, "checking for huffLog=%u", optLogGuess); + + { size_t maxBits = HUF_buildCTable_wksp(table, count, maxSymbolValue, optLogGuess, workSpace, wkspSize); + if (ERR_isError(maxBits)) continue; + + if (maxBits < optLogGuess && optLogGuess > minTableLog) break; + + hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, workSpace, wkspSize); + } + + if (ERR_isError(hSize)) continue; + + newSize = HUF_estimateCompressedSize(table, count, maxSymbolValue) + hSize; + + if (newSize > optSize + 1) { + break; + } + + if (newSize < optSize) { + optSize = newSize; + optLog = optLogGuess; + } + } + assert(optLog <= HUF_TABLELOG_MAX); + return optLog; + } +} + +/* HUF_compress_internal() : + * `workSpace_align4` must be aligned on 4-bytes boundaries, + * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U64 unsigned */ +static size_t +HUF_compress_internal (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + HUF_nbStreams_e nbStreams, + void* workSpace, size_t wkspSize, + HUF_CElt* oldHufTable, HUF_repeat* repeat, int flags) +{ + HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(size_t)); + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart; + + DEBUGLOG(5, "HUF_compress_internal (srcSize=%zu)", srcSize); + HUF_STATIC_ASSERT(sizeof(*table) + HUF_WORKSPACE_MAX_ALIGNMENT <= HUF_WORKSPACE_SIZE); + + /* checks & inits */ + if (wkspSize < sizeof(*table)) return ERROR(workSpace_tooSmall); + if (!srcSize) return 0; /* Uncompressed */ + if (!dstSize) return 0; /* cannot fit anything within dst budget */ + if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */ + if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); + if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX; + if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT; + + /* Heuristic : If old table is valid, use it for small inputs */ + if ((flags & HUF_flags_preferRepeat) && repeat && *repeat == HUF_repeat_valid) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } + + /* If uncompressible data is suspected, do a smaller sampling first */ + DEBUG_STATIC_ASSERT(SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO >= 2); + if ((flags & HUF_flags_suspectUncompressible) && srcSize >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO)) { + size_t largestTotal = 0; + DEBUGLOG(5, "input suspected incompressible : sampling to check"); + { unsigned maxSymbolValueBegin = maxSymbolValue; + CHECK_V_F(largestBegin, HIST_count_simple (table->count, &maxSymbolValueBegin, (const BYTE*)src, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) ); + largestTotal += largestBegin; + } + { unsigned maxSymbolValueEnd = maxSymbolValue; + CHECK_V_F(largestEnd, HIST_count_simple (table->count, &maxSymbolValueEnd, (const BYTE*)src + srcSize - SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) ); + largestTotal += largestEnd; + } + if (largestTotal <= ((2 * SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) >> 7)+4) return 0; /* heuristic : probably not compressible enough */ + } + + /* Scan input and build symbol stats */ + { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->wksps.hist_wksp, sizeof(table->wksps.hist_wksp)) ); + if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ + if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */ + } + DEBUGLOG(6, "histogram detail completed (%zu symbols)", showU32(table->count, maxSymbolValue+1)); + + /* Check validity of previous table */ + if ( repeat + && *repeat == HUF_repeat_check + && !HUF_validateCTable(oldHufTable, table->count, maxSymbolValue)) { + *repeat = HUF_repeat_none; + } + /* Heuristic : use existing table for small inputs */ + if ((flags & HUF_flags_preferRepeat) && repeat && *repeat != HUF_repeat_none) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } + + /* Build Huffman Tree */ + huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, &table->wksps, sizeof(table->wksps), table->CTable, table->count, flags); + { size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count, + maxSymbolValue, huffLog, + &table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp)); + CHECK_F(maxBits); + huffLog = (U32)maxBits; + DEBUGLOG(6, "bit distribution completed (%zu symbols)", showCTableBits(table->CTable + 1, maxSymbolValue+1)); + } + + /* Write table description header */ + { CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, table->CTable, maxSymbolValue, huffLog, + &table->wksps.writeCTable_wksp, sizeof(table->wksps.writeCTable_wksp)) ); + /* Check if using previous huffman table is beneficial */ + if (repeat && *repeat != HUF_repeat_none) { + size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, table->count, maxSymbolValue); + size_t const newSize = HUF_estimateCompressedSize(table->CTable, table->count, maxSymbolValue); + if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } } + + /* Use the new huffman table */ + if (hSize + 12ul >= srcSize) { return 0; } + op += hSize; + if (repeat) { *repeat = HUF_repeat_none; } + if (oldHufTable) + ZSTD_memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */ + } + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, table->CTable, flags); +} + +size_t HUF_compress1X_repeat (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + void* workSpace, size_t wkspSize, + HUF_CElt* hufTable, HUF_repeat* repeat, int flags) +{ + DEBUGLOG(5, "HUF_compress1X_repeat (srcSize = %zu)", srcSize); + return HUF_compress_internal(dst, dstSize, src, srcSize, + maxSymbolValue, huffLog, HUF_singleStream, + workSpace, wkspSize, hufTable, + repeat, flags); +} + +/* HUF_compress4X_repeat(): + * compress input using 4 streams. + * consider skipping quickly + * reuse an existing huffman compression table */ +size_t HUF_compress4X_repeat (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + void* workSpace, size_t wkspSize, + HUF_CElt* hufTable, HUF_repeat* repeat, int flags) +{ + DEBUGLOG(5, "HUF_compress4X_repeat (srcSize = %zu)", srcSize); + return HUF_compress_internal(dst, dstSize, src, srcSize, + maxSymbolValue, huffLog, HUF_fourStreams, + workSpace, wkspSize, + hufTable, repeat, flags); +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress.c new file mode 100644 index 000000000..d928b1d3e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress.c @@ -0,0 +1,7843 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ +#include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */ +#include "../common/mem.h" +#include "../common/error_private.h" +#include "hist.h" /* HIST_countFast_wksp */ +#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */ +#include "../common/fse.h" +#include "../common/huf.h" +#include "zstd_compress_internal.h" +#include "zstd_compress_sequences.h" +#include "zstd_compress_literals.h" +#include "zstd_fast.h" +#include "zstd_double_fast.h" +#include "zstd_lazy.h" +#include "zstd_opt.h" +#include "zstd_ldm.h" +#include "zstd_compress_superblock.h" +#include "../common/bits.h" /* ZSTD_highbit32, ZSTD_rotateRight_U64 */ + +/* *************************************************************** +* Tuning parameters +*****************************************************************/ +/*! + * COMPRESS_HEAPMODE : + * Select how default decompression function ZSTD_compress() allocates its context, + * on stack (0, default), or into heap (1). + * Note that functions with explicit context such as ZSTD_compressCCtx() are unaffected. + */ +#ifndef ZSTD_COMPRESS_HEAPMODE +# define ZSTD_COMPRESS_HEAPMODE 0 +#endif + +/*! + * ZSTD_HASHLOG3_MAX : + * Maximum size of the hash table dedicated to find 3-bytes matches, + * in log format, aka 17 => 1 << 17 == 128Ki positions. + * This structure is only used in zstd_opt. + * Since allocation is centralized for all strategies, it has to be known here. + * The actual (selected) size of the hash table is then stored in ZSTD_MatchState_t.hashLog3, + * so that zstd_opt.c doesn't need to know about this constant. + */ +#ifndef ZSTD_HASHLOG3_MAX +# define ZSTD_HASHLOG3_MAX 17 +#endif + +/*-************************************* +* Helper functions +***************************************/ +/* ZSTD_compressBound() + * Note that the result from this function is only valid for + * the one-pass compression functions. + * When employing the streaming mode, + * if flushes are frequently altering the size of blocks, + * the overhead from block headers can make the compressed data larger + * than the return value of ZSTD_compressBound(). + */ +size_t ZSTD_compressBound(size_t srcSize) { + size_t const r = ZSTD_COMPRESSBOUND(srcSize); + if (r==0) return ERROR(srcSize_wrong); + return r; +} + + +/*-************************************* +* Context memory management +***************************************/ +struct ZSTD_CDict_s { + const void* dictContent; + size_t dictContentSize; + ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */ + U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */ + ZSTD_cwksp workspace; + ZSTD_MatchState_t matchState; + ZSTD_compressedBlockState_t cBlockState; + ZSTD_customMem customMem; + U32 dictID; + int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */ + ZSTD_ParamSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use + * row-based matchfinder. Unless the cdict is reloaded, we will use + * the same greedy/lazy matchfinder at compression time. + */ +}; /* typedef'd to ZSTD_CDict within "zstd.h" */ + +ZSTD_CCtx* ZSTD_createCCtx(void) +{ + return ZSTD_createCCtx_advanced(ZSTD_defaultCMem); +} + +static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager) +{ + assert(cctx != NULL); + ZSTD_memset(cctx, 0, sizeof(*cctx)); + cctx->customMem = memManager; + cctx->bmi2 = ZSTD_cpuSupportsBmi2(); + { size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters); + assert(!ZSTD_isError(err)); + (void)err; + } +} + +ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) +{ + ZSTD_STATIC_ASSERT(zcss_init==0); + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1)); + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_customMalloc(sizeof(ZSTD_CCtx), customMem); + if (!cctx) return NULL; + ZSTD_initCCtx(cctx, customMem); + return cctx; + } +} + +ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize) +{ + ZSTD_cwksp ws; + ZSTD_CCtx* cctx; + if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL; /* minimum size */ + if ((size_t)workspace & 7) return NULL; /* must be 8-aligned */ + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc); + + cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx)); + if (cctx == NULL) return NULL; + + ZSTD_memset(cctx, 0, sizeof(ZSTD_CCtx)); + ZSTD_cwksp_move(&cctx->workspace, &ws); + cctx->staticSize = workspaceSize; + + /* statically sized space. tmpWorkspace never moves (but prev/next block swap places) */ + if (!ZSTD_cwksp_check_available(&cctx->workspace, TMP_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL; + cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t)); + cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t)); + cctx->tmpWorkspace = ZSTD_cwksp_reserve_object(&cctx->workspace, TMP_WORKSPACE_SIZE); + cctx->tmpWkspSize = TMP_WORKSPACE_SIZE; + cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); + return cctx; +} + +/** + * Clears and frees all of the dictionaries in the CCtx. + */ +static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx) +{ + ZSTD_customFree(cctx->localDict.dictBuffer, cctx->customMem); + ZSTD_freeCDict(cctx->localDict.cdict); + ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict)); + ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); + cctx->cdict = NULL; +} + +static size_t ZSTD_sizeof_localDict(ZSTD_localDict dict) +{ + size_t const bufferSize = dict.dictBuffer != NULL ? dict.dictSize : 0; + size_t const cdictSize = ZSTD_sizeof_CDict(dict.cdict); + return bufferSize + cdictSize; +} + +static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx) +{ + assert(cctx != NULL); + assert(cctx->staticSize == 0); + ZSTD_clearAllDicts(cctx); +#ifdef ZSTD_MULTITHREAD + ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL; +#endif + ZSTD_cwksp_free(&cctx->workspace, cctx->customMem); +} + +size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) +{ + DEBUGLOG(3, "ZSTD_freeCCtx (address: %p)", (void*)cctx); + if (cctx==NULL) return 0; /* support free on NULL */ + RETURN_ERROR_IF(cctx->staticSize, memory_allocation, + "not compatible with static CCtx"); + { int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx); + ZSTD_freeCCtxContent(cctx); + if (!cctxInWorkspace) ZSTD_customFree(cctx, cctx->customMem); + } + return 0; +} + + +static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx) +{ +#ifdef ZSTD_MULTITHREAD + return ZSTDMT_sizeof_CCtx(cctx->mtctx); +#else + (void)cctx; + return 0; +#endif +} + + +size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx) +{ + if (cctx==NULL) return 0; /* support sizeof on NULL */ + /* cctx may be in the workspace */ + return (cctx->workspace.workspace == cctx ? 0 : sizeof(*cctx)) + + ZSTD_cwksp_sizeof(&cctx->workspace) + + ZSTD_sizeof_localDict(cctx->localDict) + + ZSTD_sizeof_mtctx(cctx); +} + +size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs) +{ + return ZSTD_sizeof_CCtx(zcs); /* same object */ +} + +/* private API call, for dictBuilder only */ +const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); } + +/* Returns true if the strategy supports using a row based matchfinder */ +static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) { + return (strategy >= ZSTD_greedy && strategy <= ZSTD_lazy2); +} + +/* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder + * for this compression. + */ +static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_ParamSwitch_e mode) { + assert(mode != ZSTD_ps_auto); + return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable); +} + +/* Returns row matchfinder usage given an initial mode and cParams */ +static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */ + mode = ZSTD_ps_disable; + if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode; + if (cParams->windowLog > 14) mode = ZSTD_ps_enable; + return mode; +} + +/* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */ +static ZSTD_ParamSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; + return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable; +} + +/* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */ +static int ZSTD_allocateChainTable(const ZSTD_strategy strategy, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const U32 forDDSDict) { + assert(useRowMatchFinder != ZSTD_ps_auto); + /* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate. + * We do not allocate a chaintable if we are using ZSTD_fast, or are using the row-based matchfinder. + */ + return forDDSDict || ((strategy != ZSTD_fast) && !ZSTD_rowMatchFinderUsed(strategy, useRowMatchFinder)); +} + +/* Returns ZSTD_ps_enable if compression parameters are such that we should + * enable long distance matching (wlog >= 27, strategy >= btopt). + * Returns ZSTD_ps_disable otherwise. + */ +static ZSTD_ParamSwitch_e ZSTD_resolveEnableLdm(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; + return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable; +} + +static int ZSTD_resolveExternalSequenceValidation(int mode) { + return mode; +} + +/* Resolves maxBlockSize to the default if no value is present. */ +static size_t ZSTD_resolveMaxBlockSize(size_t maxBlockSize) { + if (maxBlockSize == 0) { + return ZSTD_BLOCKSIZE_MAX; + } else { + return maxBlockSize; + } +} + +static ZSTD_ParamSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_ParamSwitch_e value, int cLevel) { + if (value != ZSTD_ps_auto) return value; + if (cLevel < 10) { + return ZSTD_ps_disable; + } else { + return ZSTD_ps_enable; + } +} + +/* Returns 1 if compression parameters are such that CDict hashtable and chaintable indices are tagged. + * If so, the tags need to be removed in ZSTD_resetCCtx_byCopyingCDict. */ +static int ZSTD_CDictIndicesAreTagged(const ZSTD_compressionParameters* const cParams) { + return cParams->strategy == ZSTD_fast || cParams->strategy == ZSTD_dfast; +} + +static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( + ZSTD_compressionParameters cParams) +{ + ZSTD_CCtx_params cctxParams; + /* should not matter, as all cParams are presumed properly defined */ + ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT); + cctxParams.cParams = cParams; + + /* Adjust advanced params according to cParams */ + cctxParams.ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams.ldmParams.enableLdm, &cParams); + if (cctxParams.ldmParams.enableLdm == ZSTD_ps_enable) { + ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams); + assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog); + assert(cctxParams.ldmParams.hashRateLog < 32); + } + cctxParams.postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.postBlockSplitter, &cParams); + cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); + cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences); + cctxParams.maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams.maxBlockSize); + cctxParams.searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams.searchForExternalRepcodes, + cctxParams.compressionLevel); + assert(!ZSTD_checkCParams(cParams)); + return cctxParams; +} + +static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced( + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params* params; + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + params = (ZSTD_CCtx_params*)ZSTD_customCalloc( + sizeof(ZSTD_CCtx_params), customMem); + if (!params) { return NULL; } + ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT); + params->customMem = customMem; + return params; +} + +ZSTD_CCtx_params* ZSTD_createCCtxParams(void) +{ + return ZSTD_createCCtxParams_advanced(ZSTD_defaultCMem); +} + +size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params) +{ + if (params == NULL) { return 0; } + ZSTD_customFree(params, params->customMem); + return 0; +} + +size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params) +{ + return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT); +} + +size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) { + RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!"); + ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); + cctxParams->compressionLevel = compressionLevel; + cctxParams->fParams.contentSizeFlag = 1; + return 0; +} + +#define ZSTD_NO_CLEVEL 0 + +/** + * Initializes `cctxParams` from `params` and `compressionLevel`. + * @param compressionLevel If params are derived from a compression level then that compression level, otherwise ZSTD_NO_CLEVEL. + */ +static void +ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, + const ZSTD_parameters* params, + int compressionLevel) +{ + assert(!ZSTD_checkCParams(params->cParams)); + ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); + cctxParams->cParams = params->cParams; + cctxParams->fParams = params->fParams; + /* Should not matter, as all cParams are presumed properly defined. + * But, set it for tracing anyway. + */ + cctxParams->compressionLevel = compressionLevel; + cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, ¶ms->cParams); + cctxParams->postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->postBlockSplitter, ¶ms->cParams); + cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, ¶ms->cParams); + cctxParams->validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams->validateSequences); + cctxParams->maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams->maxBlockSize); + cctxParams->searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams->searchForExternalRepcodes, compressionLevel); + DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d", + cctxParams->useRowMatchFinder, cctxParams->postBlockSplitter, cctxParams->ldmParams.enableLdm); +} + +size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params) +{ + RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!"); + FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , ""); + ZSTD_CCtxParams_init_internal(cctxParams, ¶ms, ZSTD_NO_CLEVEL); + return 0; +} + +/** + * Sets cctxParams' cParams and fParams from params, but otherwise leaves them alone. + * @param params Validated zstd parameters. + */ +static void ZSTD_CCtxParams_setZstdParams( + ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params) +{ + assert(!ZSTD_checkCParams(params->cParams)); + cctxParams->cParams = params->cParams; + cctxParams->fParams = params->fParams; + /* Should not matter, as all cParams are presumed properly defined. + * But, set it for tracing anyway. + */ + cctxParams->compressionLevel = ZSTD_NO_CLEVEL; +} + +ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) +{ + ZSTD_bounds bounds = { 0, 0, 0 }; + + switch(param) + { + case ZSTD_c_compressionLevel: + bounds.lowerBound = ZSTD_minCLevel(); + bounds.upperBound = ZSTD_maxCLevel(); + return bounds; + + case ZSTD_c_windowLog: + bounds.lowerBound = ZSTD_WINDOWLOG_MIN; + bounds.upperBound = ZSTD_WINDOWLOG_MAX; + return bounds; + + case ZSTD_c_hashLog: + bounds.lowerBound = ZSTD_HASHLOG_MIN; + bounds.upperBound = ZSTD_HASHLOG_MAX; + return bounds; + + case ZSTD_c_chainLog: + bounds.lowerBound = ZSTD_CHAINLOG_MIN; + bounds.upperBound = ZSTD_CHAINLOG_MAX; + return bounds; + + case ZSTD_c_searchLog: + bounds.lowerBound = ZSTD_SEARCHLOG_MIN; + bounds.upperBound = ZSTD_SEARCHLOG_MAX; + return bounds; + + case ZSTD_c_minMatch: + bounds.lowerBound = ZSTD_MINMATCH_MIN; + bounds.upperBound = ZSTD_MINMATCH_MAX; + return bounds; + + case ZSTD_c_targetLength: + bounds.lowerBound = ZSTD_TARGETLENGTH_MIN; + bounds.upperBound = ZSTD_TARGETLENGTH_MAX; + return bounds; + + case ZSTD_c_strategy: + bounds.lowerBound = ZSTD_STRATEGY_MIN; + bounds.upperBound = ZSTD_STRATEGY_MAX; + return bounds; + + case ZSTD_c_contentSizeFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_checksumFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_dictIDFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_nbWorkers: + bounds.lowerBound = 0; +#ifdef ZSTD_MULTITHREAD + bounds.upperBound = ZSTDMT_NBWORKERS_MAX; +#else + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_jobSize: + bounds.lowerBound = 0; +#ifdef ZSTD_MULTITHREAD + bounds.upperBound = ZSTDMT_JOBSIZE_MAX; +#else + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_overlapLog: +#ifdef ZSTD_MULTITHREAD + bounds.lowerBound = ZSTD_OVERLAPLOG_MIN; + bounds.upperBound = ZSTD_OVERLAPLOG_MAX; +#else + bounds.lowerBound = 0; + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_enableDedicatedDictSearch: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_enableLongDistanceMatching: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_ldmHashLog: + bounds.lowerBound = ZSTD_LDM_HASHLOG_MIN; + bounds.upperBound = ZSTD_LDM_HASHLOG_MAX; + return bounds; + + case ZSTD_c_ldmMinMatch: + bounds.lowerBound = ZSTD_LDM_MINMATCH_MIN; + bounds.upperBound = ZSTD_LDM_MINMATCH_MAX; + return bounds; + + case ZSTD_c_ldmBucketSizeLog: + bounds.lowerBound = ZSTD_LDM_BUCKETSIZELOG_MIN; + bounds.upperBound = ZSTD_LDM_BUCKETSIZELOG_MAX; + return bounds; + + case ZSTD_c_ldmHashRateLog: + bounds.lowerBound = ZSTD_LDM_HASHRATELOG_MIN; + bounds.upperBound = ZSTD_LDM_HASHRATELOG_MAX; + return bounds; + + /* experimental parameters */ + case ZSTD_c_rsyncable: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_forceMaxWindow : + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_format: + ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless); + bounds.lowerBound = ZSTD_f_zstd1; + bounds.upperBound = ZSTD_f_zstd1_magicless; /* note : how to ensure at compile time that this is the highest value enum ? */ + return bounds; + + case ZSTD_c_forceAttachDict: + ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceLoad); + bounds.lowerBound = ZSTD_dictDefaultAttach; + bounds.upperBound = ZSTD_dictForceLoad; /* note : how to ensure at compile time that this is the highest value enum ? */ + return bounds; + + case ZSTD_c_literalCompressionMode: + ZSTD_STATIC_ASSERT(ZSTD_ps_auto < ZSTD_ps_enable && ZSTD_ps_enable < ZSTD_ps_disable); + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_targetCBlockSize: + bounds.lowerBound = ZSTD_TARGETCBLOCKSIZE_MIN; + bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX; + return bounds; + + case ZSTD_c_srcSizeHint: + bounds.lowerBound = ZSTD_SRCSIZEHINT_MIN; + bounds.upperBound = ZSTD_SRCSIZEHINT_MAX; + return bounds; + + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + bounds.lowerBound = (int)ZSTD_bm_buffered; + bounds.upperBound = (int)ZSTD_bm_stable; + return bounds; + + case ZSTD_c_blockDelimiters: + bounds.lowerBound = (int)ZSTD_sf_noBlockDelimiters; + bounds.upperBound = (int)ZSTD_sf_explicitBlockDelimiters; + return bounds; + + case ZSTD_c_validateSequences: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_splitAfterSequences: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_blockSplitterLevel: + bounds.lowerBound = 0; + bounds.upperBound = ZSTD_BLOCKSPLITTER_LEVEL_MAX; + return bounds; + + case ZSTD_c_useRowMatchFinder: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_deterministicRefPrefix: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_prefetchCDictTables: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_enableSeqProducerFallback: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_maxBlockSize: + bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN; + bounds.upperBound = ZSTD_BLOCKSIZE_MAX; + return bounds; + + case ZSTD_c_repcodeResolution: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + default: + bounds.error = ERROR(parameter_unsupported); + return bounds; + } +} + +/* ZSTD_cParam_clampBounds: + * Clamps the value into the bounded range. + */ +static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value) +{ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); + if (ZSTD_isError(bounds.error)) return bounds.error; + if (*value < bounds.lowerBound) *value = bounds.lowerBound; + if (*value > bounds.upperBound) *value = bounds.upperBound; + return 0; +} + +#define BOUNDCHECK(cParam, val) \ + do { \ + RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \ + parameter_outOfBound, "Param out of bounds"); \ + } while (0) + + +static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) +{ + switch(param) + { + case ZSTD_c_compressionLevel: + case ZSTD_c_hashLog: + case ZSTD_c_chainLog: + case ZSTD_c_searchLog: + case ZSTD_c_minMatch: + case ZSTD_c_targetLength: + case ZSTD_c_strategy: + case ZSTD_c_blockSplitterLevel: + return 1; + + case ZSTD_c_format: + case ZSTD_c_windowLog: + case ZSTD_c_contentSizeFlag: + case ZSTD_c_checksumFlag: + case ZSTD_c_dictIDFlag: + case ZSTD_c_forceMaxWindow : + case ZSTD_c_nbWorkers: + case ZSTD_c_jobSize: + case ZSTD_c_overlapLog: + case ZSTD_c_rsyncable: + case ZSTD_c_enableDedicatedDictSearch: + case ZSTD_c_enableLongDistanceMatching: + case ZSTD_c_ldmHashLog: + case ZSTD_c_ldmMinMatch: + case ZSTD_c_ldmBucketSizeLog: + case ZSTD_c_ldmHashRateLog: + case ZSTD_c_forceAttachDict: + case ZSTD_c_literalCompressionMode: + case ZSTD_c_targetCBlockSize: + case ZSTD_c_srcSizeHint: + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + case ZSTD_c_blockDelimiters: + case ZSTD_c_validateSequences: + case ZSTD_c_splitAfterSequences: + case ZSTD_c_useRowMatchFinder: + case ZSTD_c_deterministicRefPrefix: + case ZSTD_c_prefetchCDictTables: + case ZSTD_c_enableSeqProducerFallback: + case ZSTD_c_maxBlockSize: + case ZSTD_c_repcodeResolution: + default: + return 0; + } +} + +size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParameter (%i, %i)", (int)param, value); + if (cctx->streamStage != zcss_init) { + if (ZSTD_isUpdateAuthorized(param)) { + cctx->cParamsChanged = 1; + } else { + RETURN_ERROR(stage_wrong, "can only set params in cctx init stage"); + } } + + switch(param) + { + case ZSTD_c_nbWorkers: + RETURN_ERROR_IF((value!=0) && cctx->staticSize, parameter_unsupported, + "MT not compatible with static alloc"); + break; + + case ZSTD_c_compressionLevel: + case ZSTD_c_windowLog: + case ZSTD_c_hashLog: + case ZSTD_c_chainLog: + case ZSTD_c_searchLog: + case ZSTD_c_minMatch: + case ZSTD_c_targetLength: + case ZSTD_c_strategy: + case ZSTD_c_ldmHashRateLog: + case ZSTD_c_format: + case ZSTD_c_contentSizeFlag: + case ZSTD_c_checksumFlag: + case ZSTD_c_dictIDFlag: + case ZSTD_c_forceMaxWindow: + case ZSTD_c_forceAttachDict: + case ZSTD_c_literalCompressionMode: + case ZSTD_c_jobSize: + case ZSTD_c_overlapLog: + case ZSTD_c_rsyncable: + case ZSTD_c_enableDedicatedDictSearch: + case ZSTD_c_enableLongDistanceMatching: + case ZSTD_c_ldmHashLog: + case ZSTD_c_ldmMinMatch: + case ZSTD_c_ldmBucketSizeLog: + case ZSTD_c_targetCBlockSize: + case ZSTD_c_srcSizeHint: + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + case ZSTD_c_blockDelimiters: + case ZSTD_c_validateSequences: + case ZSTD_c_splitAfterSequences: + case ZSTD_c_blockSplitterLevel: + case ZSTD_c_useRowMatchFinder: + case ZSTD_c_deterministicRefPrefix: + case ZSTD_c_prefetchCDictTables: + case ZSTD_c_enableSeqProducerFallback: + case ZSTD_c_maxBlockSize: + case ZSTD_c_repcodeResolution: + break; + + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } + return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value); +} + +size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, + ZSTD_cParameter param, int value) +{ + DEBUGLOG(4, "ZSTD_CCtxParams_setParameter (%i, %i)", (int)param, value); + switch(param) + { + case ZSTD_c_format : + BOUNDCHECK(ZSTD_c_format, value); + CCtxParams->format = (ZSTD_format_e)value; + return (size_t)CCtxParams->format; + + case ZSTD_c_compressionLevel : { + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + if (value == 0) + CCtxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ + else + CCtxParams->compressionLevel = value; + if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel; + return 0; /* return type (size_t) cannot represent negative values */ + } + + case ZSTD_c_windowLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_windowLog, value); + CCtxParams->cParams.windowLog = (U32)value; + return CCtxParams->cParams.windowLog; + + case ZSTD_c_hashLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_hashLog, value); + CCtxParams->cParams.hashLog = (U32)value; + return CCtxParams->cParams.hashLog; + + case ZSTD_c_chainLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_chainLog, value); + CCtxParams->cParams.chainLog = (U32)value; + return CCtxParams->cParams.chainLog; + + case ZSTD_c_searchLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_searchLog, value); + CCtxParams->cParams.searchLog = (U32)value; + return (size_t)value; + + case ZSTD_c_minMatch : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_minMatch, value); + CCtxParams->cParams.minMatch = (U32)value; + return CCtxParams->cParams.minMatch; + + case ZSTD_c_targetLength : + BOUNDCHECK(ZSTD_c_targetLength, value); + CCtxParams->cParams.targetLength = (U32)value; + return CCtxParams->cParams.targetLength; + + case ZSTD_c_strategy : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_strategy, value); + CCtxParams->cParams.strategy = (ZSTD_strategy)value; + return (size_t)CCtxParams->cParams.strategy; + + case ZSTD_c_contentSizeFlag : + /* Content size written in frame header _when known_ (default:1) */ + DEBUGLOG(4, "set content size flag = %u", (value!=0)); + CCtxParams->fParams.contentSizeFlag = value != 0; + return (size_t)CCtxParams->fParams.contentSizeFlag; + + case ZSTD_c_checksumFlag : + /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */ + CCtxParams->fParams.checksumFlag = value != 0; + return (size_t)CCtxParams->fParams.checksumFlag; + + case ZSTD_c_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */ + DEBUGLOG(4, "set dictIDFlag = %u", (value!=0)); + CCtxParams->fParams.noDictIDFlag = !value; + return !CCtxParams->fParams.noDictIDFlag; + + case ZSTD_c_forceMaxWindow : + CCtxParams->forceWindow = (value != 0); + return (size_t)CCtxParams->forceWindow; + + case ZSTD_c_forceAttachDict : { + const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value; + BOUNDCHECK(ZSTD_c_forceAttachDict, (int)pref); + CCtxParams->attachDictPref = pref; + return CCtxParams->attachDictPref; + } + + case ZSTD_c_literalCompressionMode : { + const ZSTD_ParamSwitch_e lcm = (ZSTD_ParamSwitch_e)value; + BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm); + CCtxParams->literalCompressionMode = lcm; + return CCtxParams->literalCompressionMode; + } + + case ZSTD_c_nbWorkers : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + CCtxParams->nbWorkers = value; + return (size_t)(CCtxParams->nbWorkers); +#endif + + case ZSTD_c_jobSize : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + /* Adjust to the minimum non-default value. */ + if (value != 0 && value < ZSTDMT_JOBSIZE_MIN) + value = ZSTDMT_JOBSIZE_MIN; + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + assert(value >= 0); + CCtxParams->jobSize = (size_t)value; + return CCtxParams->jobSize; +#endif + + case ZSTD_c_overlapLog : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), ""); + CCtxParams->overlapLog = value; + return (size_t)CCtxParams->overlapLog; +#endif + + case ZSTD_c_rsyncable : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), ""); + CCtxParams->rsyncable = value; + return (size_t)CCtxParams->rsyncable; +#endif + + case ZSTD_c_enableDedicatedDictSearch : + CCtxParams->enableDedicatedDictSearch = (value!=0); + return (size_t)CCtxParams->enableDedicatedDictSearch; + + case ZSTD_c_enableLongDistanceMatching : + BOUNDCHECK(ZSTD_c_enableLongDistanceMatching, value); + CCtxParams->ldmParams.enableLdm = (ZSTD_ParamSwitch_e)value; + return CCtxParams->ldmParams.enableLdm; + + case ZSTD_c_ldmHashLog : + if (value!=0) /* 0 ==> auto */ + BOUNDCHECK(ZSTD_c_ldmHashLog, value); + CCtxParams->ldmParams.hashLog = (U32)value; + return CCtxParams->ldmParams.hashLog; + + case ZSTD_c_ldmMinMatch : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmMinMatch, value); + CCtxParams->ldmParams.minMatchLength = (U32)value; + return CCtxParams->ldmParams.minMatchLength; + + case ZSTD_c_ldmBucketSizeLog : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmBucketSizeLog, value); + CCtxParams->ldmParams.bucketSizeLog = (U32)value; + return CCtxParams->ldmParams.bucketSizeLog; + + case ZSTD_c_ldmHashRateLog : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmHashRateLog, value); + CCtxParams->ldmParams.hashRateLog = (U32)value; + return CCtxParams->ldmParams.hashRateLog; + + case ZSTD_c_targetCBlockSize : + if (value!=0) { /* 0 ==> default */ + value = MAX(value, ZSTD_TARGETCBLOCKSIZE_MIN); + BOUNDCHECK(ZSTD_c_targetCBlockSize, value); + } + CCtxParams->targetCBlockSize = (U32)value; + return CCtxParams->targetCBlockSize; + + case ZSTD_c_srcSizeHint : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_srcSizeHint, value); + CCtxParams->srcSizeHint = value; + return (size_t)CCtxParams->srcSizeHint; + + case ZSTD_c_stableInBuffer: + BOUNDCHECK(ZSTD_c_stableInBuffer, value); + CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value; + return CCtxParams->inBufferMode; + + case ZSTD_c_stableOutBuffer: + BOUNDCHECK(ZSTD_c_stableOutBuffer, value); + CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value; + return CCtxParams->outBufferMode; + + case ZSTD_c_blockDelimiters: + BOUNDCHECK(ZSTD_c_blockDelimiters, value); + CCtxParams->blockDelimiters = (ZSTD_SequenceFormat_e)value; + return CCtxParams->blockDelimiters; + + case ZSTD_c_validateSequences: + BOUNDCHECK(ZSTD_c_validateSequences, value); + CCtxParams->validateSequences = value; + return (size_t)CCtxParams->validateSequences; + + case ZSTD_c_splitAfterSequences: + BOUNDCHECK(ZSTD_c_splitAfterSequences, value); + CCtxParams->postBlockSplitter = (ZSTD_ParamSwitch_e)value; + return CCtxParams->postBlockSplitter; + + case ZSTD_c_blockSplitterLevel: + BOUNDCHECK(ZSTD_c_blockSplitterLevel, value); + CCtxParams->preBlockSplitter_level = value; + return (size_t)CCtxParams->preBlockSplitter_level; + + case ZSTD_c_useRowMatchFinder: + BOUNDCHECK(ZSTD_c_useRowMatchFinder, value); + CCtxParams->useRowMatchFinder = (ZSTD_ParamSwitch_e)value; + return CCtxParams->useRowMatchFinder; + + case ZSTD_c_deterministicRefPrefix: + BOUNDCHECK(ZSTD_c_deterministicRefPrefix, value); + CCtxParams->deterministicRefPrefix = !!value; + return (size_t)CCtxParams->deterministicRefPrefix; + + case ZSTD_c_prefetchCDictTables: + BOUNDCHECK(ZSTD_c_prefetchCDictTables, value); + CCtxParams->prefetchCDictTables = (ZSTD_ParamSwitch_e)value; + return CCtxParams->prefetchCDictTables; + + case ZSTD_c_enableSeqProducerFallback: + BOUNDCHECK(ZSTD_c_enableSeqProducerFallback, value); + CCtxParams->enableMatchFinderFallback = value; + return (size_t)CCtxParams->enableMatchFinderFallback; + + case ZSTD_c_maxBlockSize: + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_maxBlockSize, value); + assert(value>=0); + CCtxParams->maxBlockSize = (size_t)value; + return CCtxParams->maxBlockSize; + + case ZSTD_c_repcodeResolution: + BOUNDCHECK(ZSTD_c_repcodeResolution, value); + CCtxParams->searchForExternalRepcodes = (ZSTD_ParamSwitch_e)value; + return CCtxParams->searchForExternalRepcodes; + + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } +} + +size_t ZSTD_CCtx_getParameter(ZSTD_CCtx const* cctx, ZSTD_cParameter param, int* value) +{ + return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value); +} + +size_t ZSTD_CCtxParams_getParameter( + ZSTD_CCtx_params const* CCtxParams, ZSTD_cParameter param, int* value) +{ + switch(param) + { + case ZSTD_c_format : + *value = (int)CCtxParams->format; + break; + case ZSTD_c_compressionLevel : + *value = CCtxParams->compressionLevel; + break; + case ZSTD_c_windowLog : + *value = (int)CCtxParams->cParams.windowLog; + break; + case ZSTD_c_hashLog : + *value = (int)CCtxParams->cParams.hashLog; + break; + case ZSTD_c_chainLog : + *value = (int)CCtxParams->cParams.chainLog; + break; + case ZSTD_c_searchLog : + *value = (int)CCtxParams->cParams.searchLog; + break; + case ZSTD_c_minMatch : + *value = (int)CCtxParams->cParams.minMatch; + break; + case ZSTD_c_targetLength : + *value = (int)CCtxParams->cParams.targetLength; + break; + case ZSTD_c_strategy : + *value = (int)CCtxParams->cParams.strategy; + break; + case ZSTD_c_contentSizeFlag : + *value = CCtxParams->fParams.contentSizeFlag; + break; + case ZSTD_c_checksumFlag : + *value = CCtxParams->fParams.checksumFlag; + break; + case ZSTD_c_dictIDFlag : + *value = !CCtxParams->fParams.noDictIDFlag; + break; + case ZSTD_c_forceMaxWindow : + *value = CCtxParams->forceWindow; + break; + case ZSTD_c_forceAttachDict : + *value = (int)CCtxParams->attachDictPref; + break; + case ZSTD_c_literalCompressionMode : + *value = (int)CCtxParams->literalCompressionMode; + break; + case ZSTD_c_nbWorkers : +#ifndef ZSTD_MULTITHREAD + assert(CCtxParams->nbWorkers == 0); +#endif + *value = CCtxParams->nbWorkers; + break; + case ZSTD_c_jobSize : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + assert(CCtxParams->jobSize <= INT_MAX); + *value = (int)CCtxParams->jobSize; + break; +#endif + case ZSTD_c_overlapLog : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + *value = CCtxParams->overlapLog; + break; +#endif + case ZSTD_c_rsyncable : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + *value = CCtxParams->rsyncable; + break; +#endif + case ZSTD_c_enableDedicatedDictSearch : + *value = CCtxParams->enableDedicatedDictSearch; + break; + case ZSTD_c_enableLongDistanceMatching : + *value = (int)CCtxParams->ldmParams.enableLdm; + break; + case ZSTD_c_ldmHashLog : + *value = (int)CCtxParams->ldmParams.hashLog; + break; + case ZSTD_c_ldmMinMatch : + *value = (int)CCtxParams->ldmParams.minMatchLength; + break; + case ZSTD_c_ldmBucketSizeLog : + *value = (int)CCtxParams->ldmParams.bucketSizeLog; + break; + case ZSTD_c_ldmHashRateLog : + *value = (int)CCtxParams->ldmParams.hashRateLog; + break; + case ZSTD_c_targetCBlockSize : + *value = (int)CCtxParams->targetCBlockSize; + break; + case ZSTD_c_srcSizeHint : + *value = (int)CCtxParams->srcSizeHint; + break; + case ZSTD_c_stableInBuffer : + *value = (int)CCtxParams->inBufferMode; + break; + case ZSTD_c_stableOutBuffer : + *value = (int)CCtxParams->outBufferMode; + break; + case ZSTD_c_blockDelimiters : + *value = (int)CCtxParams->blockDelimiters; + break; + case ZSTD_c_validateSequences : + *value = (int)CCtxParams->validateSequences; + break; + case ZSTD_c_splitAfterSequences : + *value = (int)CCtxParams->postBlockSplitter; + break; + case ZSTD_c_blockSplitterLevel : + *value = CCtxParams->preBlockSplitter_level; + break; + case ZSTD_c_useRowMatchFinder : + *value = (int)CCtxParams->useRowMatchFinder; + break; + case ZSTD_c_deterministicRefPrefix: + *value = (int)CCtxParams->deterministicRefPrefix; + break; + case ZSTD_c_prefetchCDictTables: + *value = (int)CCtxParams->prefetchCDictTables; + break; + case ZSTD_c_enableSeqProducerFallback: + *value = CCtxParams->enableMatchFinderFallback; + break; + case ZSTD_c_maxBlockSize: + *value = (int)CCtxParams->maxBlockSize; + break; + case ZSTD_c_repcodeResolution: + *value = (int)CCtxParams->searchForExternalRepcodes; + break; + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } + return 0; +} + +/** ZSTD_CCtx_setParametersUsingCCtxParams() : + * just applies `params` into `cctx` + * no action is performed, parameters are merely stored. + * If ZSTDMT is enabled, parameters are pushed to cctx->mtctx. + * This is possible even if a compression is ongoing. + * In which case, new parameters will be applied on the fly, starting with next compression job. + */ +size_t ZSTD_CCtx_setParametersUsingCCtxParams( + ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams"); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "The context is in the wrong stage!"); + RETURN_ERROR_IF(cctx->cdict, stage_wrong, + "Can't override parameters with cdict attached (some must " + "be inherited from the cdict)."); + + cctx->requestedParams = *params; + return 0; +} + +size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams) +{ + ZSTD_STATIC_ASSERT(sizeof(cparams) == 7 * 4 /* all params are listed below */); + DEBUGLOG(4, "ZSTD_CCtx_setCParams"); + /* only update if all parameters are valid */ + FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, (int)cparams.windowLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, (int)cparams.chainLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, (int)cparams.hashLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, (int)cparams.searchLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, (int)cparams.minMatch), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, (int)cparams.targetLength), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, (int)cparams.strategy), ""); + return 0; +} + +size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams) +{ + ZSTD_STATIC_ASSERT(sizeof(fparams) == 3 * 4 /* all params are listed below */); + DEBUGLOG(4, "ZSTD_CCtx_setFParams"); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, fparams.contentSizeFlag != 0), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, fparams.checksumFlag != 0), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, fparams.noDictIDFlag == 0), ""); + return 0; +} + +size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParams"); + /* First check cParams, because we want to update all or none. */ + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + /* Next set fParams, because this could fail if the cctx isn't in init stage. */ + FORWARD_IF_ERROR(ZSTD_CCtx_setFParams(cctx, params.fParams), ""); + /* Finally set cParams, which should succeed. */ + FORWARD_IF_ERROR(ZSTD_CCtx_setCParams(cctx, params.cParams), ""); + return 0; +} + +size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %llu bytes", pledgedSrcSize); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't set pledgedSrcSize when not in init stage."); + cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1; + return 0; +} + +static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams( + int const compressionLevel, + size_t const dictSize); +static int ZSTD_dedicatedDictSearch_isSupported( + const ZSTD_compressionParameters* cParams); +static void ZSTD_dedicatedDictSearch_revertCParams( + ZSTD_compressionParameters* cParams); + +/** + * Initializes the local dictionary using requested parameters. + * NOTE: Initialization does not employ the pledged src size, + * because the dictionary may be used for multiple compressions. + */ +static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx) +{ + ZSTD_localDict* const dl = &cctx->localDict; + if (dl->dict == NULL) { + /* No local dictionary. */ + assert(dl->dictBuffer == NULL); + assert(dl->cdict == NULL); + assert(dl->dictSize == 0); + return 0; + } + if (dl->cdict != NULL) { + /* Local dictionary already initialized. */ + assert(cctx->cdict == dl->cdict); + return 0; + } + assert(dl->dictSize > 0); + assert(cctx->cdict == NULL); + assert(cctx->prefixDict.dict == NULL); + + dl->cdict = ZSTD_createCDict_advanced2( + dl->dict, + dl->dictSize, + ZSTD_dlm_byRef, + dl->dictContentType, + &cctx->requestedParams, + cctx->customMem); + RETURN_ERROR_IF(!dl->cdict, memory_allocation, "ZSTD_createCDict_advanced failed"); + cctx->cdict = dl->cdict; + return 0; +} + +size_t ZSTD_CCtx_loadDictionary_advanced( + ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't load a dictionary when cctx is not in init stage."); + ZSTD_clearAllDicts(cctx); /* erase any previously set dictionary */ + if (dict == NULL || dictSize == 0) /* no dictionary */ + return 0; + if (dictLoadMethod == ZSTD_dlm_byRef) { + cctx->localDict.dict = dict; + } else { + /* copy dictionary content inside CCtx to own its lifetime */ + void* dictBuffer; + RETURN_ERROR_IF(cctx->staticSize, memory_allocation, + "static CCtx can't allocate for an internal copy of dictionary"); + dictBuffer = ZSTD_customMalloc(dictSize, cctx->customMem); + RETURN_ERROR_IF(dictBuffer==NULL, memory_allocation, + "allocation failed for dictionary content"); + ZSTD_memcpy(dictBuffer, dict, dictSize); + cctx->localDict.dictBuffer = dictBuffer; /* owned ptr to free */ + cctx->localDict.dict = dictBuffer; /* read-only reference */ + } + cctx->localDict.dictSize = dictSize; + cctx->localDict.dictContentType = dictContentType; + return 0; +} + +size_t ZSTD_CCtx_loadDictionary_byReference( + ZSTD_CCtx* cctx, const void* dict, size_t dictSize) +{ + return ZSTD_CCtx_loadDictionary_advanced( + cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto); +} + +size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize) +{ + return ZSTD_CCtx_loadDictionary_advanced( + cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); +} + + +size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a dict when ctx not in init stage."); + /* Free the existing local cdict (if any) to save memory. */ + ZSTD_clearAllDicts(cctx); + cctx->cdict = cdict; + return 0; +} + +size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a pool when ctx not in init stage."); + cctx->pool = pool; + return 0; +} + +size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize) +{ + return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent); +} + +size_t ZSTD_CCtx_refPrefix_advanced( + ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a prefix when ctx not in init stage."); + ZSTD_clearAllDicts(cctx); + if (prefix != NULL && prefixSize > 0) { + cctx->prefixDict.dict = prefix; + cctx->prefixDict.dictSize = prefixSize; + cctx->prefixDict.dictContentType = dictContentType; + } + return 0; +} + +/*! ZSTD_CCtx_reset() : + * Also dumps dictionary */ +size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset) +{ + if ( (reset == ZSTD_reset_session_only) + || (reset == ZSTD_reset_session_and_parameters) ) { + cctx->streamStage = zcss_init; + cctx->pledgedSrcSizePlusOne = 0; + } + if ( (reset == ZSTD_reset_parameters) + || (reset == ZSTD_reset_session_and_parameters) ) { + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Reset parameters is only possible during init stage."); + ZSTD_clearAllDicts(cctx); + return ZSTD_CCtxParams_reset(&cctx->requestedParams); + } + return 0; +} + + +/** ZSTD_checkCParams() : + control CParam values remain within authorized range. + @return : 0, or an error code if one value is beyond authorized range */ +size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) +{ + BOUNDCHECK(ZSTD_c_windowLog, (int)cParams.windowLog); + BOUNDCHECK(ZSTD_c_chainLog, (int)cParams.chainLog); + BOUNDCHECK(ZSTD_c_hashLog, (int)cParams.hashLog); + BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog); + BOUNDCHECK(ZSTD_c_minMatch, (int)cParams.minMatch); + BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength); + BOUNDCHECK(ZSTD_c_strategy, (int)cParams.strategy); + return 0; +} + +/** ZSTD_clampCParams() : + * make CParam values within valid range. + * @return : valid CParams */ +static ZSTD_compressionParameters +ZSTD_clampCParams(ZSTD_compressionParameters cParams) +{ +# define CLAMP_TYPE(cParam, val, type) \ + do { \ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); \ + if ((int)valbounds.upperBound) val=(type)bounds.upperBound; \ + } while (0) +# define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, unsigned) + CLAMP(ZSTD_c_windowLog, cParams.windowLog); + CLAMP(ZSTD_c_chainLog, cParams.chainLog); + CLAMP(ZSTD_c_hashLog, cParams.hashLog); + CLAMP(ZSTD_c_searchLog, cParams.searchLog); + CLAMP(ZSTD_c_minMatch, cParams.minMatch); + CLAMP(ZSTD_c_targetLength,cParams.targetLength); + CLAMP_TYPE(ZSTD_c_strategy,cParams.strategy, ZSTD_strategy); + return cParams; +} + +/** ZSTD_cycleLog() : + * condition for correct operation : hashLog > 1 */ +U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) +{ + U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2); + return hashLog - btScale; +} + +/** ZSTD_dictAndWindowLog() : + * Returns an adjusted window log that is large enough to fit the source and the dictionary. + * The zstd format says that the entire dictionary is valid if one byte of the dictionary + * is within the window. So the hashLog and chainLog should be large enough to reference both + * the dictionary and the window. So we must use this adjusted dictAndWindowLog when downsizing + * the hashLog and windowLog. + * NOTE: srcSize must not be ZSTD_CONTENTSIZE_UNKNOWN. + */ +static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize) +{ + const U64 maxWindowSize = 1ULL << ZSTD_WINDOWLOG_MAX; + /* No dictionary ==> No change */ + if (dictSize == 0) { + return windowLog; + } + assert(windowLog <= ZSTD_WINDOWLOG_MAX); + assert(srcSize != ZSTD_CONTENTSIZE_UNKNOWN); /* Handled in ZSTD_adjustCParams_internal() */ + { + U64 const windowSize = 1ULL << windowLog; + U64 const dictAndWindowSize = dictSize + windowSize; + /* If the window size is already large enough to fit both the source and the dictionary + * then just use the window size. Otherwise adjust so that it fits the dictionary and + * the window. + */ + if (windowSize >= dictSize + srcSize) { + return windowLog; /* Window size large enough already */ + } else if (dictAndWindowSize >= maxWindowSize) { + return ZSTD_WINDOWLOG_MAX; /* Larger than max window log */ + } else { + return ZSTD_highbit32((U32)dictAndWindowSize - 1) + 1; + } + } +} + +/** ZSTD_adjustCParams_internal() : + * optimize `cPar` for a specified input (`srcSize` and `dictSize`). + * mostly downsize to reduce memory consumption and initialization latency. + * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known. + * `mode` is the mode for parameter adjustment. See docs for `ZSTD_CParamMode_e`. + * note : `srcSize==0` means 0! + * condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */ +static ZSTD_compressionParameters +ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, + unsigned long long srcSize, + size_t dictSize, + ZSTD_CParamMode_e mode, + ZSTD_ParamSwitch_e useRowMatchFinder) +{ + const U64 minSrcSize = 513; /* (1<<9) + 1 */ + const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1); + assert(ZSTD_checkCParams(cPar)==0); + + /* Cascade the selected strategy down to the next-highest one built into + * this binary. */ +#ifdef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btultra2) { + cPar.strategy = ZSTD_btultra; + } + if (cPar.strategy == ZSTD_btultra) { + cPar.strategy = ZSTD_btopt; + } +#endif +#ifdef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btopt) { + cPar.strategy = ZSTD_btlazy2; + } +#endif +#ifdef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btlazy2) { + cPar.strategy = ZSTD_lazy2; + } +#endif +#ifdef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_lazy2) { + cPar.strategy = ZSTD_lazy; + } +#endif +#ifdef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_lazy) { + cPar.strategy = ZSTD_greedy; + } +#endif +#ifdef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_greedy) { + cPar.strategy = ZSTD_dfast; + } +#endif +#ifdef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_dfast) { + cPar.strategy = ZSTD_fast; + cPar.targetLength = 0; + } +#endif + + switch (mode) { + case ZSTD_cpm_unknown: + case ZSTD_cpm_noAttachDict: + /* If we don't know the source size, don't make any + * assumptions about it. We will already have selected + * smaller parameters if a dictionary is in use. + */ + break; + case ZSTD_cpm_createCDict: + /* Assume a small source size when creating a dictionary + * with an unknown source size. + */ + if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN) + srcSize = minSrcSize; + break; + case ZSTD_cpm_attachDict: + /* Dictionary has its own dedicated parameters which have + * already been selected. We are selecting parameters + * for only the source. + */ + dictSize = 0; + break; + default: + assert(0); + break; + } + + /* resize windowLog if input is small enough, to use less memory */ + if ( (srcSize <= maxWindowResize) + && (dictSize <= maxWindowResize) ) { + U32 const tSize = (U32)(srcSize + dictSize); + static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN; + U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN : + ZSTD_highbit32(tSize-1) + 1; + if (cPar.windowLog > srcLog) cPar.windowLog = srcLog; + } + if (srcSize != ZSTD_CONTENTSIZE_UNKNOWN) { + U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize); + U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); + if (cPar.hashLog > dictAndWindowLog+1) cPar.hashLog = dictAndWindowLog+1; + if (cycleLog > dictAndWindowLog) + cPar.chainLog -= (cycleLog - dictAndWindowLog); + } + + if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) + cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* minimum wlog required for valid frame header */ + + /* We can't use more than 32 bits of hash in total, so that means that we require: + * (hashLog + 8) <= 32 && (chainLog + 8) <= 32 + */ + if (mode == ZSTD_cpm_createCDict && ZSTD_CDictIndicesAreTagged(&cPar)) { + U32 const maxShortCacheHashLog = 32 - ZSTD_SHORT_CACHE_TAG_BITS; + if (cPar.hashLog > maxShortCacheHashLog) { + cPar.hashLog = maxShortCacheHashLog; + } + if (cPar.chainLog > maxShortCacheHashLog) { + cPar.chainLog = maxShortCacheHashLog; + } + } + + + /* At this point, we aren't 100% sure if we are using the row match finder. + * Unless it is explicitly disabled, conservatively assume that it is enabled. + * In this case it will only be disabled for small sources, so shrinking the + * hash log a little bit shouldn't result in any ratio loss. + */ + if (useRowMatchFinder == ZSTD_ps_auto) + useRowMatchFinder = ZSTD_ps_enable; + + /* We can't hash more than 32-bits in total. So that means that we require: + * (hashLog - rowLog + 8) <= 32 + */ + if (ZSTD_rowMatchFinderUsed(cPar.strategy, useRowMatchFinder)) { + /* Switch to 32-entry rows if searchLog is 5 (or more) */ + U32 const rowLog = BOUNDED(4, cPar.searchLog, 6); + U32 const maxRowHashLog = 32 - ZSTD_ROW_HASH_TAG_BITS; + U32 const maxHashLog = maxRowHashLog + rowLog; + assert(cPar.hashLog >= rowLog); + if (cPar.hashLog > maxHashLog) { + cPar.hashLog = maxHashLog; + } + } + + return cPar; +} + +ZSTD_compressionParameters +ZSTD_adjustCParams(ZSTD_compressionParameters cPar, + unsigned long long srcSize, + size_t dictSize) +{ + cPar = ZSTD_clampCParams(cPar); /* resulting cPar is necessarily valid (all parameters within range) */ + if (srcSize == 0) srcSize = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown, ZSTD_ps_auto); +} + +static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); +static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); + +static void ZSTD_overrideCParams( + ZSTD_compressionParameters* cParams, + const ZSTD_compressionParameters* overrides) +{ + if (overrides->windowLog) cParams->windowLog = overrides->windowLog; + if (overrides->hashLog) cParams->hashLog = overrides->hashLog; + if (overrides->chainLog) cParams->chainLog = overrides->chainLog; + if (overrides->searchLog) cParams->searchLog = overrides->searchLog; + if (overrides->minMatch) cParams->minMatch = overrides->minMatch; + if (overrides->targetLength) cParams->targetLength = overrides->targetLength; + if (overrides->strategy) cParams->strategy = overrides->strategy; +} + +ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( + const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + ZSTD_compressionParameters cParams; + if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) { + assert(CCtxParams->srcSizeHint>=0); + srcSizeHint = (U64)CCtxParams->srcSizeHint; + } + cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode); + if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; + ZSTD_overrideCParams(&cParams, &CCtxParams->cParams); + assert(!ZSTD_checkCParams(cParams)); + /* srcSizeHint == 0 means 0 */ + return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize, mode, CCtxParams->useRowMatchFinder); +} + +static size_t +ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const int enableDedicatedDictSearch, + const U32 forCCtx) +{ + /* chain table size should be 0 for fast or row-hash strategies */ + size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder, enableDedicatedDictSearch && !forCCtx) + ? ((size_t)1 << cParams->chainLog) + : 0; + size_t const hSize = ((size_t)1) << cParams->hashLog; + U32 const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; + size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; + /* We don't use ZSTD_cwksp_alloc_size() here because the tables aren't + * surrounded by redzones in ASAN. */ + size_t const tableSpace = chainSize * sizeof(U32) + + hSize * sizeof(U32) + + h3Size * sizeof(U32); + size_t const optPotentialSpace = + ZSTD_cwksp_aligned64_alloc_size((MaxML+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((MaxLL+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((MaxOff+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((1<strategy, useRowMatchFinder) + ? ZSTD_cwksp_aligned64_alloc_size(hSize) + : 0; + size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt)) + ? optPotentialSpace + : 0; + size_t const slackSpace = ZSTD_cwksp_slack_space_required(); + + /* tables are guaranteed to be sized in multiples of 64 bytes (or 16 uint32_t) */ + ZSTD_STATIC_ASSERT(ZSTD_HASHLOG_MIN >= 4 && ZSTD_WINDOWLOG_MIN >= 4 && ZSTD_CHAINLOG_MIN >= 4); + assert(useRowMatchFinder != ZSTD_ps_auto); + + DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u", + (U32)chainSize, (U32)hSize, (U32)h3Size); + return tableSpace + optSpace + slackSpace + lazyAdditionalSpace; +} + +/* Helper function for calculating memory requirements. + * Gives a tighter bound than ZSTD_sequenceBound() by taking minMatch into account. */ +static size_t ZSTD_maxNbSeq(size_t blockSize, unsigned minMatch, int useSequenceProducer) { + U32 const divider = (minMatch==3 || useSequenceProducer) ? 3 : 4; + return blockSize / divider; +} + +static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( + const ZSTD_compressionParameters* cParams, + const ldmParams_t* ldmParams, + const int isStatic, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const size_t buffInSize, + const size_t buffOutSize, + const U64 pledgedSrcSize, + int useSequenceProducer, + size_t maxBlockSize) +{ + size_t const windowSize = (size_t) BOUNDED(1ULL, 1ULL << cParams->windowLog, pledgedSrcSize); + size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(maxBlockSize), windowSize); + size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useSequenceProducer); + size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize) + + ZSTD_cwksp_aligned64_alloc_size(maxNbSeq * sizeof(SeqDef)) + + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE)); + size_t const tmpWorkSpace = ZSTD_cwksp_alloc_size(TMP_WORKSPACE_SIZE); + size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t)); + size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1); + + size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams); + size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize); + size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ? + ZSTD_cwksp_aligned64_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0; + + + size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + + ZSTD_cwksp_alloc_size(buffOutSize); + + size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0; + + size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize); + size_t const externalSeqSpace = useSequenceProducer + ? ZSTD_cwksp_aligned64_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence)) + : 0; + + size_t const neededSpace = + cctxSpace + + tmpWorkSpace + + blockStateSpace + + ldmSpace + + ldmSeqSpace + + matchStateSize + + tokenSpace + + bufferSpace + + externalSeqSpace; + + DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace); + return neededSpace; +} + +size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) +{ + ZSTD_compressionParameters const cParams = + ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); + ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, + &cParams); + + RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); + /* estimateCCtxSize is for one-shot compression. So no buffers should + * be needed. However, we still allocate two 0-sized buffers, which can + * take space under ASAN. */ + return ZSTD_estimateCCtxSize_usingCCtxParams_internal( + &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize); +} + +size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) +{ + ZSTD_CCtx_params initialParams = ZSTD_makeCCtxParamsFromCParams(cParams); + if (ZSTD_rowMatchFinderSupported(cParams.strategy)) { + /* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */ + size_t noRowCCtxSize; + size_t rowCCtxSize; + initialParams.useRowMatchFinder = ZSTD_ps_disable; + noRowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + initialParams.useRowMatchFinder = ZSTD_ps_enable; + rowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + return MAX(noRowCCtxSize, rowCCtxSize); + } else { + return ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + } +} + +static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel) +{ + int tier = 0; + size_t largestSize = 0; + static const unsigned long long srcSizeTiers[4] = {16 KB, 128 KB, 256 KB, ZSTD_CONTENTSIZE_UNKNOWN}; + for (; tier < 4; ++tier) { + /* Choose the set of cParams for a given level across all srcSizes that give the largest cctxSize */ + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeTiers[tier], 0, ZSTD_cpm_noAttachDict); + largestSize = MAX(ZSTD_estimateCCtxSize_usingCParams(cParams), largestSize); + } + return largestSize; +} + +size_t ZSTD_estimateCCtxSize(int compressionLevel) +{ + int level; + size_t memBudget = 0; + for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) { + /* Ensure monotonically increasing memory usage as compression level increases */ + size_t const newMB = ZSTD_estimateCCtxSize_internal(level); + if (newMB > memBudget) memBudget = newMB; + } + return memBudget; +} + +size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params) +{ + RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); + { ZSTD_compressionParameters const cParams = + ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); + size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(params->maxBlockSize), (size_t)1 << cParams.windowLog); + size_t const inBuffSize = (params->inBufferMode == ZSTD_bm_buffered) + ? ((size_t)1 << cParams.windowLog) + blockSize + : 0; + size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered) + ? ZSTD_compressBound(blockSize) + 1 + : 0; + ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, ¶ms->cParams); + + return ZSTD_estimateCCtxSize_usingCCtxParams_internal( + &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize, + ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize); + } +} + +size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams) +{ + ZSTD_CCtx_params initialParams = ZSTD_makeCCtxParamsFromCParams(cParams); + if (ZSTD_rowMatchFinderSupported(cParams.strategy)) { + /* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */ + size_t noRowCCtxSize; + size_t rowCCtxSize; + initialParams.useRowMatchFinder = ZSTD_ps_disable; + noRowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams); + initialParams.useRowMatchFinder = ZSTD_ps_enable; + rowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams); + return MAX(noRowCCtxSize, rowCCtxSize); + } else { + return ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams); + } +} + +static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel) +{ + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); + return ZSTD_estimateCStreamSize_usingCParams(cParams); +} + +size_t ZSTD_estimateCStreamSize(int compressionLevel) +{ + int level; + size_t memBudget = 0; + for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) { + size_t const newMB = ZSTD_estimateCStreamSize_internal(level); + if (newMB > memBudget) memBudget = newMB; + } + return memBudget; +} + +/* ZSTD_getFrameProgression(): + * tells how much data has been consumed (input) and produced (output) for current frame. + * able to count progression inside worker threads (non-blocking mode). + */ +ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx) +{ +#ifdef ZSTD_MULTITHREAD + if (cctx->appliedParams.nbWorkers > 0) { + return ZSTDMT_getFrameProgression(cctx->mtctx); + } +#endif + { ZSTD_frameProgression fp; + size_t const buffered = (cctx->inBuff == NULL) ? 0 : + cctx->inBuffPos - cctx->inToCompress; + if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress); + assert(buffered <= ZSTD_BLOCKSIZE_MAX); + fp.ingested = cctx->consumedSrcSize + buffered; + fp.consumed = cctx->consumedSrcSize; + fp.produced = cctx->producedCSize; + fp.flushed = cctx->producedCSize; /* simplified; some data might still be left within streaming output buffer */ + fp.currentJobID = 0; + fp.nbActiveWorkers = 0; + return fp; +} } + +/*! ZSTD_toFlushNow() + * Only useful for multithreading scenarios currently (nbWorkers >= 1). + */ +size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx) +{ +#ifdef ZSTD_MULTITHREAD + if (cctx->appliedParams.nbWorkers > 0) { + return ZSTDMT_toFlushNow(cctx->mtctx); + } +#endif + (void)cctx; + return 0; /* over-simplification; could also check if context is currently running in streaming mode, and in which case, report how many bytes are left to be flushed within output buffer */ +} + +static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1, + ZSTD_compressionParameters cParams2) +{ + (void)cParams1; + (void)cParams2; + assert(cParams1.windowLog == cParams2.windowLog); + assert(cParams1.chainLog == cParams2.chainLog); + assert(cParams1.hashLog == cParams2.hashLog); + assert(cParams1.searchLog == cParams2.searchLog); + assert(cParams1.minMatch == cParams2.minMatch); + assert(cParams1.targetLength == cParams2.targetLength); + assert(cParams1.strategy == cParams2.strategy); +} + +void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs) +{ + int i; + for (i = 0; i < ZSTD_REP_NUM; ++i) + bs->rep[i] = repStartValue[i]; + bs->entropy.huf.repeatMode = HUF_repeat_none; + bs->entropy.fse.offcode_repeatMode = FSE_repeat_none; + bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none; + bs->entropy.fse.litlength_repeatMode = FSE_repeat_none; +} + +/*! ZSTD_invalidateMatchState() + * Invalidate all the matches in the match finder tables. + * Requires nextSrc and base to be set (can be NULL). + */ +static void ZSTD_invalidateMatchState(ZSTD_MatchState_t* ms) +{ + ZSTD_window_clear(&ms->window); + + ms->nextToUpdate = ms->window.dictLimit; + ms->loadedDictEnd = 0; + ms->opt.litLengthSum = 0; /* force reset of btopt stats */ + ms->dictMatchState = NULL; +} + +/** + * Controls, for this matchState reset, whether the tables need to be cleared / + * prepared for the coming compression (ZSTDcrp_makeClean), or whether the + * tables can be left unclean (ZSTDcrp_leaveDirty), because we know that a + * subsequent operation will overwrite the table space anyways (e.g., copying + * the matchState contents in from a CDict). + */ +typedef enum { + ZSTDcrp_makeClean, + ZSTDcrp_leaveDirty +} ZSTD_compResetPolicy_e; + +/** + * Controls, for this matchState reset, whether indexing can continue where it + * left off (ZSTDirp_continue), or whether it needs to be restarted from zero + * (ZSTDirp_reset). + */ +typedef enum { + ZSTDirp_continue, + ZSTDirp_reset +} ZSTD_indexResetPolicy_e; + +typedef enum { + ZSTD_resetTarget_CDict, + ZSTD_resetTarget_CCtx +} ZSTD_resetTarget_e; + +/* Mixes bits in a 64 bits in a value, based on XXH3_rrmxmx */ +static U64 ZSTD_bitmix(U64 val, U64 len) { + val ^= ZSTD_rotateRight_U64(val, 49) ^ ZSTD_rotateRight_U64(val, 24); + val *= 0x9FB21C651E98DF25ULL; + val ^= (val >> 35) + len ; + val *= 0x9FB21C651E98DF25ULL; + return val ^ (val >> 28); +} + +/* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */ +static void ZSTD_advanceHashSalt(ZSTD_MatchState_t* ms) { + ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4); +} + +static size_t +ZSTD_reset_matchState(ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + const ZSTD_compressionParameters* cParams, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const ZSTD_compResetPolicy_e crp, + const ZSTD_indexResetPolicy_e forceResetIndex, + const ZSTD_resetTarget_e forWho) +{ + /* disable chain table allocation for fast or row-based strategies */ + size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder, + ms->dedicatedDictSearch && (forWho == ZSTD_resetTarget_CDict)) + ? ((size_t)1 << cParams->chainLog) + : 0; + size_t const hSize = ((size_t)1) << cParams->hashLog; + U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; + size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; + + DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset); + assert(useRowMatchFinder != ZSTD_ps_auto); + if (forceResetIndex == ZSTDirp_reset) { + ZSTD_window_init(&ms->window); + ZSTD_cwksp_mark_tables_dirty(ws); + } + + ms->hashLog3 = hashLog3; + ms->lazySkipping = 0; + + ZSTD_invalidateMatchState(ms); + + assert(!ZSTD_cwksp_reserve_failed(ws)); /* check that allocation hasn't already failed */ + + ZSTD_cwksp_clear_tables(ws); + + DEBUGLOG(5, "reserving table space"); + /* table Space */ + ms->hashTable = (U32*)ZSTD_cwksp_reserve_table(ws, hSize * sizeof(U32)); + ms->chainTable = (U32*)ZSTD_cwksp_reserve_table(ws, chainSize * sizeof(U32)); + ms->hashTable3 = (U32*)ZSTD_cwksp_reserve_table(ws, h3Size * sizeof(U32)); + RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation, + "failed a workspace allocation in ZSTD_reset_matchState"); + + DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_leaveDirty); + if (crp!=ZSTDcrp_leaveDirty) { + /* reset tables only */ + ZSTD_cwksp_clean_tables(ws); + } + + if (ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)) { + /* Row match finder needs an additional table of hashes ("tags") */ + size_t const tagTableSize = hSize; + /* We want to generate a new salt in case we reset a Cctx, but we always want to use + * 0 when we reset a Cdict */ + if(forWho == ZSTD_resetTarget_CCtx) { + ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned_init_once(ws, tagTableSize); + ZSTD_advanceHashSalt(ms); + } else { + /* When we are not salting we want to always memset the memory */ + ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned64(ws, tagTableSize); + ZSTD_memset(ms->tagTable, 0, tagTableSize); + ms->hashSalt = 0; + } + { /* Switch to 32-entry rows if searchLog is 5 (or more) */ + U32 const rowLog = BOUNDED(4, cParams->searchLog, 6); + assert(cParams->hashLog >= rowLog); + ms->rowHashLog = cParams->hashLog - rowLog; + } + } + + /* opt parser space */ + if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) { + DEBUGLOG(4, "reserving optimal parser space"); + ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (1<opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxLL+1) * sizeof(unsigned)); + ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxML+1) * sizeof(unsigned)); + ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxOff+1) * sizeof(unsigned)); + ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_match_t)); + ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t)); + } + + ms->cParams = *cParams; + + RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation, + "failed a workspace allocation in ZSTD_reset_matchState"); + return 0; +} + +/* ZSTD_indexTooCloseToMax() : + * minor optimization : prefer memset() rather than reduceIndex() + * which is measurably slow in some circumstances (reported for Visual Studio). + * Works when re-using a context for a lot of smallish inputs : + * if all inputs are smaller than ZSTD_INDEXOVERFLOW_MARGIN, + * memset() will be triggered before reduceIndex(). + */ +#define ZSTD_INDEXOVERFLOW_MARGIN (16 MB) +static int ZSTD_indexTooCloseToMax(ZSTD_window_t w) +{ + return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN); +} + +/** ZSTD_dictTooBig(): + * When dictionaries are larger than ZSTD_CHUNKSIZE_MAX they can't be loaded in + * one go generically. So we ensure that in that case we reset the tables to zero, + * so that we can load as much of the dictionary as possible. + */ +static int ZSTD_dictTooBig(size_t const loadedDictSize) +{ + return loadedDictSize > ZSTD_CHUNKSIZE_MAX; +} + +/*! ZSTD_resetCCtx_internal() : + * @param loadedDictSize The size of the dictionary to be loaded + * into the context, if any. If no dictionary is used, or the + * dictionary is being attached / copied, then pass 0. + * note : `params` are assumed fully validated at this stage. + */ +static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, + ZSTD_CCtx_params const* params, + U64 const pledgedSrcSize, + size_t const loadedDictSize, + ZSTD_compResetPolicy_e const crp, + ZSTD_buffered_policy_e const zbuff) +{ + ZSTD_cwksp* const ws = &zc->workspace; + DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d", + (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->postBlockSplitter); + assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); + + zc->isFirstBlock = 1; + + /* Set applied params early so we can modify them for LDM, + * and point params at the applied params. + */ + zc->appliedParams = *params; + params = &zc->appliedParams; + + assert(params->useRowMatchFinder != ZSTD_ps_auto); + assert(params->postBlockSplitter != ZSTD_ps_auto); + assert(params->ldmParams.enableLdm != ZSTD_ps_auto); + assert(params->maxBlockSize != 0); + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* Adjust long distance matching parameters */ + ZSTD_ldm_adjustParameters(&zc->appliedParams.ldmParams, ¶ms->cParams); + assert(params->ldmParams.hashLog >= params->ldmParams.bucketSizeLog); + assert(params->ldmParams.hashRateLog < 32); + } + + { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params->cParams.windowLog), pledgedSrcSize)); + size_t const blockSize = MIN(params->maxBlockSize, windowSize); + size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, params->cParams.minMatch, ZSTD_hasExtSeqProd(params)); + size_t const buffOutSize = (zbuff == ZSTDb_buffered && params->outBufferMode == ZSTD_bm_buffered) + ? ZSTD_compressBound(blockSize) + 1 + : 0; + size_t const buffInSize = (zbuff == ZSTDb_buffered && params->inBufferMode == ZSTD_bm_buffered) + ? windowSize + blockSize + : 0; + size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize); + + int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window); + int const dictTooBig = ZSTD_dictTooBig(loadedDictSize); + ZSTD_indexResetPolicy_e needsIndexReset = + (indexTooClose || dictTooBig || !zc->initialized) ? ZSTDirp_reset : ZSTDirp_continue; + + size_t const neededSpace = + ZSTD_estimateCCtxSize_usingCCtxParams_internal( + ¶ms->cParams, ¶ms->ldmParams, zc->staticSize != 0, params->useRowMatchFinder, + buffInSize, buffOutSize, pledgedSrcSize, ZSTD_hasExtSeqProd(params), params->maxBlockSize); + + FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!"); + + if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0); + + { /* Check if workspace is large enough, alloc a new one if needed */ + int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace; + int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace); + int resizeWorkspace = workspaceTooSmall || workspaceWasteful; + DEBUGLOG(4, "Need %zu B workspace", neededSpace); + DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize); + + if (resizeWorkspace) { + DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB", + ZSTD_cwksp_sizeof(ws) >> 10, + neededSpace >> 10); + + RETURN_ERROR_IF(zc->staticSize, memory_allocation, "static cctx : no resize"); + + needsIndexReset = ZSTDirp_reset; + + ZSTD_cwksp_free(ws, zc->customMem); + FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem), ""); + + DEBUGLOG(5, "reserving object space"); + /* Statically sized space. + * tmpWorkspace never moves, + * though prev/next block swap places */ + assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t))); + zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t)); + RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock"); + zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t)); + RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock"); + zc->tmpWorkspace = ZSTD_cwksp_reserve_object(ws, TMP_WORKSPACE_SIZE); + RETURN_ERROR_IF(zc->tmpWorkspace == NULL, memory_allocation, "couldn't allocate tmpWorkspace"); + zc->tmpWkspSize = TMP_WORKSPACE_SIZE; + } } + + ZSTD_cwksp_clear(ws); + + /* init params */ + zc->blockState.matchState.cParams = params->cParams; + zc->blockState.matchState.prefetchCDictTables = params->prefetchCDictTables == ZSTD_ps_enable; + zc->pledgedSrcSizePlusOne = pledgedSrcSize+1; + zc->consumedSrcSize = 0; + zc->producedCSize = 0; + if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) + zc->appliedParams.fParams.contentSizeFlag = 0; + DEBUGLOG(4, "pledged content size : %u ; flag : %u", + (unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag); + zc->blockSizeMax = blockSize; + + XXH64_reset(&zc->xxhState, 0); + zc->stage = ZSTDcs_init; + zc->dictID = 0; + zc->dictContentSize = 0; + + ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock); + + FORWARD_IF_ERROR(ZSTD_reset_matchState( + &zc->blockState.matchState, + ws, + ¶ms->cParams, + params->useRowMatchFinder, + crp, + needsIndexReset, + ZSTD_resetTarget_CCtx), ""); + + zc->seqStore.sequencesStart = (SeqDef*)ZSTD_cwksp_reserve_aligned64(ws, maxNbSeq * sizeof(SeqDef)); + + /* ldm hash table */ + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* TODO: avoid memset? */ + size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog; + zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned64(ws, ldmHSize * sizeof(ldmEntry_t)); + ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t)); + zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned64(ws, maxNbLdmSeq * sizeof(rawSeq)); + zc->maxNbLdmSequences = maxNbLdmSeq; + + ZSTD_window_init(&zc->ldmState.window); + zc->ldmState.loadedDictEnd = 0; + } + + /* reserve space for block-level external sequences */ + if (ZSTD_hasExtSeqProd(params)) { + size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize); + zc->extSeqBufCapacity = maxNbExternalSeq; + zc->extSeqBuf = + (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned64(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence)); + } + + /* buffers */ + + /* ZSTD_wildcopy() is used to copy into the literals buffer, + * so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes. + */ + zc->seqStore.litStart = ZSTD_cwksp_reserve_buffer(ws, blockSize + WILDCOPY_OVERLENGTH); + zc->seqStore.maxNbLit = blockSize; + + zc->bufferedPolicy = zbuff; + zc->inBuffSize = buffInSize; + zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize); + zc->outBuffSize = buffOutSize; + zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize); + + /* ldm bucketOffsets table */ + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* TODO: avoid memset? */ + size_t const numBuckets = + ((size_t)1) << (params->ldmParams.hashLog - + params->ldmParams.bucketSizeLog); + zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, numBuckets); + ZSTD_memset(zc->ldmState.bucketOffsets, 0, numBuckets); + } + + /* sequences storage */ + ZSTD_referenceExternalSequences(zc, NULL, 0); + zc->seqStore.maxNbSeq = maxNbSeq; + zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + + DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws)); + assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace)); + + zc->initialized = 1; + + return 0; + } +} + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) { + int i; + for (i=0; iblockState.prevCBlock->rep[i] = 0; + assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window)); +} + +/* These are the approximate sizes for each strategy past which copying the + * dictionary tables into the working context is faster than using them + * in-place. + */ +static const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1] = { + 8 KB, /* unused */ + 8 KB, /* ZSTD_fast */ + 16 KB, /* ZSTD_dfast */ + 32 KB, /* ZSTD_greedy */ + 32 KB, /* ZSTD_lazy */ + 32 KB, /* ZSTD_lazy2 */ + 32 KB, /* ZSTD_btlazy2 */ + 32 KB, /* ZSTD_btopt */ + 8 KB, /* ZSTD_btultra */ + 8 KB /* ZSTD_btultra2 */ +}; + +static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize) +{ + size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy]; + int const dedicatedDictSearch = cdict->matchState.dedicatedDictSearch; + return dedicatedDictSearch + || ( ( pledgedSrcSize <= cutoff + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || params->attachDictPref == ZSTD_dictForceAttach ) + && params->attachDictPref != ZSTD_dictForceCopy + && !params->forceWindow ); /* dictMatchState isn't correctly + * handled in _enforceMaxDist */ +} + +static size_t +ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + ZSTD_CCtx_params params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + DEBUGLOG(4, "ZSTD_resetCCtx_byAttachingCDict() pledgedSrcSize=%llu", + (unsigned long long)pledgedSrcSize); + { + ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams; + unsigned const windowLog = params.cParams.windowLog; + assert(windowLog != 0); + /* Resize working context table params for input only, since the dict + * has its own tables. */ + /* pledgedSrcSize == 0 means 0! */ + + if (cdict->matchState.dedicatedDictSearch) { + ZSTD_dedicatedDictSearch_revertCParams(&adjusted_cdict_cParams); + } + + params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize, + cdict->dictContentSize, ZSTD_cpm_attachDict, + params.useRowMatchFinder); + params.cParams.windowLog = windowLog; + params.useRowMatchFinder = cdict->useRowMatchFinder; /* cdict overrides */ + FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_makeClean, zbuff), ""); + assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy); + } + + { const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc + - cdict->matchState.window.base); + const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit; + if (cdictLen == 0) { + /* don't even attach dictionaries with no contents */ + DEBUGLOG(4, "skipping attaching empty dictionary"); + } else { + DEBUGLOG(4, "attaching dictionary into context"); + cctx->blockState.matchState.dictMatchState = &cdict->matchState; + + /* prep working match state so dict matches never have negative indices + * when they are translated to the working context's index space. */ + if (cctx->blockState.matchState.window.dictLimit < cdictEnd) { + cctx->blockState.matchState.window.nextSrc = + cctx->blockState.matchState.window.base + cdictEnd; + ZSTD_window_clear(&cctx->blockState.matchState.window); + } + /* loadedDictEnd is expressed within the referential of the active context */ + cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit; + } } + + cctx->dictID = cdict->dictID; + cctx->dictContentSize = cdict->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); + + return 0; +} + +static void ZSTD_copyCDictTableIntoCCtx(U32* dst, U32 const* src, size_t tableSize, + ZSTD_compressionParameters const* cParams) { + if (ZSTD_CDictIndicesAreTagged(cParams)){ + /* Remove tags from the CDict table if they are present. + * See docs on "short cache" in zstd_compress_internal.h for context. */ + size_t i; + for (i = 0; i < tableSize; i++) { + U32 const taggedIndex = src[i]; + U32 const index = taggedIndex >> ZSTD_SHORT_CACHE_TAG_BITS; + dst[i] = index; + } + } else { + ZSTD_memcpy(dst, src, tableSize * sizeof(U32)); + } +} + +static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + ZSTD_CCtx_params params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams; + + assert(!cdict->matchState.dedicatedDictSearch); + DEBUGLOG(4, "ZSTD_resetCCtx_byCopyingCDict() pledgedSrcSize=%llu", + (unsigned long long)pledgedSrcSize); + + { unsigned const windowLog = params.cParams.windowLog; + assert(windowLog != 0); + /* Copy only compression parameters related to tables. */ + params.cParams = *cdict_cParams; + params.cParams.windowLog = windowLog; + params.useRowMatchFinder = cdict->useRowMatchFinder; + FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_leaveDirty, zbuff), ""); + assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy); + assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog); + assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog); + } + + ZSTD_cwksp_mark_tables_dirty(&cctx->workspace); + assert(params.useRowMatchFinder != ZSTD_ps_auto); + + /* copy tables */ + { size_t const chainSize = ZSTD_allocateChainTable(cdict_cParams->strategy, cdict->useRowMatchFinder, 0 /* DDS guaranteed disabled */) + ? ((size_t)1 << cdict_cParams->chainLog) + : 0; + size_t const hSize = (size_t)1 << cdict_cParams->hashLog; + + ZSTD_copyCDictTableIntoCCtx(cctx->blockState.matchState.hashTable, + cdict->matchState.hashTable, + hSize, cdict_cParams); + + /* Do not copy cdict's chainTable if cctx has parameters such that it would not use chainTable */ + if (ZSTD_allocateChainTable(cctx->appliedParams.cParams.strategy, cctx->appliedParams.useRowMatchFinder, 0 /* forDDSDict */)) { + ZSTD_copyCDictTableIntoCCtx(cctx->blockState.matchState.chainTable, + cdict->matchState.chainTable, + chainSize, cdict_cParams); + } + /* copy tag table */ + if (ZSTD_rowMatchFinderUsed(cdict_cParams->strategy, cdict->useRowMatchFinder)) { + size_t const tagTableSize = hSize; + ZSTD_memcpy(cctx->blockState.matchState.tagTable, + cdict->matchState.tagTable, + tagTableSize); + cctx->blockState.matchState.hashSalt = cdict->matchState.hashSalt; + } + } + + /* Zero the hashTable3, since the cdict never fills it */ + assert(cctx->blockState.matchState.hashLog3 <= 31); + { U32 const h3log = cctx->blockState.matchState.hashLog3; + size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; + assert(cdict->matchState.hashLog3 == 0); + ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32)); + } + + ZSTD_cwksp_mark_tables_clean(&cctx->workspace); + + /* copy dictionary offsets */ + { ZSTD_MatchState_t const* srcMatchState = &cdict->matchState; + ZSTD_MatchState_t* dstMatchState = &cctx->blockState.matchState; + dstMatchState->window = srcMatchState->window; + dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; + dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; + } + + cctx->dictID = cdict->dictID; + cctx->dictContentSize = cdict->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); + + return 0; +} + +/* We have a choice between copying the dictionary context into the working + * context, or referencing the dictionary context from the working context + * in-place. We decide here which strategy to use. */ +static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + + DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", + (unsigned)pledgedSrcSize); + + if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) { + return ZSTD_resetCCtx_byAttachingCDict( + cctx, cdict, *params, pledgedSrcSize, zbuff); + } else { + return ZSTD_resetCCtx_byCopyingCDict( + cctx, cdict, *params, pledgedSrcSize, zbuff); + } +} + +/*! ZSTD_copyCCtx_internal() : + * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. + * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). + * The "context", in this case, refers to the hash and chain tables, + * entropy tables, and dictionary references. + * `windowLog` value is enforced if != 0, otherwise value is copied from srcCCtx. + * @return : 0, or an error code */ +static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, + const ZSTD_CCtx* srcCCtx, + ZSTD_frameParameters fParams, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong, + "Can't copy a ctx that's not in init stage."); + DEBUGLOG(5, "ZSTD_copyCCtx_internal"); + ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); + { ZSTD_CCtx_params params = dstCCtx->requestedParams; + /* Copy only compression parameters related to tables. */ + params.cParams = srcCCtx->appliedParams.cParams; + assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto); + assert(srcCCtx->appliedParams.postBlockSplitter != ZSTD_ps_auto); + assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto); + params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder; + params.postBlockSplitter = srcCCtx->appliedParams.postBlockSplitter; + params.ldmParams = srcCCtx->appliedParams.ldmParams; + params.fParams = fParams; + params.maxBlockSize = srcCCtx->appliedParams.maxBlockSize; + ZSTD_resetCCtx_internal(dstCCtx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_leaveDirty, zbuff); + assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog); + assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy); + assert(dstCCtx->appliedParams.cParams.hashLog == srcCCtx->appliedParams.cParams.hashLog); + assert(dstCCtx->appliedParams.cParams.chainLog == srcCCtx->appliedParams.cParams.chainLog); + assert(dstCCtx->blockState.matchState.hashLog3 == srcCCtx->blockState.matchState.hashLog3); + } + + ZSTD_cwksp_mark_tables_dirty(&dstCCtx->workspace); + + /* copy tables */ + { size_t const chainSize = ZSTD_allocateChainTable(srcCCtx->appliedParams.cParams.strategy, + srcCCtx->appliedParams.useRowMatchFinder, + 0 /* forDDSDict */) + ? ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog) + : 0; + size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog; + U32 const h3log = srcCCtx->blockState.matchState.hashLog3; + size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; + + ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable, + srcCCtx->blockState.matchState.hashTable, + hSize * sizeof(U32)); + ZSTD_memcpy(dstCCtx->blockState.matchState.chainTable, + srcCCtx->blockState.matchState.chainTable, + chainSize * sizeof(U32)); + ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable3, + srcCCtx->blockState.matchState.hashTable3, + h3Size * sizeof(U32)); + } + + ZSTD_cwksp_mark_tables_clean(&dstCCtx->workspace); + + /* copy dictionary offsets */ + { + const ZSTD_MatchState_t* srcMatchState = &srcCCtx->blockState.matchState; + ZSTD_MatchState_t* dstMatchState = &dstCCtx->blockState.matchState; + dstMatchState->window = srcMatchState->window; + dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; + dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; + } + dstCCtx->dictID = srcCCtx->dictID; + dstCCtx->dictContentSize = srcCCtx->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock)); + + return 0; +} + +/*! ZSTD_copyCCtx() : + * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. + * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). + * pledgedSrcSize==0 means "unknown". +* @return : 0, or an error code */ +size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize) +{ + ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + ZSTD_buffered_policy_e const zbuff = srcCCtx->bufferedPolicy; + ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1); + if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; + fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN); + + return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx, + fParams, pledgedSrcSize, + zbuff); +} + + +#define ZSTD_ROWSIZE 16 +/*! ZSTD_reduceTable() : + * reduce table indexes by `reducerValue`, or squash to zero. + * PreserveMark preserves "unsorted mark" for btlazy2 strategy. + * It must be set to a clear 0/1 value, to remove branch during inlining. + * Presume table size is a multiple of ZSTD_ROWSIZE + * to help auto-vectorization */ +FORCE_INLINE_TEMPLATE void +ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerValue, int const preserveMark) +{ + int const nbRows = (int)size / ZSTD_ROWSIZE; + int cellNb = 0; + int rowNb; + /* Protect special index values < ZSTD_WINDOW_START_INDEX. */ + U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX; + assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */ + assert(size < (1U<<31)); /* can be cast to int */ + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the table reuse logic is sound, and that we don't + * access table space that we haven't cleaned, we re-"poison" the table + * space every time we mark it dirty. + * + * This function however is intended to operate on those dirty tables and + * re-clean them. So when this function is used correctly, we can unpoison + * the memory it operated on. This introduces a blind spot though, since + * if we now try to operate on __actually__ poisoned memory, we will not + * detect that. */ + __msan_unpoison(table, size * sizeof(U32)); +#endif + + for (rowNb=0 ; rowNb < nbRows ; rowNb++) { + int column; + for (column=0; columncParams.hashLog; + ZSTD_reduceTable(ms->hashTable, hSize, reducerValue); + } + + if (ZSTD_allocateChainTable(params->cParams.strategy, params->useRowMatchFinder, (U32)ms->dedicatedDictSearch)) { + U32 const chainSize = (U32)1 << params->cParams.chainLog; + if (params->cParams.strategy == ZSTD_btlazy2) + ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue); + else + ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue); + } + + if (ms->hashLog3) { + U32 const h3Size = (U32)1 << ms->hashLog3; + ZSTD_reduceTable(ms->hashTable3, h3Size, reducerValue); + } +} + + +/*-******************************************************* +* Block entropic compression +*********************************************************/ + +/* See doc/zstd_compression_format.md for detailed format description */ + +int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr) +{ + const SeqDef* const sequences = seqStorePtr->sequencesStart; + BYTE* const llCodeTable = seqStorePtr->llCode; + BYTE* const ofCodeTable = seqStorePtr->ofCode; + BYTE* const mlCodeTable = seqStorePtr->mlCode; + U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + U32 u; + int longOffsets = 0; + assert(nbSeq <= seqStorePtr->maxNbSeq); + for (u=0; u= STREAM_ACCUMULATOR_MIN)); + if (MEM_32bits() && ofCode >= STREAM_ACCUMULATOR_MIN) + longOffsets = 1; + } + if (seqStorePtr->longLengthType==ZSTD_llt_literalLength) + llCodeTable[seqStorePtr->longLengthPos] = MaxLL; + if (seqStorePtr->longLengthType==ZSTD_llt_matchLength) + mlCodeTable[seqStorePtr->longLengthPos] = MaxML; + return longOffsets; +} + +/* ZSTD_useTargetCBlockSize(): + * Returns if target compressed block size param is being used. + * If used, compression will do best effort to make a compressed block size to be around targetCBlockSize. + * Returns 1 if true, 0 otherwise. */ +static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams) +{ + DEBUGLOG(5, "ZSTD_useTargetCBlockSize (targetCBlockSize=%zu)", cctxParams->targetCBlockSize); + return (cctxParams->targetCBlockSize != 0); +} + +/* ZSTD_blockSplitterEnabled(): + * Returns if block splitting param is being used + * If used, compression will do best effort to split a block in order to improve compression ratio. + * At the time this function is called, the parameter must be finalized. + * Returns 1 if true, 0 otherwise. */ +static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams) +{ + DEBUGLOG(5, "ZSTD_blockSplitterEnabled (postBlockSplitter=%d)", cctxParams->postBlockSplitter); + assert(cctxParams->postBlockSplitter != ZSTD_ps_auto); + return (cctxParams->postBlockSplitter == ZSTD_ps_enable); +} + +/* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types + * and size of the sequences statistics + */ +typedef struct { + U32 LLtype; + U32 Offtype; + U32 MLtype; + size_t size; + size_t lastCountSize; /* Accounts for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */ + int longOffsets; +} ZSTD_symbolEncodingTypeStats_t; + +/* ZSTD_buildSequencesStatistics(): + * Returns a ZSTD_symbolEncodingTypeStats_t, or a zstd error code in the `size` field. + * Modifies `nextEntropy` to have the appropriate values as a side effect. + * nbSeq must be greater than 0. + * + * entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32) + */ +static ZSTD_symbolEncodingTypeStats_t +ZSTD_buildSequencesStatistics( + const SeqStore_t* seqStorePtr, size_t nbSeq, + const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy, + BYTE* dst, const BYTE* const dstEnd, + ZSTD_strategy strategy, unsigned* countWorkspace, + void* entropyWorkspace, size_t entropyWkspSize) +{ + BYTE* const ostart = dst; + const BYTE* const oend = dstEnd; + BYTE* op = ostart; + FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable; + FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable; + FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable; + const BYTE* const ofCodeTable = seqStorePtr->ofCode; + const BYTE* const llCodeTable = seqStorePtr->llCode; + const BYTE* const mlCodeTable = seqStorePtr->mlCode; + ZSTD_symbolEncodingTypeStats_t stats; + + stats.lastCountSize = 0; + /* convert length/distances into codes */ + stats.longOffsets = ZSTD_seqToCodes(seqStorePtr); + assert(op <= oend); + assert(nbSeq != 0); /* ZSTD_selectEncodingType() divides by nbSeq */ + /* build CTable for Literal Lengths */ + { unsigned max = MaxLL; + size_t const mostFrequent = HIST_countFast_wksp(countWorkspace, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + DEBUGLOG(5, "Building LL table"); + nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode; + stats.LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + LLFSELog, prevEntropy->litlengthCTable, + LL_defaultNorm, LL_defaultNormLog, + ZSTD_defaultAllowed, strategy); + assert(set_basic < set_compressed && set_rle < set_compressed); + assert(!(stats.LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_LitLength, LLFSELog, (SymbolEncodingType_e)stats.LLtype, + countWorkspace, max, llCodeTable, nbSeq, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + prevEntropy->litlengthCTable, + sizeof(prevEntropy->litlengthCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for LitLens failed"); + stats.size = countSize; + return stats; + } + if (stats.LLtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + /* build CTable for Offsets */ + { unsigned max = MaxOff; + size_t const mostFrequent = HIST_countFast_wksp( + countWorkspace, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */ + ZSTD_DefaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed; + DEBUGLOG(5, "Building OF table"); + nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode; + stats.Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + OffFSELog, prevEntropy->offcodeCTable, + OF_defaultNorm, OF_defaultNormLog, + defaultPolicy, strategy); + assert(!(stats.Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_OffsetBits, OffFSELog, (SymbolEncodingType_e)stats.Offtype, + countWorkspace, max, ofCodeTable, nbSeq, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + prevEntropy->offcodeCTable, + sizeof(prevEntropy->offcodeCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for Offsets failed"); + stats.size = countSize; + return stats; + } + if (stats.Offtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + /* build CTable for MatchLengths */ + { unsigned max = MaxML; + size_t const mostFrequent = HIST_countFast_wksp( + countWorkspace, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op)); + nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode; + stats.MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + MLFSELog, prevEntropy->matchlengthCTable, + ML_defaultNorm, ML_defaultNormLog, + ZSTD_defaultAllowed, strategy); + assert(!(stats.MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_MatchLength, MLFSELog, (SymbolEncodingType_e)stats.MLtype, + countWorkspace, max, mlCodeTable, nbSeq, + ML_defaultNorm, ML_defaultNormLog, MaxML, + prevEntropy->matchlengthCTable, + sizeof(prevEntropy->matchlengthCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for MatchLengths failed"); + stats.size = countSize; + return stats; + } + if (stats.MLtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + stats.size = (size_t)(op-ostart); + return stats; +} + +/* ZSTD_entropyCompressSeqStore_internal(): + * compresses both literals and sequences + * Returns compressed size of block, or a zstd error. + */ +#define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20 +MEM_STATIC size_t +ZSTD_entropyCompressSeqStore_internal( + void* dst, size_t dstCapacity, + const void* literals, size_t litSize, + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* entropyWorkspace, size_t entropyWkspSize, + const int bmi2) +{ + ZSTD_strategy const strategy = cctxParams->cParams.strategy; + unsigned* count = (unsigned*)entropyWorkspace; + FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable; + FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable; + FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable; + const SeqDef* const sequences = seqStorePtr->sequencesStart; + const size_t nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + const BYTE* const ofCodeTable = seqStorePtr->ofCode; + const BYTE* const llCodeTable = seqStorePtr->llCode; + const BYTE* const mlCodeTable = seqStorePtr->mlCode; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + size_t lastCountSize; + int longOffsets = 0; + + entropyWorkspace = count + (MaxSeq + 1); + entropyWkspSize -= (MaxSeq + 1) * sizeof(*count); + + DEBUGLOG(5, "ZSTD_entropyCompressSeqStore_internal (nbSeq=%zu, dstCapacity=%zu)", nbSeq, dstCapacity); + ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<= HUF_WORKSPACE_SIZE); + + /* Compress literals */ + { size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + /* Base suspicion of uncompressibility on ratio of literals to sequences */ + int const suspectUncompressible = (numSequences == 0) || (litSize / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO); + + size_t const cSize = ZSTD_compressLiterals( + op, dstCapacity, + literals, litSize, + entropyWorkspace, entropyWkspSize, + &prevEntropy->huf, &nextEntropy->huf, + cctxParams->cParams.strategy, + ZSTD_literalsCompressionIsDisabled(cctxParams), + suspectUncompressible, bmi2); + FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed"); + assert(cSize <= dstCapacity); + op += cSize; + } + + /* Sequences Header */ + RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/, + dstSize_tooSmall, "Can't fit seq hdr in output buf!"); + if (nbSeq < 128) { + *op++ = (BYTE)nbSeq; + } else if (nbSeq < LONGNBSEQ) { + op[0] = (BYTE)((nbSeq>>8) + 0x80); + op[1] = (BYTE)nbSeq; + op+=2; + } else { + op[0]=0xFF; + MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)); + op+=3; + } + assert(op <= oend); + if (nbSeq==0) { + /* Copy the old tables over as if we repeated them */ + ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse)); + return (size_t)(op - ostart); + } + { BYTE* const seqHead = op++; + /* build stats for sequences */ + const ZSTD_symbolEncodingTypeStats_t stats = + ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq, + &prevEntropy->fse, &nextEntropy->fse, + op, oend, + strategy, count, + entropyWorkspace, entropyWkspSize); + FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!"); + *seqHead = (BYTE)((stats.LLtype<<6) + (stats.Offtype<<4) + (stats.MLtype<<2)); + lastCountSize = stats.lastCountSize; + op += stats.size; + longOffsets = stats.longOffsets; + } + + { size_t const bitstreamSize = ZSTD_encodeSequences( + op, (size_t)(oend - op), + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, + longOffsets, bmi2); + FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed"); + op += bitstreamSize; + assert(op <= oend); + /* zstd versions <= 1.3.4 mistakenly report corruption when + * FSE_readNCount() receives a buffer < 4 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1146. + * This can happen when the last set_compressed table present is 2 + * bytes and the bitstream is only one byte. + * In this exceedingly rare case, we will simply emit an uncompressed + * block, since it isn't worth optimizing. + */ + if (lastCountSize && (lastCountSize + bitstreamSize) < 4) { + /* lastCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */ + assert(lastCountSize + bitstreamSize == 3); + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by " + "emitting an uncompressed block."); + return 0; + } + } + + DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart)); + return (size_t)(op - ostart); +} + +static size_t +ZSTD_entropyCompressSeqStore_wExtLitBuffer( + void* dst, size_t dstCapacity, + const void* literals, size_t litSize, + size_t blockSize, + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* entropyWorkspace, size_t entropyWkspSize, + int bmi2) +{ + size_t const cSize = ZSTD_entropyCompressSeqStore_internal( + dst, dstCapacity, + literals, litSize, + seqStorePtr, prevEntropy, nextEntropy, cctxParams, + entropyWorkspace, entropyWkspSize, bmi2); + if (cSize == 0) return 0; + /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block. + * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block. + */ + if ((cSize == ERROR(dstSize_tooSmall)) & (blockSize <= dstCapacity)) { + DEBUGLOG(4, "not enough dstCapacity (%zu) for ZSTD_entropyCompressSeqStore_internal()=> do not compress block", dstCapacity); + return 0; /* block not compressed */ + } + FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSeqStore_internal failed"); + + /* Check compressibility */ + { size_t const maxCSize = blockSize - ZSTD_minGain(blockSize, cctxParams->cParams.strategy); + if (cSize >= maxCSize) return 0; /* block not compressed */ + } + DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize); + /* libzstd decoder before > v1.5.4 is not compatible with compressed blocks of size ZSTD_BLOCKSIZE_MAX exactly. + * This restriction is indirectly already fulfilled by respecting ZSTD_minGain() condition above. + */ + assert(cSize < ZSTD_BLOCKSIZE_MAX); + return cSize; +} + +static size_t +ZSTD_entropyCompressSeqStore( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + size_t srcSize, + void* entropyWorkspace, size_t entropyWkspSize, + int bmi2) +{ + return ZSTD_entropyCompressSeqStore_wExtLitBuffer( + dst, dstCapacity, + seqStorePtr->litStart, (size_t)(seqStorePtr->lit - seqStorePtr->litStart), + srcSize, + seqStorePtr, + prevEntropy, nextEntropy, + cctxParams, + entropyWorkspace, entropyWkspSize, + bmi2); +} + +/* ZSTD_selectBlockCompressor() : + * Not static, but internal use only (used by long distance matcher) + * assumption : strat is a valid strategy */ +ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_ParamSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode) +{ + static const ZSTD_BlockCompressor_f blockCompressor[4][ZSTD_STRATEGY_MAX+1] = { + { ZSTD_compressBlock_fast /* default for 0 */, + ZSTD_compressBlock_fast, + ZSTD_COMPRESSBLOCK_DOUBLEFAST, + ZSTD_COMPRESSBLOCK_GREEDY, + ZSTD_COMPRESSBLOCK_LAZY, + ZSTD_COMPRESSBLOCK_LAZY2, + ZSTD_COMPRESSBLOCK_BTLAZY2, + ZSTD_COMPRESSBLOCK_BTOPT, + ZSTD_COMPRESSBLOCK_BTULTRA, + ZSTD_COMPRESSBLOCK_BTULTRA2 + }, + { ZSTD_compressBlock_fast_extDict /* default for 0 */, + ZSTD_compressBlock_fast_extDict, + ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT, + ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT, + ZSTD_COMPRESSBLOCK_LAZY_EXTDICT, + ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT, + ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT, + ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT, + ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT, + ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT + }, + { ZSTD_compressBlock_fast_dictMatchState /* default for 0 */, + ZSTD_compressBlock_fast_dictMatchState, + ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE + }, + { NULL /* default for 0 */, + NULL, + NULL, + ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH, + ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH, + ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH, + NULL, + NULL, + NULL, + NULL } + }; + ZSTD_BlockCompressor_f selectedCompressor; + ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); + + assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat)); + DEBUGLOG(5, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder); + if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) { + static const ZSTD_BlockCompressor_f rowBasedBlockCompressors[4][3] = { + { + ZSTD_COMPRESSBLOCK_GREEDY_ROW, + ZSTD_COMPRESSBLOCK_LAZY_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW, + ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW, + ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW, + ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW + } + }; + DEBUGLOG(5, "Selecting a row-based matchfinder"); + assert(useRowMatchFinder != ZSTD_ps_auto); + selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy]; + } else { + selectedCompressor = blockCompressor[(int)dictMode][(int)strat]; + } + assert(selectedCompressor != NULL); + return selectedCompressor; +} + +static void ZSTD_storeLastLiterals(SeqStore_t* seqStorePtr, + const BYTE* anchor, size_t lastLLSize) +{ + ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; +} + +void ZSTD_resetSeqStore(SeqStore_t* ssPtr) +{ + ssPtr->lit = ssPtr->litStart; + ssPtr->sequences = ssPtr->sequencesStart; + ssPtr->longLengthType = ZSTD_llt_none; +} + +/* ZSTD_postProcessSequenceProducerResult() : + * Validates and post-processes sequences obtained through the external matchfinder API: + * - Checks whether nbExternalSeqs represents an error condition. + * - Appends a block delimiter to outSeqs if one is not already present. + * See zstd.h for context regarding block delimiters. + * Returns the number of sequences after post-processing, or an error code. */ +static size_t ZSTD_postProcessSequenceProducerResult( + ZSTD_Sequence* outSeqs, size_t nbExternalSeqs, size_t outSeqsCapacity, size_t srcSize +) { + RETURN_ERROR_IF( + nbExternalSeqs > outSeqsCapacity, + sequenceProducer_failed, + "External sequence producer returned error code %lu", + (unsigned long)nbExternalSeqs + ); + + RETURN_ERROR_IF( + nbExternalSeqs == 0 && srcSize > 0, + sequenceProducer_failed, + "Got zero sequences from external sequence producer for a non-empty src buffer!" + ); + + if (srcSize == 0) { + ZSTD_memset(&outSeqs[0], 0, sizeof(ZSTD_Sequence)); + return 1; + } + + { + ZSTD_Sequence const lastSeq = outSeqs[nbExternalSeqs - 1]; + + /* We can return early if lastSeq is already a block delimiter. */ + if (lastSeq.offset == 0 && lastSeq.matchLength == 0) { + return nbExternalSeqs; + } + + /* This error condition is only possible if the external matchfinder + * produced an invalid parse, by definition of ZSTD_sequenceBound(). */ + RETURN_ERROR_IF( + nbExternalSeqs == outSeqsCapacity, + sequenceProducer_failed, + "nbExternalSeqs == outSeqsCapacity but lastSeq is not a block delimiter!" + ); + + /* lastSeq is not a block delimiter, so we need to append one. */ + ZSTD_memset(&outSeqs[nbExternalSeqs], 0, sizeof(ZSTD_Sequence)); + return nbExternalSeqs + 1; + } +} + +/* ZSTD_fastSequenceLengthSum() : + * Returns sum(litLen) + sum(matchLen) + lastLits for *seqBuf*. + * Similar to another function in zstd_compress.c (determine_blockSize), + * except it doesn't check for a block delimiter to end summation. + * Removing the early exit allows the compiler to auto-vectorize (https://godbolt.org/z/cY1cajz9P). + * This function can be deleted and replaced by determine_blockSize after we resolve issue #3456. */ +static size_t ZSTD_fastSequenceLengthSum(ZSTD_Sequence const* seqBuf, size_t seqBufSize) { + size_t matchLenSum, litLenSum, i; + matchLenSum = 0; + litLenSum = 0; + for (i = 0; i < seqBufSize; i++) { + litLenSum += seqBuf[i].litLength; + matchLenSum += seqBuf[i].matchLength; + } + return litLenSum + matchLenSum; +} + +/** + * Function to validate sequences produced by a block compressor. + */ +static void ZSTD_validateSeqStore(const SeqStore_t* seqStore, const ZSTD_compressionParameters* cParams) +{ +#if DEBUGLEVEL >= 1 + const SeqDef* seq = seqStore->sequencesStart; + const SeqDef* const seqEnd = seqStore->sequences; + size_t const matchLenLowerBound = cParams->minMatch == 3 ? 3 : 4; + for (; seq < seqEnd; ++seq) { + const ZSTD_SequenceLength seqLength = ZSTD_getSequenceLength(seqStore, seq); + assert(seqLength.matchLength >= matchLenLowerBound); + (void)seqLength; + (void)matchLenLowerBound; + } +#else + (void)seqStore; + (void)cParams; +#endif +} + +static size_t +ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx, + ZSTD_SequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize, + ZSTD_ParamSwitch_e externalRepSearch); + +typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_BuildSeqStore_e; + +static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) +{ + ZSTD_MatchState_t* const ms = &zc->blockState.matchState; + DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize); + assert(srcSize <= ZSTD_BLOCKSIZE_MAX); + /* Assert that we have correctly flushed the ctx params into the ms's copy */ + ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams); + /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding + * additional 1. We need to revisit and change this logic to be more consistent */ + if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1+1) { + if (zc->appliedParams.cParams.strategy >= ZSTD_btopt) { + ZSTD_ldm_skipRawSeqStoreBytes(&zc->externSeqStore, srcSize); + } else { + ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch); + } + return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */ + } + ZSTD_resetSeqStore(&(zc->seqStore)); + /* required for optimal parser to read stats from dictionary */ + ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy; + /* tell the optimal parser how we expect to compress literals */ + ms->opt.literalCompressionMode = zc->appliedParams.literalCompressionMode; + /* a gap between an attached dict and the current window is not safe, + * they must remain adjacent, + * and when that stops being the case, the dict must be unset */ + assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit); + + /* limited update after a very long match */ + { const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const U32 curr = (U32)(istart-base); + if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1)); /* ensure no overflow */ + if (curr > ms->nextToUpdate + 384) + ms->nextToUpdate = curr - MIN(192, (U32)(curr - ms->nextToUpdate - 384)); + } + + /* select and store sequences */ + { ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms); + size_t lastLLSize; + { int i; + for (i = 0; i < ZSTD_REP_NUM; ++i) + zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i]; + } + if (zc->externSeqStore.pos < zc->externSeqStore.size) { + assert(zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_disable); + + /* External matchfinder + LDM is technically possible, just not implemented yet. + * We need to revisit soon and implement it. */ + RETURN_ERROR_IF( + ZSTD_hasExtSeqProd(&zc->appliedParams), + parameter_combination_unsupported, + "Long-distance matching with external sequence producer enabled is not currently supported." + ); + + /* Updates ldmSeqStore.pos */ + lastLLSize = + ZSTD_ldm_blockCompress(&zc->externSeqStore, + ms, &zc->seqStore, + zc->blockState.nextCBlock->rep, + zc->appliedParams.useRowMatchFinder, + src, srcSize); + assert(zc->externSeqStore.pos <= zc->externSeqStore.size); + } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { + RawSeqStore_t ldmSeqStore = kNullRawSeqStore; + + /* External matchfinder + LDM is technically possible, just not implemented yet. + * We need to revisit soon and implement it. */ + RETURN_ERROR_IF( + ZSTD_hasExtSeqProd(&zc->appliedParams), + parameter_combination_unsupported, + "Long-distance matching with external sequence producer enabled is not currently supported." + ); + + ldmSeqStore.seq = zc->ldmSequences; + ldmSeqStore.capacity = zc->maxNbLdmSequences; + /* Updates ldmSeqStore.size */ + FORWARD_IF_ERROR(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore, + &zc->appliedParams.ldmParams, + src, srcSize), ""); + /* Updates ldmSeqStore.pos */ + lastLLSize = + ZSTD_ldm_blockCompress(&ldmSeqStore, + ms, &zc->seqStore, + zc->blockState.nextCBlock->rep, + zc->appliedParams.useRowMatchFinder, + src, srcSize); + assert(ldmSeqStore.pos == ldmSeqStore.size); + } else if (ZSTD_hasExtSeqProd(&zc->appliedParams)) { + assert( + zc->extSeqBufCapacity >= ZSTD_sequenceBound(srcSize) + ); + assert(zc->appliedParams.extSeqProdFunc != NULL); + + { U32 const windowSize = (U32)1 << zc->appliedParams.cParams.windowLog; + + size_t const nbExternalSeqs = (zc->appliedParams.extSeqProdFunc)( + zc->appliedParams.extSeqProdState, + zc->extSeqBuf, + zc->extSeqBufCapacity, + src, srcSize, + NULL, 0, /* dict and dictSize, currently not supported */ + zc->appliedParams.compressionLevel, + windowSize + ); + + size_t const nbPostProcessedSeqs = ZSTD_postProcessSequenceProducerResult( + zc->extSeqBuf, + nbExternalSeqs, + zc->extSeqBufCapacity, + srcSize + ); + + /* Return early if there is no error, since we don't need to worry about last literals */ + if (!ZSTD_isError(nbPostProcessedSeqs)) { + ZSTD_SequencePosition seqPos = {0,0,0}; + size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->extSeqBuf, nbPostProcessedSeqs); + RETURN_ERROR_IF(seqLenSum > srcSize, externalSequences_invalid, "External sequences imply too large a block!"); + FORWARD_IF_ERROR( + ZSTD_transferSequences_wBlockDelim( + zc, &seqPos, + zc->extSeqBuf, nbPostProcessedSeqs, + src, srcSize, + zc->appliedParams.searchForExternalRepcodes + ), + "Failed to copy external sequences to seqStore!" + ); + ms->ldmSeqStore = NULL; + DEBUGLOG(5, "Copied %lu sequences from external sequence producer to internal seqStore.", (unsigned long)nbExternalSeqs); + return ZSTDbss_compress; + } + + /* Propagate the error if fallback is disabled */ + if (!zc->appliedParams.enableMatchFinderFallback) { + return nbPostProcessedSeqs; + } + + /* Fallback to software matchfinder */ + { ZSTD_BlockCompressor_f const blockCompressor = + ZSTD_selectBlockCompressor( + zc->appliedParams.cParams.strategy, + zc->appliedParams.useRowMatchFinder, + dictMode); + ms->ldmSeqStore = NULL; + DEBUGLOG( + 5, + "External sequence producer returned error code %lu. Falling back to internal parser.", + (unsigned long)nbExternalSeqs + ); + lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); + } } + } else { /* not long range mode and no external matchfinder */ + ZSTD_BlockCompressor_f const blockCompressor = ZSTD_selectBlockCompressor( + zc->appliedParams.cParams.strategy, + zc->appliedParams.useRowMatchFinder, + dictMode); + ms->ldmSeqStore = NULL; + lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); + } + { const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize; + ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize); + } } + ZSTD_validateSeqStore(&zc->seqStore, &zc->appliedParams.cParams); + return ZSTDbss_compress; +} + +static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const SeqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM]) +{ + const SeqDef* inSeqs = seqStore->sequencesStart; + const size_t nbInSequences = (size_t)(seqStore->sequences - inSeqs); + const size_t nbInLiterals = (size_t)(seqStore->lit - seqStore->litStart); + + ZSTD_Sequence* outSeqs = seqCollector->seqIndex == 0 ? seqCollector->seqStart : seqCollector->seqStart + seqCollector->seqIndex; + const size_t nbOutSequences = nbInSequences + 1; + size_t nbOutLiterals = 0; + Repcodes_t repcodes; + size_t i; + + /* Bounds check that we have enough space for every input sequence + * and the block delimiter + */ + assert(seqCollector->seqIndex <= seqCollector->maxSequences); + RETURN_ERROR_IF( + nbOutSequences > (size_t)(seqCollector->maxSequences - seqCollector->seqIndex), + dstSize_tooSmall, + "Not enough space to copy sequences"); + + ZSTD_memcpy(&repcodes, prevRepcodes, sizeof(repcodes)); + for (i = 0; i < nbInSequences; ++i) { + U32 rawOffset; + outSeqs[i].litLength = inSeqs[i].litLength; + outSeqs[i].matchLength = inSeqs[i].mlBase + MINMATCH; + outSeqs[i].rep = 0; + + /* Handle the possible single length >= 64K + * There can only be one because we add MINMATCH to every match length, + * and blocks are at most 128K. + */ + if (i == seqStore->longLengthPos) { + if (seqStore->longLengthType == ZSTD_llt_literalLength) { + outSeqs[i].litLength += 0x10000; + } else if (seqStore->longLengthType == ZSTD_llt_matchLength) { + outSeqs[i].matchLength += 0x10000; + } + } + + /* Determine the raw offset given the offBase, which may be a repcode. */ + if (OFFBASE_IS_REPCODE(inSeqs[i].offBase)) { + const U32 repcode = OFFBASE_TO_REPCODE(inSeqs[i].offBase); + assert(repcode > 0); + outSeqs[i].rep = repcode; + if (outSeqs[i].litLength != 0) { + rawOffset = repcodes.rep[repcode - 1]; + } else { + if (repcode == 3) { + assert(repcodes.rep[0] > 1); + rawOffset = repcodes.rep[0] - 1; + } else { + rawOffset = repcodes.rep[repcode]; + } + } + } else { + rawOffset = OFFBASE_TO_OFFSET(inSeqs[i].offBase); + } + outSeqs[i].offset = rawOffset; + + /* Update repcode history for the sequence */ + ZSTD_updateRep(repcodes.rep, + inSeqs[i].offBase, + inSeqs[i].litLength == 0); + + nbOutLiterals += outSeqs[i].litLength; + } + /* Insert last literals (if any exist) in the block as a sequence with ml == off == 0. + * If there are no last literals, then we'll emit (of: 0, ml: 0, ll: 0), which is a marker + * for the block boundary, according to the API. + */ + assert(nbInLiterals >= nbOutLiterals); + { + const size_t lastLLSize = nbInLiterals - nbOutLiterals; + outSeqs[nbInSequences].litLength = (U32)lastLLSize; + outSeqs[nbInSequences].matchLength = 0; + outSeqs[nbInSequences].offset = 0; + assert(nbOutSequences == nbInSequences + 1); + } + seqCollector->seqIndex += nbOutSequences; + assert(seqCollector->seqIndex <= seqCollector->maxSequences); + + return 0; +} + +size_t ZSTD_sequenceBound(size_t srcSize) { + const size_t maxNbSeq = (srcSize / ZSTD_MINMATCH_MIN) + 1; + const size_t maxNbDelims = (srcSize / ZSTD_BLOCKSIZE_MAX_MIN) + 1; + return maxNbSeq + maxNbDelims; +} + +size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, + size_t outSeqsSize, const void* src, size_t srcSize) +{ + const size_t dstCapacity = ZSTD_compressBound(srcSize); + void* dst; /* Make C90 happy. */ + SeqCollector seqCollector; + { + int targetCBlockSize; + FORWARD_IF_ERROR(ZSTD_CCtx_getParameter(zc, ZSTD_c_targetCBlockSize, &targetCBlockSize), ""); + RETURN_ERROR_IF(targetCBlockSize != 0, parameter_unsupported, "targetCBlockSize != 0"); + } + { + int nbWorkers; + FORWARD_IF_ERROR(ZSTD_CCtx_getParameter(zc, ZSTD_c_nbWorkers, &nbWorkers), ""); + RETURN_ERROR_IF(nbWorkers != 0, parameter_unsupported, "nbWorkers != 0"); + } + + dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem); + RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!"); + + seqCollector.collectSequences = 1; + seqCollector.seqStart = outSeqs; + seqCollector.seqIndex = 0; + seqCollector.maxSequences = outSeqsSize; + zc->seqCollector = seqCollector; + + { + const size_t ret = ZSTD_compress2(zc, dst, dstCapacity, src, srcSize); + ZSTD_customFree(dst, ZSTD_defaultCMem); + FORWARD_IF_ERROR(ret, "ZSTD_compress2 failed"); + } + assert(zc->seqCollector.seqIndex <= ZSTD_sequenceBound(srcSize)); + return zc->seqCollector.seqIndex; +} + +size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize) { + size_t in = 0; + size_t out = 0; + for (; in < seqsSize; ++in) { + if (sequences[in].offset == 0 && sequences[in].matchLength == 0) { + if (in != seqsSize - 1) { + sequences[in+1].litLength += sequences[in].litLength; + } + } else { + sequences[out] = sequences[in]; + ++out; + } + } + return out; +} + +/* Unrolled loop to read four size_ts of input at a time. Returns 1 if is RLE, 0 if not. */ +static int ZSTD_isRLE(const BYTE* src, size_t length) { + const BYTE* ip = src; + const BYTE value = ip[0]; + const size_t valueST = (size_t)((U64)value * 0x0101010101010101ULL); + const size_t unrollSize = sizeof(size_t) * 4; + const size_t unrollMask = unrollSize - 1; + const size_t prefixLength = length & unrollMask; + size_t i; + if (length == 1) return 1; + /* Check if prefix is RLE first before using unrolled loop */ + if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) { + return 0; + } + for (i = prefixLength; i != length; i += unrollSize) { + size_t u; + for (u = 0; u < unrollSize; u += sizeof(size_t)) { + if (MEM_readST(ip + i + u) != valueST) { + return 0; + } } } + return 1; +} + +/* Returns true if the given block may be RLE. + * This is just a heuristic based on the compressibility. + * It may return both false positives and false negatives. + */ +static int ZSTD_maybeRLE(SeqStore_t const* seqStore) +{ + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart); + + return nbSeqs < 4 && nbLits < 10; +} + +static void +ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs) +{ + ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock; + bs->prevCBlock = bs->nextCBlock; + bs->nextCBlock = tmp; +} + +/* Writes the block header */ +static void +writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock) +{ + U32 const cBlockHeader = cSize == 1 ? + lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) : + lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(op, cBlockHeader); + DEBUGLOG(5, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock); +} + +/** ZSTD_buildBlockEntropyStats_literals() : + * Builds entropy for the literals. + * Stores literals block type (raw, rle, compressed, repeat) and + * huffman description table to hufMetadata. + * Requires ENTROPY_WORKSPACE_SIZE workspace + * @return : size of huffman description table, or an error code + */ +static size_t +ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_hufCTablesMetadata_t* hufMetadata, + const int literalsCompressionIsDisabled, + void* workspace, size_t wkspSize, + int hufFlags) +{ + BYTE* const wkspStart = (BYTE*)workspace; + BYTE* const wkspEnd = wkspStart + wkspSize; + BYTE* const countWkspStart = wkspStart; + unsigned* const countWksp = (unsigned*)workspace; + const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned); + BYTE* const nodeWksp = countWkspStart + countWkspSize; + const size_t nodeWkspSize = (size_t)(wkspEnd - nodeWksp); + unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX; + unsigned huffLog = LitHufLog; + HUF_repeat repeat = prevHuf->repeatMode; + DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_literals (srcSize=%zu)", srcSize); + + /* Prepare nextEntropy assuming reusing the existing table */ + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + + if (literalsCompressionIsDisabled) { + DEBUGLOG(5, "set_basic - disabled"); + hufMetadata->hType = set_basic; + return 0; + } + + /* small ? don't even attempt compression (speed opt) */ +#ifndef COMPRESS_LITERALS_SIZE_MIN +# define COMPRESS_LITERALS_SIZE_MIN 63 /* heuristic */ +#endif + { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN; + if (srcSize <= minLitSize) { + DEBUGLOG(5, "set_basic - too small"); + hufMetadata->hType = set_basic; + return 0; + } } + + /* Scan input and build symbol stats */ + { size_t const largest = + HIST_count_wksp (countWksp, &maxSymbolValue, + (const BYTE*)src, srcSize, + workspace, wkspSize); + FORWARD_IF_ERROR(largest, "HIST_count_wksp failed"); + if (largest == srcSize) { + /* only one literal symbol */ + DEBUGLOG(5, "set_rle"); + hufMetadata->hType = set_rle; + return 0; + } + if (largest <= (srcSize >> 7)+4) { + /* heuristic: likely not compressible */ + DEBUGLOG(5, "set_basic - no gain"); + hufMetadata->hType = set_basic; + return 0; + } } + + /* Validate the previous Huffman table */ + if (repeat == HUF_repeat_check + && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) { + repeat = HUF_repeat_none; + } + + /* Build Huffman Tree */ + ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable)); + huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, nodeWksp, nodeWkspSize, nextHuf->CTable, countWksp, hufFlags); + assert(huffLog <= LitHufLog); + { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp, + maxSymbolValue, huffLog, + nodeWksp, nodeWkspSize); + FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp"); + huffLog = (U32)maxBits; + } + { /* Build and write the CTable */ + size_t const newCSize = HUF_estimateCompressedSize( + (HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue); + size_t const hSize = HUF_writeCTable_wksp( + hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer), + (HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog, + nodeWksp, nodeWkspSize); + /* Check against repeating the previous CTable */ + if (repeat != HUF_repeat_none) { + size_t const oldCSize = HUF_estimateCompressedSize( + (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue); + if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) { + DEBUGLOG(5, "set_repeat - smaller"); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + hufMetadata->hType = set_repeat; + return 0; + } } + if (newCSize + hSize >= srcSize) { + DEBUGLOG(5, "set_basic - no gains"); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + hufMetadata->hType = set_basic; + return 0; + } + DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize); + hufMetadata->hType = set_compressed; + nextHuf->repeatMode = HUF_repeat_check; + return hSize; + } +} + + +/* ZSTD_buildDummySequencesStatistics(): + * Returns a ZSTD_symbolEncodingTypeStats_t with all encoding types as set_basic, + * and updates nextEntropy to the appropriate repeatMode. + */ +static ZSTD_symbolEncodingTypeStats_t +ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy) +{ + ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0, 0}; + nextEntropy->litlength_repeatMode = FSE_repeat_none; + nextEntropy->offcode_repeatMode = FSE_repeat_none; + nextEntropy->matchlength_repeatMode = FSE_repeat_none; + return stats; +} + +/** ZSTD_buildBlockEntropyStats_sequences() : + * Builds entropy for the sequences. + * Stores symbol compression modes and fse table to fseMetadata. + * Requires ENTROPY_WORKSPACE_SIZE wksp. + * @return : size of fse tables or error code */ +static size_t +ZSTD_buildBlockEntropyStats_sequences( + const SeqStore_t* seqStorePtr, + const ZSTD_fseCTables_t* prevEntropy, + ZSTD_fseCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize) +{ + ZSTD_strategy const strategy = cctxParams->cParams.strategy; + size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + BYTE* const ostart = fseMetadata->fseTablesBuffer; + BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer); + BYTE* op = ostart; + unsigned* countWorkspace = (unsigned*)workspace; + unsigned* entropyWorkspace = countWorkspace + (MaxSeq + 1); + size_t entropyWorkspaceSize = wkspSize - (MaxSeq + 1) * sizeof(*countWorkspace); + ZSTD_symbolEncodingTypeStats_t stats; + + DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_sequences (nbSeq=%zu)", nbSeq); + stats = nbSeq != 0 ? ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq, + prevEntropy, nextEntropy, op, oend, + strategy, countWorkspace, + entropyWorkspace, entropyWorkspaceSize) + : ZSTD_buildDummySequencesStatistics(nextEntropy); + FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!"); + fseMetadata->llType = (SymbolEncodingType_e) stats.LLtype; + fseMetadata->ofType = (SymbolEncodingType_e) stats.Offtype; + fseMetadata->mlType = (SymbolEncodingType_e) stats.MLtype; + fseMetadata->lastCountSize = stats.lastCountSize; + return stats.size; +} + + +/** ZSTD_buildBlockEntropyStats() : + * Builds entropy for the block. + * Requires workspace size ENTROPY_WORKSPACE_SIZE + * @return : 0 on success, or an error code + * Note : also employed in superblock + */ +size_t ZSTD_buildBlockEntropyStats( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize) +{ + size_t const litSize = (size_t)(seqStorePtr->lit - seqStorePtr->litStart); + int const huf_useOptDepth = (cctxParams->cParams.strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD); + int const hufFlags = huf_useOptDepth ? HUF_flags_optimalDepth : 0; + + entropyMetadata->hufMetadata.hufDesSize = + ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize, + &prevEntropy->huf, &nextEntropy->huf, + &entropyMetadata->hufMetadata, + ZSTD_literalsCompressionIsDisabled(cctxParams), + workspace, wkspSize, hufFlags); + + FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildBlockEntropyStats_literals failed"); + entropyMetadata->fseMetadata.fseTablesSize = + ZSTD_buildBlockEntropyStats_sequences(seqStorePtr, + &prevEntropy->fse, &nextEntropy->fse, + cctxParams, + &entropyMetadata->fseMetadata, + workspace, wkspSize); + FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildBlockEntropyStats_sequences failed"); + return 0; +} + +/* Returns the size estimate for the literals section (header + content) of a block */ +static size_t +ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize, + const ZSTD_hufCTables_t* huf, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + unsigned* const countWksp = (unsigned*)workspace; + unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX; + size_t literalSectionHeaderSize = 3 + (litSize >= 1 KB) + (litSize >= 16 KB); + U32 singleStream = litSize < 256; + + if (hufMetadata->hType == set_basic) return litSize; + else if (hufMetadata->hType == set_rle) return 1; + else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) { + size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize); + if (ZSTD_isError(largest)) return litSize; + { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue); + if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize; + if (!singleStream) cLitSizeEstimate += 6; /* multi-stream huffman uses 6-byte jump table */ + return cLitSizeEstimate + literalSectionHeaderSize; + } } + assert(0); /* impossible */ + return 0; +} + +/* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */ +static size_t +ZSTD_estimateBlockSize_symbolType(SymbolEncodingType_e type, + const BYTE* codeTable, size_t nbSeq, unsigned maxCode, + const FSE_CTable* fseCTable, + const U8* additionalBits, + short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, + void* workspace, size_t wkspSize) +{ + unsigned* const countWksp = (unsigned*)workspace; + const BYTE* ctp = codeTable; + const BYTE* const ctStart = ctp; + const BYTE* const ctEnd = ctStart + nbSeq; + size_t cSymbolTypeSizeEstimateInBits = 0; + unsigned max = maxCode; + + HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */ + if (type == set_basic) { + /* We selected this encoding type, so it must be valid. */ + assert(max <= defaultMax); + (void)defaultMax; + cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max); + } else if (type == set_rle) { + cSymbolTypeSizeEstimateInBits = 0; + } else if (type == set_compressed || type == set_repeat) { + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); + } + if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) { + return nbSeq * 10; + } + while (ctp < ctEnd) { + if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp]; + else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */ + ctp++; + } + return cSymbolTypeSizeEstimateInBits >> 3; +} + +/* Returns the size estimate for the sequences section (header + content) of a block */ +static size_t +ZSTD_estimateBlockSize_sequences(const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + size_t sequencesSectionHeaderSize = 1 /* seqHead */ + 1 /* min seqSize size */ + (nbSeq >= 128) + (nbSeq >= LONGNBSEQ); + size_t cSeqSizeEstimate = 0; + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, nbSeq, MaxOff, + fseTables->offcodeCTable, NULL, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->llType, llCodeTable, nbSeq, MaxLL, + fseTables->litlengthCTable, LL_bits, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, nbSeq, MaxML, + fseTables->matchlengthCTable, ML_bits, + ML_defaultNorm, ML_defaultNormLog, MaxML, + workspace, wkspSize); + if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; + return cSeqSizeEstimate + sequencesSectionHeaderSize; +} + +/* Returns the size estimate for a given stream of literals, of, ll, ml */ +static size_t +ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize, + const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize, + int writeLitEntropy, int writeSeqEntropy) +{ + size_t const literalsSize = ZSTD_estimateBlockSize_literal(literals, litSize, + &entropy->huf, &entropyMetadata->hufMetadata, + workspace, wkspSize, writeLitEntropy); + size_t const seqSize = ZSTD_estimateBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, + nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, + workspace, wkspSize, writeSeqEntropy); + return seqSize + literalsSize + ZSTD_blockHeaderSize; +} + +/* Builds entropy statistics and uses them for blocksize estimation. + * + * @return: estimated compressed size of the seqStore, or a zstd error. + */ +static size_t +ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(SeqStore_t* seqStore, ZSTD_CCtx* zc) +{ + ZSTD_entropyCTablesMetadata_t* const entropyMetadata = &zc->blockSplitCtx.entropyMetadata; + DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()"); + FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore, + &zc->blockState.prevCBlock->entropy, + &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize), ""); + return ZSTD_estimateBlockSize( + seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart), + seqStore->ofCode, seqStore->llCode, seqStore->mlCode, + (size_t)(seqStore->sequences - seqStore->sequencesStart), + &zc->blockState.nextCBlock->entropy, + entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize, + (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1); +} + +/* Returns literals bytes represented in a seqStore */ +static size_t ZSTD_countSeqStoreLiteralsBytes(const SeqStore_t* const seqStore) +{ + size_t literalsBytes = 0; + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t i; + for (i = 0; i < nbSeqs; ++i) { + SeqDef const seq = seqStore->sequencesStart[i]; + literalsBytes += seq.litLength; + if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) { + literalsBytes += 0x10000; + } } + return literalsBytes; +} + +/* Returns match bytes represented in a seqStore */ +static size_t ZSTD_countSeqStoreMatchBytes(const SeqStore_t* const seqStore) +{ + size_t matchBytes = 0; + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t i; + for (i = 0; i < nbSeqs; ++i) { + SeqDef seq = seqStore->sequencesStart[i]; + matchBytes += seq.mlBase + MINMATCH; + if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) { + matchBytes += 0x10000; + } } + return matchBytes; +} + +/* Derives the seqStore that is a chunk of the originalSeqStore from [startIdx, endIdx). + * Stores the result in resultSeqStore. + */ +static void ZSTD_deriveSeqStoreChunk(SeqStore_t* resultSeqStore, + const SeqStore_t* originalSeqStore, + size_t startIdx, size_t endIdx) +{ + *resultSeqStore = *originalSeqStore; + if (startIdx > 0) { + resultSeqStore->sequences = originalSeqStore->sequencesStart + startIdx; + resultSeqStore->litStart += ZSTD_countSeqStoreLiteralsBytes(resultSeqStore); + } + + /* Move longLengthPos into the correct position if necessary */ + if (originalSeqStore->longLengthType != ZSTD_llt_none) { + if (originalSeqStore->longLengthPos < startIdx || originalSeqStore->longLengthPos > endIdx) { + resultSeqStore->longLengthType = ZSTD_llt_none; + } else { + resultSeqStore->longLengthPos -= (U32)startIdx; + } + } + resultSeqStore->sequencesStart = originalSeqStore->sequencesStart + startIdx; + resultSeqStore->sequences = originalSeqStore->sequencesStart + endIdx; + if (endIdx == (size_t)(originalSeqStore->sequences - originalSeqStore->sequencesStart)) { + /* This accounts for possible last literals if the derived chunk reaches the end of the block */ + assert(resultSeqStore->lit == originalSeqStore->lit); + } else { + size_t const literalsBytes = ZSTD_countSeqStoreLiteralsBytes(resultSeqStore); + resultSeqStore->lit = resultSeqStore->litStart + literalsBytes; + } + resultSeqStore->llCode += startIdx; + resultSeqStore->mlCode += startIdx; + resultSeqStore->ofCode += startIdx; +} + +/** + * Returns the raw offset represented by the combination of offBase, ll0, and repcode history. + * offBase must represent a repcode in the numeric representation of ZSTD_storeSeq(). + */ +static U32 +ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, const U32 ll0) +{ + U32 const adjustedRepCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; /* [ 0 - 3 ] */ + assert(OFFBASE_IS_REPCODE(offBase)); + if (adjustedRepCode == ZSTD_REP_NUM) { + assert(ll0); + /* litlength == 0 and offCode == 2 implies selection of first repcode - 1 + * This is only valid if it results in a valid offset value, aka > 0. + * Note : it may happen that `rep[0]==1` in exceptional circumstances. + * In which case this function will return 0, which is an invalid offset. + * It's not an issue though, since this value will be + * compared and discarded within ZSTD_seqStore_resolveOffCodes(). + */ + return rep[0] - 1; + } + return rep[adjustedRepCode]; +} + +/** + * ZSTD_seqStore_resolveOffCodes() reconciles any possible divergences in offset history that may arise + * due to emission of RLE/raw blocks that disturb the offset history, + * and replaces any repcodes within the seqStore that may be invalid. + * + * dRepcodes are updated as would be on the decompression side. + * cRepcodes are updated exactly in accordance with the seqStore. + * + * Note : this function assumes seq->offBase respects the following numbering scheme : + * 0 : invalid + * 1-3 : repcode 1-3 + * 4+ : real_offset+3 + */ +static void +ZSTD_seqStore_resolveOffCodes(Repcodes_t* const dRepcodes, Repcodes_t* const cRepcodes, + const SeqStore_t* const seqStore, U32 const nbSeq) +{ + U32 idx = 0; + U32 const longLitLenIdx = seqStore->longLengthType == ZSTD_llt_literalLength ? seqStore->longLengthPos : nbSeq; + for (; idx < nbSeq; ++idx) { + SeqDef* const seq = seqStore->sequencesStart + idx; + U32 const ll0 = (seq->litLength == 0) && (idx != longLitLenIdx); + U32 const offBase = seq->offBase; + assert(offBase > 0); + if (OFFBASE_IS_REPCODE(offBase)) { + U32 const dRawOffset = ZSTD_resolveRepcodeToRawOffset(dRepcodes->rep, offBase, ll0); + U32 const cRawOffset = ZSTD_resolveRepcodeToRawOffset(cRepcodes->rep, offBase, ll0); + /* Adjust simulated decompression repcode history if we come across a mismatch. Replace + * the repcode with the offset it actually references, determined by the compression + * repcode history. + */ + if (dRawOffset != cRawOffset) { + seq->offBase = OFFSET_TO_OFFBASE(cRawOffset); + } + } + /* Compression repcode history is always updated with values directly from the unmodified seqStore. + * Decompression repcode history may use modified seq->offset value taken from compression repcode history. + */ + ZSTD_updateRep(dRepcodes->rep, seq->offBase, ll0); + ZSTD_updateRep(cRepcodes->rep, offBase, ll0); + } +} + +/* ZSTD_compressSeqStore_singleBlock(): + * Compresses a seqStore into a block with a block header, into the buffer dst. + * + * Returns the total size of that block (including header) or a ZSTD error code. + */ +static size_t +ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, + const SeqStore_t* const seqStore, + Repcodes_t* const dRep, Repcodes_t* const cRep, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastBlock, U32 isPartition) +{ + const U32 rleMaxLength = 25; + BYTE* op = (BYTE*)dst; + const BYTE* ip = (const BYTE*)src; + size_t cSize; + size_t cSeqsSize; + + /* In case of an RLE or raw block, the simulated decompression repcode history must be reset */ + Repcodes_t const dRepOriginal = *dRep; + DEBUGLOG(5, "ZSTD_compressSeqStore_singleBlock"); + if (isPartition) + ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart)); + + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "Block header doesn't fit"); + cSeqsSize = ZSTD_entropyCompressSeqStore(seqStore, + &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize, + srcSize, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */, + zc->bmi2); + FORWARD_IF_ERROR(cSeqsSize, "ZSTD_entropyCompressSeqStore failed!"); + + if (!zc->isFirstBlock && + cSeqsSize < rleMaxLength && + ZSTD_isRLE((BYTE const*)src, srcSize)) { + /* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + cSeqsSize = 1; + } + + /* Sequence collection not supported when block splitting */ + if (zc->seqCollector.collectSequences) { + FORWARD_IF_ERROR(ZSTD_copyBlockSequences(&zc->seqCollector, seqStore, dRepOriginal.rep), "copyBlockSequences failed"); + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return 0; + } + + if (cSeqsSize == 0) { + cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "Nocompress block failed"); + DEBUGLOG(5, "Writing out nocompress block, size: %zu", cSize); + *dRep = dRepOriginal; /* reset simulated decompression repcode history */ + } else if (cSeqsSize == 1) { + cSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "RLE compress block failed"); + DEBUGLOG(5, "Writing out RLE block, size: %zu", cSize); + *dRep = dRepOriginal; /* reset simulated decompression repcode history */ + } else { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + writeBlockHeader(op, cSeqsSize, srcSize, lastBlock); + cSize = ZSTD_blockHeaderSize + cSeqsSize; + DEBUGLOG(5, "Writing out compressed block, size: %zu", cSize); + } + + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +/* Struct to keep track of where we are in our recursive calls. */ +typedef struct { + U32* splitLocations; /* Array of split indices */ + size_t idx; /* The current index within splitLocations being worked on */ +} seqStoreSplits; + +#define MIN_SEQUENCES_BLOCK_SPLITTING 300 + +/* Helper function to perform the recursive search for block splits. + * Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half. + * If advantageous to split, then we recurse down the two sub-blocks. + * If not, or if an error occurred in estimation, then we do not recurse. + * + * Note: The recursion depth is capped by a heuristic minimum number of sequences, + * defined by MIN_SEQUENCES_BLOCK_SPLITTING. + * In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING). + * In practice, recursion depth usually doesn't go beyond 4. + * + * Furthermore, the number of splits is capped by ZSTD_MAX_NB_BLOCK_SPLITS. + * At ZSTD_MAX_NB_BLOCK_SPLITS == 196 with the current existing blockSize + * maximum of 128 KB, this value is actually impossible to reach. + */ +static void +ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx, + ZSTD_CCtx* zc, const SeqStore_t* origSeqStore) +{ + SeqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk; + SeqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore; + SeqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore; + size_t estimatedOriginalSize; + size_t estimatedFirstHalfSize; + size_t estimatedSecondHalfSize; + size_t midIdx = (startIdx + endIdx)/2; + + DEBUGLOG(5, "ZSTD_deriveBlockSplitsHelper: startIdx=%zu endIdx=%zu", startIdx, endIdx); + assert(endIdx >= startIdx); + if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= ZSTD_MAX_NB_BLOCK_SPLITS) { + DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences (%zu)", endIdx - startIdx); + return; + } + ZSTD_deriveSeqStoreChunk(fullSeqStoreChunk, origSeqStore, startIdx, endIdx); + ZSTD_deriveSeqStoreChunk(firstHalfSeqStore, origSeqStore, startIdx, midIdx); + ZSTD_deriveSeqStoreChunk(secondHalfSeqStore, origSeqStore, midIdx, endIdx); + estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(fullSeqStoreChunk, zc); + estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(firstHalfSeqStore, zc); + estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(secondHalfSeqStore, zc); + DEBUGLOG(5, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu", + estimatedOriginalSize, estimatedFirstHalfSize, estimatedSecondHalfSize); + if (ZSTD_isError(estimatedOriginalSize) || ZSTD_isError(estimatedFirstHalfSize) || ZSTD_isError(estimatedSecondHalfSize)) { + return; + } + if (estimatedFirstHalfSize + estimatedSecondHalfSize < estimatedOriginalSize) { + DEBUGLOG(5, "split decided at seqNb:%zu", midIdx); + ZSTD_deriveBlockSplitsHelper(splits, startIdx, midIdx, zc, origSeqStore); + splits->splitLocations[splits->idx] = (U32)midIdx; + splits->idx++; + ZSTD_deriveBlockSplitsHelper(splits, midIdx, endIdx, zc, origSeqStore); + } +} + +/* Base recursive function. + * Populates a table with intra-block partition indices that can improve compression ratio. + * + * @return: number of splits made (which equals the size of the partition table - 1). + */ +static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq) +{ + seqStoreSplits splits; + splits.splitLocations = partitions; + splits.idx = 0; + if (nbSeq <= 4) { + DEBUGLOG(5, "ZSTD_deriveBlockSplits: Too few sequences to split (%u <= 4)", nbSeq); + /* Refuse to try and split anything with less than 4 sequences */ + return 0; + } + ZSTD_deriveBlockSplitsHelper(&splits, 0, nbSeq, zc, &zc->seqStore); + splits.splitLocations[splits.idx] = nbSeq; + DEBUGLOG(5, "ZSTD_deriveBlockSplits: final nb partitions: %zu", splits.idx+1); + return splits.idx; +} + +/* ZSTD_compressBlock_splitBlock(): + * Attempts to split a given block into multiple blocks to improve compression ratio. + * + * Returns combined size of all blocks (which includes headers), or a ZSTD error code. + */ +static size_t +ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t blockSize, + U32 lastBlock, U32 nbSeq) +{ + size_t cSize = 0; + const BYTE* ip = (const BYTE*)src; + BYTE* op = (BYTE*)dst; + size_t i = 0; + size_t srcBytesTotal = 0; + U32* const partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */ + SeqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore; + SeqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore; + size_t const numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq); + + /* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history + * may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two + * separate repcode histories that simulate repcode history on compression and decompression side, + * and use the histories to determine whether we must replace a particular repcode with its raw offset. + * + * 1) cRep gets updated for each partition, regardless of whether the block was emitted as uncompressed + * or RLE. This allows us to retrieve the offset value that an invalid repcode references within + * a nocompress/RLE block. + * 2) dRep gets updated only for compressed partitions, and when a repcode gets replaced, will use + * the replacement offset value rather than the original repcode to update the repcode history. + * dRep also will be the final repcode history sent to the next block. + * + * See ZSTD_seqStore_resolveOffCodes() for more details. + */ + Repcodes_t dRep; + Repcodes_t cRep; + ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + ZSTD_memset(nextSeqStore, 0, sizeof(SeqStore_t)); + + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, + (unsigned)zc->blockState.matchState.nextToUpdate); + + if (numSplits == 0) { + size_t cSizeSingleBlock = + ZSTD_compressSeqStore_singleBlock(zc, &zc->seqStore, + &dRep, &cRep, + op, dstCapacity, + ip, blockSize, + lastBlock, 0 /* isPartition */); + FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!"); + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits"); + assert(zc->blockSizeMax <= ZSTD_BLOCKSIZE_MAX); + assert(cSizeSingleBlock <= zc->blockSizeMax + ZSTD_blockHeaderSize); + return cSizeSingleBlock; + } + + ZSTD_deriveSeqStoreChunk(currSeqStore, &zc->seqStore, 0, partitions[0]); + for (i = 0; i <= numSplits; ++i) { + size_t cSizeChunk; + U32 const lastPartition = (i == numSplits); + U32 lastBlockEntireSrc = 0; + + size_t srcBytes = ZSTD_countSeqStoreLiteralsBytes(currSeqStore) + ZSTD_countSeqStoreMatchBytes(currSeqStore); + srcBytesTotal += srcBytes; + if (lastPartition) { + /* This is the final partition, need to account for possible last literals */ + srcBytes += blockSize - srcBytesTotal; + lastBlockEntireSrc = lastBlock; + } else { + ZSTD_deriveSeqStoreChunk(nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]); + } + + cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, currSeqStore, + &dRep, &cRep, + op, dstCapacity, + ip, srcBytes, + lastBlockEntireSrc, 1 /* isPartition */); + DEBUGLOG(5, "Estimated size: %zu vs %zu : actual size", + ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(currSeqStore, zc), cSizeChunk); + FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!"); + + ip += srcBytes; + op += cSizeChunk; + dstCapacity -= cSizeChunk; + cSize += cSizeChunk; + *currSeqStore = *nextSeqStore; + assert(cSizeChunk <= zc->blockSizeMax + ZSTD_blockHeaderSize); + } + /* cRep and dRep may have diverged during the compression. + * If so, we use the dRep repcodes for the next block. + */ + ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(Repcodes_t)); + return cSize; +} + +static size_t +ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, U32 lastBlock) +{ + U32 nbSeq; + size_t cSize; + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock"); + assert(zc->appliedParams.postBlockSplitter == ZSTD_ps_enable); + + { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + if (bss == ZSTDbss_noCompress) { + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block"); + cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock: Nocompress block"); + return cSize; + } + nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart); + } + + cSize = ZSTD_compressBlock_splitBlock_internal(zc, dst, dstCapacity, src, srcSize, lastBlock, nbSeq); + FORWARD_IF_ERROR(cSize, "Splitting blocks failed!"); + return cSize; +} + +static size_t +ZSTD_compressBlock_internal(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, U32 frame) +{ + /* This is an estimated upper bound for the length of an rle block. + * This isn't the actual upper bound. + * Finding the real threshold needs further investigation. + */ + const U32 rleMaxLength = 25; + size_t cSize; + const BYTE* ip = (const BYTE*)src; + BYTE* op = (BYTE*)dst; + DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, + (unsigned)zc->blockState.matchState.nextToUpdate); + + { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + if (bss == ZSTDbss_noCompress) { + RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block"); + cSize = 0; + goto out; + } + } + + if (zc->seqCollector.collectSequences) { + FORWARD_IF_ERROR(ZSTD_copyBlockSequences(&zc->seqCollector, ZSTD_getSeqStore(zc), zc->blockState.prevCBlock->rep), "copyBlockSequences failed"); + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return 0; + } + + /* encode sequences and literals */ + cSize = ZSTD_entropyCompressSeqStore(&zc->seqStore, + &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + dst, dstCapacity, + srcSize, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */, + zc->bmi2); + + if (frame && + /* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + !zc->isFirstBlock && + cSize < rleMaxLength && + ZSTD_isRLE(ip, srcSize)) + { + cSize = 1; + op[0] = ip[0]; + } + +out: + if (!ZSTD_isError(cSize) && cSize > 1) { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + } + /* We check that dictionaries have offset codes available for the first + * block. After the first block, the offcode table might not have large + * enough codes to represent the offsets in the data. + */ + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const size_t bss, U32 lastBlock) +{ + DEBUGLOG(6, "Attempting ZSTD_compressSuperBlock()"); + if (bss == ZSTDbss_compress) { + if (/* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + !zc->isFirstBlock && + ZSTD_maybeRLE(&zc->seqStore) && + ZSTD_isRLE((BYTE const*)src, srcSize)) + { + return ZSTD_rleCompressBlock(dst, dstCapacity, *(BYTE const*)src, srcSize, lastBlock); + } + /* Attempt superblock compression. + * + * Note that compressed size of ZSTD_compressSuperBlock() is not bound by the + * standard ZSTD_compressBound(). This is a problem, because even if we have + * space now, taking an extra byte now could cause us to run out of space later + * and violate ZSTD_compressBound(). + * + * Define blockBound(blockSize) = blockSize + ZSTD_blockHeaderSize. + * + * In order to respect ZSTD_compressBound() we must attempt to emit a raw + * uncompressed block in these cases: + * * cSize == 0: Return code for an uncompressed block. + * * cSize == dstSize_tooSmall: We may have expanded beyond blockBound(srcSize). + * ZSTD_noCompressBlock() will return dstSize_tooSmall if we are really out of + * output space. + * * cSize >= blockBound(srcSize): We have expanded the block too much so + * emit an uncompressed block. + */ + { size_t const cSize = + ZSTD_compressSuperBlock(zc, dst, dstCapacity, src, srcSize, lastBlock); + if (cSize != ERROR(dstSize_tooSmall)) { + size_t const maxCSize = + srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed"); + if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return cSize; + } + } + } + } /* if (bss == ZSTDbss_compress)*/ + + DEBUGLOG(6, "Resorting to ZSTD_noCompressBlock()"); + /* Superblock compression failed, attempt to emit a single no compress block. + * The decoder will be able to stream this block since it is uncompressed. + */ + return ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock); +} + +static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastBlock) +{ + size_t cSize = 0; + const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + DEBUGLOG(5, "ZSTD_compressBlock_targetCBlockSize (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u, srcSize=%zu)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)zc->blockState.matchState.nextToUpdate, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + + cSize = ZSTD_compressBlock_targetCBlockSize_body(zc, dst, dstCapacity, src, srcSize, bss, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize_body failed"); + + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +static void ZSTD_overflowCorrectIfNeeded(ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + void const* ip, + void const* iend) +{ + U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy); + U32 const maxDist = (U32)1 << params->cParams.windowLog; + if (ZSTD_window_needOverflowCorrection(ms->window, cycleLog, maxDist, ms->loadedDictEnd, ip, iend)) { + U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip); + ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30); + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30); + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); + ZSTD_cwksp_mark_tables_dirty(ws); + ZSTD_reduceIndex(ms, params, correction); + ZSTD_cwksp_mark_tables_clean(ws); + if (ms->nextToUpdate < correction) ms->nextToUpdate = 0; + else ms->nextToUpdate -= correction; + /* invalidate dictionaries on overflow correction */ + ms->loadedDictEnd = 0; + ms->dictMatchState = NULL; + } +} + +#include "zstd_preSplit.h" + +static size_t ZSTD_optimalBlockSize(ZSTD_CCtx* cctx, const void* src, size_t srcSize, size_t blockSizeMax, int splitLevel, ZSTD_strategy strat, S64 savings) +{ + /* split level based on compression strategy, from `fast` to `btultra2` */ + static const int splitLevels[] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4 }; + /* note: conservatively only split full blocks (128 KB) currently. + * While it's possible to go lower, let's keep it simple for a first implementation. + * Besides, benefits of splitting are reduced when blocks are already small. + */ + if (srcSize < 128 KB || blockSizeMax < 128 KB) + return MIN(srcSize, blockSizeMax); + /* do not split incompressible data though: + * require verified savings to allow pre-splitting. + * Note: as a consequence, the first full block is not split. + */ + if (savings < 3) { + DEBUGLOG(6, "don't attempt splitting: savings (%i) too low", (int)savings); + return 128 KB; + } + /* apply @splitLevel, or use default value (which depends on @strat). + * note that splitting heuristic is still conditioned by @savings >= 3, + * so the first block will not reach this code path */ + if (splitLevel == 1) return 128 KB; + if (splitLevel == 0) { + assert(ZSTD_fast <= strat && strat <= ZSTD_btultra2); + splitLevel = splitLevels[strat]; + } else { + assert(2 <= splitLevel && splitLevel <= 6); + splitLevel -= 2; + } + return ZSTD_splitBlock(src, blockSizeMax, splitLevel, cctx->tmpWorkspace, cctx->tmpWkspSize); +} + +/*! ZSTD_compress_frameChunk() : +* Compress a chunk of data into one or multiple blocks. +* All blocks will be terminated, all input will be consumed. +* Function will issue an error if there is not enough `dstCapacity` to hold the compressed content. +* Frame is supposed already started (header already produced) +* @return : compressed size, or an error code +*/ +static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastFrameChunk) +{ + size_t blockSizeMax = cctx->blockSizeMax; + size_t remaining = srcSize; + const BYTE* ip = (const BYTE*)src; + BYTE* const ostart = (BYTE*)dst; + BYTE* op = ostart; + U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog; + S64 savings = (S64)cctx->consumedSrcSize - (S64)cctx->producedCSize; + + assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX); + + DEBUGLOG(5, "ZSTD_compress_frameChunk (srcSize=%u, blockSizeMax=%u)", (unsigned)srcSize, (unsigned)blockSizeMax); + if (cctx->appliedParams.fParams.checksumFlag && srcSize) + XXH64_update(&cctx->xxhState, src, srcSize); + + while (remaining) { + ZSTD_MatchState_t* const ms = &cctx->blockState.matchState; + size_t const blockSize = ZSTD_optimalBlockSize(cctx, + ip, remaining, + blockSizeMax, + cctx->appliedParams.preBlockSplitter_level, + cctx->appliedParams.cParams.strategy, + savings); + U32 const lastBlock = lastFrameChunk & (blockSize == remaining); + assert(blockSize <= remaining); + + /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding + * additional 1. We need to revisit and change this logic to be more consistent */ + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE + 1, + dstSize_tooSmall, + "not enough space to store compressed block"); + + ZSTD_overflowCorrectIfNeeded( + ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize); + ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); + ZSTD_window_enforceMaxDist(&ms->window, ip, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); + + /* Ensure hash/chain table insertion resumes no sooner than lowlimit */ + if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit; + + { size_t cSize; + if (ZSTD_useTargetCBlockSize(&cctx->appliedParams)) { + cSize = ZSTD_compressBlock_targetCBlockSize(cctx, op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize failed"); + assert(cSize > 0); + assert(cSize <= blockSize + ZSTD_blockHeaderSize); + } else if (ZSTD_blockSplitterEnabled(&cctx->appliedParams)) { + cSize = ZSTD_compressBlock_splitBlock(cctx, op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_splitBlock failed"); + assert(cSize > 0 || cctx->seqCollector.collectSequences == 1); + } else { + cSize = ZSTD_compressBlock_internal(cctx, + op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, + ip, blockSize, 1 /* frame */); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_internal failed"); + + if (cSize == 0) { /* block is not compressible */ + cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + } else { + U32 const cBlockHeader = cSize == 1 ? + lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) : + lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(op, cBlockHeader); + cSize += ZSTD_blockHeaderSize; + } + } /* if (ZSTD_useTargetCBlockSize(&cctx->appliedParams))*/ + + /* @savings is employed to ensure that splitting doesn't worsen expansion of incompressible data. + * Without splitting, the maximum expansion is 3 bytes per full block. + * An adversarial input could attempt to fudge the split detector, + * and make it split incompressible data, resulting in more block headers. + * Note that, since ZSTD_COMPRESSBOUND() assumes a worst case scenario of 1KB per block, + * and the splitter never creates blocks that small (current lower limit is 8 KB), + * there is already no risk to expand beyond ZSTD_COMPRESSBOUND() limit. + * But if the goal is to not expand by more than 3-bytes per 128 KB full block, + * then yes, it becomes possible to make the block splitter oversplit incompressible data. + * Using @savings, we enforce an even more conservative condition, + * requiring the presence of enough savings (at least 3 bytes) to authorize splitting, + * otherwise only full blocks are used. + * But being conservative is fine, + * since splitting barely compressible blocks is not fruitful anyway */ + savings += (S64)blockSize - (S64)cSize; + + ip += blockSize; + assert(remaining >= blockSize); + remaining -= blockSize; + op += cSize; + assert(dstCapacity >= cSize); + dstCapacity -= cSize; + cctx->isFirstBlock = 0; + DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u", + (unsigned)cSize); + } } + + if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending; + return (size_t)(op-ostart); +} + + +static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize, U32 dictID) +{ + BYTE* const op = (BYTE*)dst; + U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */ + U32 const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */ + U32 const checksumFlag = params->fParams.checksumFlag>0; + U32 const windowSize = (U32)1 << params->cParams.windowLog; + U32 const singleSegment = params->fParams.contentSizeFlag && (windowSize >= pledgedSrcSize); + BYTE const windowLogByte = (BYTE)((params->cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3); + U32 const fcsCode = params->fParams.contentSizeFlag ? + (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0; /* 0-3 */ + BYTE const frameHeaderDescriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) ); + size_t pos=0; + + assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)); + RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall, + "dst buf is too small to fit worst-case frame header size."); + DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u", + !params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode); + if (params->format == ZSTD_f_zstd1) { + MEM_writeLE32(dst, ZSTD_MAGICNUMBER); + pos = 4; + } + op[pos++] = frameHeaderDescriptionByte; + if (!singleSegment) op[pos++] = windowLogByte; + switch(dictIDSizeCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : break; + case 1 : op[pos] = (BYTE)(dictID); pos++; break; + case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break; + case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break; + } + switch(fcsCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break; + case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break; + case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break; + case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break; + } + return pos; +} + +/* ZSTD_writeSkippableFrame_advanced() : + * Writes out a skippable frame with the specified magic number variant (16 are supported), + * from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15, and the desired source data. + * + * Returns the total number of bytes written, or a ZSTD error code. + */ +size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, unsigned magicVariant) { + BYTE* op = (BYTE*)dst; + RETURN_ERROR_IF(dstCapacity < srcSize + ZSTD_SKIPPABLEHEADERSIZE /* Skippable frame overhead */, + dstSize_tooSmall, "Not enough room for skippable frame"); + RETURN_ERROR_IF(srcSize > (unsigned)0xFFFFFFFF, srcSize_wrong, "Src size too large for skippable frame"); + RETURN_ERROR_IF(magicVariant > 15, parameter_outOfBound, "Skippable frame magic number variant not supported"); + + MEM_writeLE32(op, (U32)(ZSTD_MAGIC_SKIPPABLE_START + magicVariant)); + MEM_writeLE32(op+4, (U32)srcSize); + ZSTD_memcpy(op+8, src, srcSize); + return srcSize + ZSTD_SKIPPABLEHEADERSIZE; +} + +/* ZSTD_writeLastEmptyBlock() : + * output an empty Block with end-of-frame mark to complete a frame + * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h)) + * or an error code if `dstCapacity` is too small (stage == ZSTDcs_init); + assert(nbSeq == 0 || cctx->appliedParams.ldmParams.enableLdm != ZSTD_ps_enable); + cctx->externSeqStore.seq = seq; + cctx->externSeqStore.size = nbSeq; + cctx->externSeqStore.capacity = nbSeq; + cctx->externSeqStore.pos = 0; + cctx->externSeqStore.posInSequence = 0; +} + + +static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 frame, U32 lastFrameChunk) +{ + ZSTD_MatchState_t* const ms = &cctx->blockState.matchState; + size_t fhSize = 0; + + DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u", + cctx->stage, (unsigned)srcSize); + RETURN_ERROR_IF(cctx->stage==ZSTDcs_created, stage_wrong, + "missing init (ZSTD_compressBegin)"); + + if (frame && (cctx->stage==ZSTDcs_init)) { + fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, + cctx->pledgedSrcSizePlusOne-1, cctx->dictID); + FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed"); + assert(fhSize <= dstCapacity); + dstCapacity -= fhSize; + dst = (char*)dst + fhSize; + cctx->stage = ZSTDcs_ongoing; + } + + if (!srcSize) return fhSize; /* do not generate an empty block if no input */ + + if (!ZSTD_window_update(&ms->window, src, srcSize, ms->forceNonContiguous)) { + ms->forceNonContiguous = 0; + ms->nextToUpdate = ms->window.dictLimit; + } + if (cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { + ZSTD_window_update(&cctx->ldmState.window, src, srcSize, /* forceNonContiguous */ 0); + } + + if (!frame) { + /* overflow check and correction for block mode */ + ZSTD_overflowCorrectIfNeeded( + ms, &cctx->workspace, &cctx->appliedParams, + src, (BYTE const*)src + srcSize); + } + + DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSizeMax); + { size_t const cSize = frame ? + ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) : + ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */); + FORWARD_IF_ERROR(cSize, "%s", frame ? "ZSTD_compress_frameChunk failed" : "ZSTD_compressBlock_internal failed"); + cctx->consumedSrcSize += srcSize; + cctx->producedCSize += (cSize + fhSize); + assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); + if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); + RETURN_ERROR_IF( + cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne, + srcSize_wrong, + "error : pledgedSrcSize = %u, while realSrcSize >= %u", + (unsigned)cctx->pledgedSrcSizePlusOne-1, + (unsigned)cctx->consumedSrcSize); + } + return cSize + fhSize; + } +} + +size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressContinue (srcSize=%u)", (unsigned)srcSize); + return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */); +} + +/* NOTE: Must just wrap ZSTD_compressContinue_public() */ +size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_compressContinue_public(cctx, dst, dstCapacity, src, srcSize); +} + +static size_t ZSTD_getBlockSize_deprecated(const ZSTD_CCtx* cctx) +{ + ZSTD_compressionParameters const cParams = cctx->appliedParams.cParams; + assert(!ZSTD_checkCParams(cParams)); + return MIN(cctx->appliedParams.maxBlockSize, (size_t)1 << cParams.windowLog); +} + +/* NOTE: Must just wrap ZSTD_getBlockSize_deprecated() */ +size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx) +{ + return ZSTD_getBlockSize_deprecated(cctx); +} + +/* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */ +size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize); + { size_t const blockSizeMax = ZSTD_getBlockSize_deprecated(cctx); + RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong, "input is larger than a block"); } + + return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */); +} + +/* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */ +size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_deprecated(cctx, dst, dstCapacity, src, srcSize); +} + +/*! ZSTD_loadDictionaryContent() : + * @return : 0, or an error code + */ +static size_t +ZSTD_loadDictionaryContent(ZSTD_MatchState_t* ms, + ldmState_t* ls, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + const void* src, size_t srcSize, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + const BYTE* ip = (const BYTE*) src; + const BYTE* const iend = ip + srcSize; + int const loadLdmDict = params->ldmParams.enableLdm == ZSTD_ps_enable && ls != NULL; + + /* Assert that the ms params match the params we're being given */ + ZSTD_assertEqualCParams(params->cParams, ms->cParams); + + { /* Ensure large dictionaries can't cause index overflow */ + + /* Allow the dictionary to set indices up to exactly ZSTD_CURRENT_MAX. + * Dictionaries right at the edge will immediately trigger overflow + * correction, but I don't want to insert extra constraints here. + */ + U32 maxDictSize = ZSTD_CURRENT_MAX - ZSTD_WINDOW_START_INDEX; + + int const CDictTaggedIndices = ZSTD_CDictIndicesAreTagged(¶ms->cParams); + if (CDictTaggedIndices && tfp == ZSTD_tfp_forCDict) { + /* Some dictionary matchfinders in zstd use "short cache", + * which treats the lower ZSTD_SHORT_CACHE_TAG_BITS of each + * CDict hashtable entry as a tag rather than as part of an index. + * When short cache is used, we need to truncate the dictionary + * so that its indices don't overlap with the tag. */ + U32 const shortCacheMaxDictSize = (1u << (32 - ZSTD_SHORT_CACHE_TAG_BITS)) - ZSTD_WINDOW_START_INDEX; + maxDictSize = MIN(maxDictSize, shortCacheMaxDictSize); + assert(!loadLdmDict); + } + + /* If the dictionary is too large, only load the suffix of the dictionary. */ + if (srcSize > maxDictSize) { + ip = iend - maxDictSize; + src = ip; + srcSize = maxDictSize; + } + } + + if (srcSize > ZSTD_CHUNKSIZE_MAX) { + /* We must have cleared our windows when our source is this large. */ + assert(ZSTD_window_isEmpty(ms->window)); + if (loadLdmDict) assert(ZSTD_window_isEmpty(ls->window)); + } + ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0); + + DEBUGLOG(4, "ZSTD_loadDictionaryContent: useRowMatchFinder=%d", (int)params->useRowMatchFinder); + + if (loadLdmDict) { /* Load the entire dict into LDM matchfinders. */ + DEBUGLOG(4, "ZSTD_loadDictionaryContent: Trigger loadLdmDict"); + ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0); + ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base); + ZSTD_ldm_fillHashTable(ls, ip, iend, ¶ms->ldmParams); + DEBUGLOG(4, "ZSTD_loadDictionaryContent: ZSTD_ldm_fillHashTable completes"); + } + + /* If the dict is larger than we can reasonably index in our tables, only load the suffix. */ + { U32 maxDictSize = 1U << MIN(MAX(params->cParams.hashLog + 3, params->cParams.chainLog + 1), 31); + if (srcSize > maxDictSize) { + ip = iend - maxDictSize; + src = ip; + srcSize = maxDictSize; + } + } + + ms->nextToUpdate = (U32)(ip - ms->window.base); + ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base); + ms->forceNonContiguous = params->deterministicRefPrefix; + + if (srcSize <= HASH_READ_SIZE) return 0; + + ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, iend); + + switch(params->cParams.strategy) + { + case ZSTD_fast: + ZSTD_fillHashTable(ms, iend, dtlm, tfp); + break; + case ZSTD_dfast: +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + ZSTD_fillDoubleHashTable(ms, iend, dtlm, tfp); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) + assert(srcSize >= HASH_READ_SIZE); + if (ms->dedicatedDictSearch) { + assert(ms->chainTable != NULL); + ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, iend-HASH_READ_SIZE); + } else { + assert(params->useRowMatchFinder != ZSTD_ps_auto); + if (params->useRowMatchFinder == ZSTD_ps_enable) { + size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog); + ZSTD_memset(ms->tagTable, 0, tagTableSize); + ZSTD_row_update(ms, iend-HASH_READ_SIZE); + DEBUGLOG(4, "Using row-based hash table for lazy dict"); + } else { + ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE); + DEBUGLOG(4, "Using chain-based hash table for lazy dict"); + } + } +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_btlazy2: /* we want the dictionary table fully sorted */ + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) + assert(srcSize >= HASH_READ_SIZE); + DEBUGLOG(4, "Fill %u bytes into the Binary Tree", (unsigned)srcSize); + ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + default: + assert(0); /* not possible : not a valid strategy id */ + } + + ms->nextToUpdate = (U32)(iend - ms->window.base); + return 0; +} + + +/* Dictionaries that assign zero probability to symbols that show up causes problems + * when FSE encoding. Mark dictionaries with zero probability symbols as FSE_repeat_check + * and only dictionaries with 100% valid symbols can be assumed valid. + */ +static FSE_repeat ZSTD_dictNCountRepeat(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) +{ + U32 s; + if (dictMaxSymbolValue < maxSymbolValue) { + return FSE_repeat_check; + } + for (s = 0; s <= maxSymbolValue; ++s) { + if (normalizedCounter[s] == 0) { + return FSE_repeat_check; + } + } + return FSE_repeat_valid; +} + +size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, + const void* const dict, size_t dictSize) +{ + short offcodeNCount[MaxOff+1]; + unsigned offcodeMaxValue = MaxOff; + const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */ + const BYTE* const dictEnd = dictPtr + dictSize; + dictPtr += 8; + bs->entropy.huf.repeatMode = HUF_repeat_check; + + { unsigned maxSymbolValue = 255; + unsigned hasZeroWeights = 1; + size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, + (size_t)(dictEnd-dictPtr), &hasZeroWeights); + + /* We only set the loaded table as valid if it contains all non-zero + * weights. Otherwise, we set it to check */ + if (!hasZeroWeights && maxSymbolValue == 255) + bs->entropy.huf.repeatMode = HUF_repeat_valid; + + RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted, ""); + dictPtr += hufHeaderSize; + } + + { unsigned offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); + /* fill all offset symbols to avoid garbage at end of table */ + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.offcodeCTable, + offcodeNCount, MaxOff, offcodeLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ + dictPtr += offcodeHeaderSize; + } + + { short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.matchlengthCTable, + matchlengthNCount, matchlengthMaxValue, matchlengthLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + bs->entropy.fse.matchlength_repeatMode = ZSTD_dictNCountRepeat(matchlengthNCount, matchlengthMaxValue, MaxML); + dictPtr += matchlengthHeaderSize; + } + + { short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.litlengthCTable, + litlengthNCount, litlengthMaxValue, litlengthLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + bs->entropy.fse.litlength_repeatMode = ZSTD_dictNCountRepeat(litlengthNCount, litlengthMaxValue, MaxLL); + dictPtr += litlengthHeaderSize; + } + + RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, ""); + bs->rep[0] = MEM_readLE32(dictPtr+0); + bs->rep[1] = MEM_readLE32(dictPtr+4); + bs->rep[2] = MEM_readLE32(dictPtr+8); + dictPtr += 12; + + { size_t const dictContentSize = (size_t)(dictEnd - dictPtr); + U32 offcodeMax = MaxOff; + if (dictContentSize <= ((U32)-1) - 128 KB) { + U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */ + offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */ + } + /* All offset values <= dictContentSize + 128 KB must be representable for a valid table */ + bs->entropy.fse.offcode_repeatMode = ZSTD_dictNCountRepeat(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)); + + /* All repCodes must be <= dictContentSize and != 0 */ + { U32 u; + for (u=0; u<3; u++) { + RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, ""); + RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, ""); + } } } + + return (size_t)(dictPtr - (const BYTE*)dict); +} + +/* Dictionary format : + * See : + * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#dictionary-format + */ +/*! ZSTD_loadZstdDictionary() : + * @return : dictID, or an error code + * assumptions : magic number supposed already checked + * dictSize supposed >= 8 + */ +static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, + ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + const void* dict, size_t dictSize, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp, + void* workspace) +{ + const BYTE* dictPtr = (const BYTE*)dict; + const BYTE* const dictEnd = dictPtr + dictSize; + size_t dictID; + size_t eSize; + ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<= 8); + assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY); + + dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr + 4 /* skip magic number */ ); + eSize = ZSTD_loadCEntropy(bs, workspace, dict, dictSize); + FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed"); + dictPtr += eSize; + + { + size_t const dictContentSize = (size_t)(dictEnd - dictPtr); + FORWARD_IF_ERROR(ZSTD_loadDictionaryContent( + ms, NULL, ws, params, dictPtr, dictContentSize, dtlm, tfp), ""); + } + return dictID; +} + +/** ZSTD_compress_insertDictionary() : +* @return : dictID, or an error code */ +static size_t +ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, + ZSTD_MatchState_t* ms, + ldmState_t* ls, + ZSTD_cwksp* ws, + const ZSTD_CCtx_params* params, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp, + void* workspace) +{ + DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize); + if ((dict==NULL) || (dictSize<8)) { + RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, ""); + return 0; + } + + ZSTD_reset_compressedBlockState(bs); + + /* dict restricted modes */ + if (dictContentType == ZSTD_dct_rawContent) + return ZSTD_loadDictionaryContent(ms, ls, ws, params, dict, dictSize, dtlm, tfp); + + if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) { + if (dictContentType == ZSTD_dct_auto) { + DEBUGLOG(4, "raw content dictionary detected"); + return ZSTD_loadDictionaryContent( + ms, ls, ws, params, dict, dictSize, dtlm, tfp); + } + RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, ""); + assert(0); /* impossible */ + } + + /* dict as full zstd dictionary */ + return ZSTD_loadZstdDictionary( + bs, ms, ws, params, dict, dictSize, dtlm, tfp, workspace); +} + +#define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB) +#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6ULL) + +/*! ZSTD_compressBegin_internal() : + * Assumption : either @dict OR @cdict (or none) is non-NULL, never both + * @return : 0, or an error code */ +static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + size_t const dictContentSize = cdict ? cdict->dictContentSize : dictSize; +#if ZSTD_TRACE + cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0; +#endif + DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog); + /* params are supposed to be fully validated at this point */ + assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); + assert(!((dict) && (cdict))); /* either dict or cdict, not both */ + if ( (cdict) + && (cdict->dictContentSize > 0) + && ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF + || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || cdict->compressionLevel == 0) + && (params->attachDictPref != ZSTD_dictForceLoad) ) { + return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff); + } + + FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, + dictContentSize, + ZSTDcrp_makeClean, zbuff) , ""); + { size_t const dictID = cdict ? + ZSTD_compress_insertDictionary( + cctx->blockState.prevCBlock, &cctx->blockState.matchState, + &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent, + cdict->dictContentSize, cdict->dictContentType, dtlm, + ZSTD_tfp_forCCtx, cctx->tmpWorkspace) + : ZSTD_compress_insertDictionary( + cctx->blockState.prevCBlock, &cctx->blockState.matchState, + &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize, + dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->tmpWorkspace); + FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed"); + assert(dictID <= UINT_MAX); + cctx->dictID = (U32)dictID; + cctx->dictContentSize = dictContentSize; + } + return 0; +} + +size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params->cParams.windowLog); + /* compression parameters verification and optimization */ + FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) , ""); + return ZSTD_compressBegin_internal(cctx, + dict, dictSize, dictContentType, dtlm, + cdict, + params, pledgedSrcSize, + ZSTDb_not_buffered); +} + +/*! ZSTD_compressBegin_advanced() : +* @return : 0, or an error code */ +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_parameters params, unsigned long long pledgedSrcSize) +{ + ZSTD_CCtx_params cctxParams; + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, ZSTD_NO_CLEVEL); + return ZSTD_compressBegin_advanced_internal(cctx, + dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, + NULL /*cdict*/, + &cctxParams, pledgedSrcSize); +} + +static size_t +ZSTD_compressBegin_usingDict_deprecated(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_CCtx_params cctxParams; + { ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict); + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel); + } + DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered); +} + +size_t +ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) +{ + return ZSTD_compressBegin_usingDict_deprecated(cctx, dict, dictSize, compressionLevel); +} + +size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel) +{ + return ZSTD_compressBegin_usingDict_deprecated(cctx, NULL, 0, compressionLevel); +} + + +/*! ZSTD_writeEpilogue() : +* Ends a frame. +* @return : nb of bytes written into dst (or an error code) */ +static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity) +{ + BYTE* const ostart = (BYTE*)dst; + BYTE* op = ostart; + + DEBUGLOG(4, "ZSTD_writeEpilogue"); + RETURN_ERROR_IF(cctx->stage == ZSTDcs_created, stage_wrong, "init missing"); + + /* special case : empty frame */ + if (cctx->stage == ZSTDcs_init) { + size_t fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0); + FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed"); + dstCapacity -= fhSize; + op += fhSize; + cctx->stage = ZSTDcs_ongoing; + } + + if (cctx->stage != ZSTDcs_ending) { + /* write one last empty block, make it the "last" block */ + U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0; + ZSTD_STATIC_ASSERT(ZSTD_BLOCKHEADERSIZE == 3); + RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "no room for epilogue"); + MEM_writeLE24(op, cBlockHeader24); + op += ZSTD_blockHeaderSize; + dstCapacity -= ZSTD_blockHeaderSize; + } + + if (cctx->appliedParams.fParams.checksumFlag) { + U32 const checksum = (U32) XXH64_digest(&cctx->xxhState); + RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum"); + DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum); + MEM_writeLE32(op, checksum); + op += 4; + } + + cctx->stage = ZSTDcs_created; /* return to "created but no init" status */ + return (size_t)(op-ostart); +} + +void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize) +{ +#if ZSTD_TRACE + if (cctx->traceCtx && ZSTD_trace_compress_end != NULL) { + int const streaming = cctx->inBuffSize > 0 || cctx->outBuffSize > 0 || cctx->appliedParams.nbWorkers > 0; + ZSTD_Trace trace; + ZSTD_memset(&trace, 0, sizeof(trace)); + trace.version = ZSTD_VERSION_NUMBER; + trace.streaming = streaming; + trace.dictionaryID = cctx->dictID; + trace.dictionarySize = cctx->dictContentSize; + trace.uncompressedSize = cctx->consumedSrcSize; + trace.compressedSize = cctx->producedCSize + extraCSize; + trace.params = &cctx->appliedParams; + trace.cctx = cctx; + ZSTD_trace_compress_end(cctx->traceCtx, &trace); + } + cctx->traceCtx = 0; +#else + (void)cctx; + (void)extraCSize; +#endif +} + +size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + size_t endResult; + size_t const cSize = ZSTD_compressContinue_internal(cctx, + dst, dstCapacity, src, srcSize, + 1 /* frame mode */, 1 /* last chunk */); + FORWARD_IF_ERROR(cSize, "ZSTD_compressContinue_internal failed"); + endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); + FORWARD_IF_ERROR(endResult, "ZSTD_writeEpilogue failed"); + assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); + if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); + DEBUGLOG(4, "end of frame : controlling src size"); + RETURN_ERROR_IF( + cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1, + srcSize_wrong, + "error : pledgedSrcSize = %u, while realSrcSize = %u", + (unsigned)cctx->pledgedSrcSizePlusOne-1, + (unsigned)cctx->consumedSrcSize); + } + ZSTD_CCtx_trace(cctx, endResult); + return cSize + endResult; +} + +/* NOTE: Must just wrap ZSTD_compressEnd_public() */ +size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + ZSTD_parameters params) +{ + DEBUGLOG(4, "ZSTD_compress_advanced"); + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + ZSTD_CCtxParams_init_internal(&cctx->simpleApiParams, ¶ms, ZSTD_NO_CLEVEL); + return ZSTD_compress_advanced_internal(cctx, + dst, dstCapacity, + src, srcSize, + dict, dictSize, + &cctx->simpleApiParams); +} + +/* Internal */ +size_t ZSTD_compress_advanced_internal( + ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + const ZSTD_CCtx_params* params) +{ + DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize); + FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx, + dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, + params, srcSize, ZSTDb_not_buffered) , ""); + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel) +{ + { + ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict); + assert(params.fParams.contentSizeFlag == 1); + ZSTD_CCtxParams_init_internal(&cctx->simpleApiParams, ¶ms, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT: compressionLevel); + } + DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize); + return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctx->simpleApiParams); +} + +size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel) +{ + DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (unsigned)srcSize); + assert(cctx != NULL); + return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel); +} + +size_t ZSTD_compress(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel) +{ + size_t result; +#if ZSTD_COMPRESS_HEAPMODE + ZSTD_CCtx* cctx = ZSTD_createCCtx(); + RETURN_ERROR_IF(!cctx, memory_allocation, "ZSTD_createCCtx failed"); + result = ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel); + ZSTD_freeCCtx(cctx); +#else + ZSTD_CCtx ctxBody; + ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem); + result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel); + ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */ +#endif + return result; +} + + +/* ===== Dictionary API ===== */ + +/*! ZSTD_estimateCDictSize_advanced() : + * Estimate amount of memory that will be needed to create a dictionary with following arguments */ +size_t ZSTD_estimateCDictSize_advanced( + size_t dictSize, ZSTD_compressionParameters cParams, + ZSTD_dictLoadMethod_e dictLoadMethod) +{ + DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict)); + return ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + /* enableDedicatedDictSearch == 1 ensures that CDict estimation will not be too small + * in case we are using DDS with row-hash. */ + + ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams), + /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *)))); +} + +size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy); +} + +size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; /* support sizeof on NULL */ + DEBUGLOG(5, "sizeof(*cdict) : %u", (unsigned)sizeof(*cdict)); + /* cdict may be in the workspace */ + return (cdict->workspace.workspace == cdict ? 0 : sizeof(*cdict)) + + ZSTD_cwksp_sizeof(&cdict->workspace); +} + +static size_t ZSTD_initCDict_internal( + ZSTD_CDict* cdict, + const void* dictBuffer, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_CCtx_params params) +{ + DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (unsigned)dictContentType); + assert(!ZSTD_checkCParams(params.cParams)); + cdict->matchState.cParams = params.cParams; + cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch; + if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) { + cdict->dictContent = dictBuffer; + } else { + void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*))); + RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!"); + cdict->dictContent = internalBuffer; + ZSTD_memcpy(internalBuffer, dictBuffer, dictSize); + } + cdict->dictContentSize = dictSize; + cdict->dictContentType = dictContentType; + + cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE); + + + /* Reset the state to no dictionary */ + ZSTD_reset_compressedBlockState(&cdict->cBlockState); + FORWARD_IF_ERROR(ZSTD_reset_matchState( + &cdict->matchState, + &cdict->workspace, + ¶ms.cParams, + params.useRowMatchFinder, + ZSTDcrp_makeClean, + ZSTDirp_reset, + ZSTD_resetTarget_CDict), ""); + /* (Maybe) load the dictionary + * Skips loading the dictionary if it is < 8 bytes. + */ + { params.compressionLevel = ZSTD_CLEVEL_DEFAULT; + params.fParams.contentSizeFlag = 1; + { size_t const dictID = ZSTD_compress_insertDictionary( + &cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace, + ¶ms, cdict->dictContent, cdict->dictContentSize, + dictContentType, ZSTD_dtlm_full, ZSTD_tfp_forCDict, cdict->entropyWorkspace); + FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed"); + assert(dictID <= (size_t)(U32)-1); + cdict->dictID = (U32)dictID; + } + } + + return 0; +} + +static ZSTD_CDict* +ZSTD_createCDict_advanced_internal(size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_compressionParameters cParams, + ZSTD_ParamSwitch_e useRowMatchFinder, + int enableDedicatedDictSearch, + ZSTD_customMem customMem) +{ + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + DEBUGLOG(3, "ZSTD_createCDict_advanced_internal (dictSize=%u)", (unsigned)dictSize); + + { size_t const workspaceSize = + ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + + ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, enableDedicatedDictSearch, /* forCCtx */ 0) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))); + void* const workspace = ZSTD_customMalloc(workspaceSize, customMem); + ZSTD_cwksp ws; + ZSTD_CDict* cdict; + + if (!workspace) { + ZSTD_customFree(workspace, customMem); + return NULL; + } + + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_dynamic_alloc); + + cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); + assert(cdict != NULL); + ZSTD_cwksp_move(&cdict->workspace, &ws); + cdict->customMem = customMem; + cdict->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */ + cdict->useRowMatchFinder = useRowMatchFinder; + return cdict; + } +} + +ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams, + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params cctxParams; + ZSTD_memset(&cctxParams, 0, sizeof(cctxParams)); + DEBUGLOG(3, "ZSTD_createCDict_advanced, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType); + ZSTD_CCtxParams_init(&cctxParams, 0); + cctxParams.cParams = cParams; + cctxParams.customMem = customMem; + return ZSTD_createCDict_advanced2( + dictBuffer, dictSize, + dictLoadMethod, dictContentType, + &cctxParams, customMem); +} + +ZSTD_CDict* ZSTD_createCDict_advanced2( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + const ZSTD_CCtx_params* originalCctxParams, + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params cctxParams = *originalCctxParams; + ZSTD_compressionParameters cParams; + ZSTD_CDict* cdict; + + DEBUGLOG(3, "ZSTD_createCDict_advanced2, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType); + if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + + if (cctxParams.enableDedicatedDictSearch) { + cParams = ZSTD_dedicatedDictSearch_getCParams( + cctxParams.compressionLevel, dictSize); + ZSTD_overrideCParams(&cParams, &cctxParams.cParams); + } else { + cParams = ZSTD_getCParamsFromCCtxParams( + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + } + + if (!ZSTD_dedicatedDictSearch_isSupported(&cParams)) { + /* Fall back to non-DDSS params */ + cctxParams.enableDedicatedDictSearch = 0; + cParams = ZSTD_getCParamsFromCCtxParams( + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + } + + DEBUGLOG(3, "ZSTD_createCDict_advanced2: DedicatedDictSearch=%u", cctxParams.enableDedicatedDictSearch); + cctxParams.cParams = cParams; + cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); + + cdict = ZSTD_createCDict_advanced_internal(dictSize, + dictLoadMethod, cctxParams.cParams, + cctxParams.useRowMatchFinder, cctxParams.enableDedicatedDictSearch, + customMem); + + if (!cdict || ZSTD_isError( ZSTD_initCDict_internal(cdict, + dict, dictSize, + dictLoadMethod, dictContentType, + cctxParams) )) { + ZSTD_freeCDict(cdict); + return NULL; + } + + return cdict; +} + +ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_dlm_byCopy, ZSTD_dct_auto, + cParams, ZSTD_defaultCMem); + if (cdict) + cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel; + return cdict; +} + +ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_dlm_byRef, ZSTD_dct_auto, + cParams, ZSTD_defaultCMem); + if (cdict) + cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel; + return cdict; +} + +size_t ZSTD_freeCDict(ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; /* support free on NULL */ + { ZSTD_customMem const cMem = cdict->customMem; + int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict); + ZSTD_cwksp_free(&cdict->workspace, cMem); + if (!cdictInWorkspace) { + ZSTD_customFree(cdict, cMem); + } + return 0; + } +} + +/*! ZSTD_initStaticCDict_advanced() : + * Generate a digested dictionary in provided memory area. + * workspace: The memory area to emplace the dictionary into. + * Provided pointer must 8-bytes aligned. + * It must outlive dictionary usage. + * workspaceSize: Use ZSTD_estimateCDictSize() + * to determine how large workspace must be. + * cParams : use ZSTD_getCParams() to transform a compression level + * into its relevant cParams. + * @return : pointer to ZSTD_CDict*, or NULL if error (size too small) + * Note : there is no corresponding "free" function. + * Since workspace was allocated externally, it must be freed externally. + */ +const ZSTD_CDict* ZSTD_initStaticCDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams) +{ + ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams); + /* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */ + size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0); + size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + + matchStateSize; + ZSTD_CDict* cdict; + ZSTD_CCtx_params params; + + DEBUGLOG(4, "ZSTD_initStaticCDict (dictSize==%u)", (unsigned)dictSize); + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + + { + ZSTD_cwksp ws; + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc); + cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); + if (cdict == NULL) return NULL; + ZSTD_cwksp_move(&cdict->workspace, &ws); + } + + if (workspaceSize < neededSize) return NULL; + + ZSTD_CCtxParams_init(¶ms, 0); + params.cParams = cParams; + params.useRowMatchFinder = useRowMatchFinder; + cdict->useRowMatchFinder = useRowMatchFinder; + cdict->compressionLevel = ZSTD_NO_CLEVEL; + + if (ZSTD_isError( ZSTD_initCDict_internal(cdict, + dict, dictSize, + dictLoadMethod, dictContentType, + params) )) + return NULL; + + return cdict; +} + +ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict) +{ + assert(cdict != NULL); + return cdict->matchState.cParams; +} + +/*! ZSTD_getDictID_fromCDict() : + * Provides the dictID of the dictionary loaded into `cdict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; + return cdict->dictID; +} + +/* ZSTD_compressBegin_usingCDict_internal() : + * Implementation of various ZSTD_compressBegin_usingCDict* functions. + */ +static size_t ZSTD_compressBegin_usingCDict_internal( + ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, + ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) +{ + ZSTD_CCtx_params cctxParams; + DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_internal"); + RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!"); + /* Initialize the cctxParams from the cdict */ + { + ZSTD_parameters params; + params.fParams = fParams; + params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF + || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || cdict->compressionLevel == 0 ) ? + ZSTD_getCParamsFromCDict(cdict) + : ZSTD_getCParams(cdict->compressionLevel, + pledgedSrcSize, + cdict->dictContentSize); + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, cdict->compressionLevel); + } + /* Increase window log to fit the entire dictionary and source if the + * source size is known. Limit the increase to 19, which is the + * window log for compression level 1 with the largest source size. + */ + if (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN) { + U32 const limitedSrcSize = (U32)MIN(pledgedSrcSize, 1U << 19); + U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1; + cctxParams.cParams.windowLog = MAX(cctxParams.cParams.windowLog, limitedSrcLog); + } + return ZSTD_compressBegin_internal(cctx, + NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, + cdict, + &cctxParams, pledgedSrcSize, + ZSTDb_not_buffered); +} + + +/* ZSTD_compressBegin_usingCDict_advanced() : + * This function is DEPRECATED. + * cdict must be != NULL */ +size_t ZSTD_compressBegin_usingCDict_advanced( + ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, + ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) +{ + return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, pledgedSrcSize); +} + +/* ZSTD_compressBegin_usingCDict() : + * cdict must be != NULL */ +size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); +} + +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + return ZSTD_compressBegin_usingCDict_deprecated(cctx, cdict); +} + +/*! ZSTD_compress_usingCDict_internal(): + * Implementation of various ZSTD_compress_usingCDict* functions. + */ +static size_t ZSTD_compress_usingCDict_internal(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, ZSTD_frameParameters fParams) +{ + FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */ + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +/*! ZSTD_compress_usingCDict_advanced(): + * This function is DEPRECATED. + */ +size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, ZSTD_frameParameters fParams) +{ + return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams); +} + +/*! ZSTD_compress_usingCDict() : + * Compression using a digested Dictionary. + * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. + * Note that compression parameters are decided at CDict creation time + * while frame parameters are hardcoded */ +size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict) +{ + ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams); +} + + + +/* ****************************************************************** +* Streaming +********************************************************************/ + +ZSTD_CStream* ZSTD_createCStream(void) +{ + DEBUGLOG(3, "ZSTD_createCStream"); + return ZSTD_createCStream_advanced(ZSTD_defaultCMem); +} + +ZSTD_CStream* ZSTD_initStaticCStream(void *workspace, size_t workspaceSize) +{ + return ZSTD_initStaticCCtx(workspace, workspaceSize); +} + +ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem) +{ /* CStream and CCtx are now same object */ + return ZSTD_createCCtx_advanced(customMem); +} + +size_t ZSTD_freeCStream(ZSTD_CStream* zcs) +{ + return ZSTD_freeCCtx(zcs); /* same object */ +} + + + +/*====== Initialization ======*/ + +size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX; } + +size_t ZSTD_CStreamOutSize(void) +{ + return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; +} + +static ZSTD_CParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize) +{ + if (cdict != NULL && ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) + return ZSTD_cpm_attachDict; + else + return ZSTD_cpm_noAttachDict; +} + +/* ZSTD_resetCStream(): + * pledgedSrcSize == 0 means "unknown" */ +size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pss) +{ + /* temporary : 0 interpreted as "unknown" during transition period. + * Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN. + * 0 will be interpreted as "empty" in the future. + */ + U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss; + DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (unsigned)pledgedSrcSize); + FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , ""); + return 0; +} + +/*! ZSTD_initCStream_internal() : + * Note : for lib/compress only. Used by zstdmt_compress.c. + * Assumption 1 : params are valid + * Assumption 2 : either dict, or cdict, is defined, not both */ +size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, + const void* dict, size_t dictSize, const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTD_initCStream_internal"); + FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , ""); + assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); + zcs->requestedParams = *params; + assert(!((dict) && (cdict))); /* either dict or cdict, not both */ + if (dict) { + FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , ""); + } else { + /* Dictionary is cleared if !cdict */ + FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , ""); + } + return 0; +} + +/* ZSTD_initCStream_usingCDict_advanced() : + * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */ +size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, + const ZSTD_CDict* cdict, + ZSTD_frameParameters fParams, + unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTD_initCStream_usingCDict_advanced"); + FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , ""); + zcs->requestedParams.fParams = fParams; + FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , ""); + return 0; +} + +/* note : cdict must outlive compression session */ +size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict) +{ + DEBUGLOG(4, "ZSTD_initCStream_usingCDict"); + FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , ""); + return 0; +} + + +/* ZSTD_initCStream_advanced() : + * pledgedSrcSize must be exact. + * if srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. + * dict is loaded with default parameters ZSTD_dct_auto and ZSTD_dlm_byCopy. */ +size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, + const void* dict, size_t dictSize, + ZSTD_parameters params, unsigned long long pss) +{ + /* for compatibility with older programs relying on this behavior. + * Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. + * This line will be removed in the future. + */ + U64 const pledgedSrcSize = (pss==0 && params.fParams.contentSizeFlag==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss; + DEBUGLOG(4, "ZSTD_initCStream_advanced"); + FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , ""); + FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , ""); + ZSTD_CCtxParams_setZstdParams(&zcs->requestedParams, ¶ms); + FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , ""); + return 0; +} + +size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel) +{ + DEBUGLOG(4, "ZSTD_initCStream_usingDict"); + FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , ""); + return 0; +} + +size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss) +{ + /* temporary : 0 interpreted as "unknown" during transition period. + * Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN. + * 0 will be interpreted as "empty" in the future. + */ + U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss; + DEBUGLOG(4, "ZSTD_initCStream_srcSize"); + FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , ""); + return 0; +} + +size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel) +{ + DEBUGLOG(4, "ZSTD_initCStream"); + FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) , ""); + FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , ""); + return 0; +} + +/*====== Compression ======*/ + +static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx) +{ + if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) { + return cctx->blockSizeMax - cctx->stableIn_notConsumed; + } + assert(cctx->appliedParams.inBufferMode == ZSTD_bm_buffered); + { size_t hintInSize = cctx->inBuffTarget - cctx->inBuffPos; + if (hintInSize==0) hintInSize = cctx->blockSizeMax; + return hintInSize; + } +} + +/** ZSTD_compressStream_generic(): + * internal function for all *compressStream*() variants + * @return : hint size for next input to complete ongoing block */ +static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective const flushMode) +{ + const char* const istart = (assert(input != NULL), (const char*)input->src); + const char* const iend = (istart != NULL) ? istart + input->size : istart; + const char* ip = (istart != NULL) ? istart + input->pos : istart; + char* const ostart = (assert(output != NULL), (char*)output->dst); + char* const oend = (ostart != NULL) ? ostart + output->size : ostart; + char* op = (ostart != NULL) ? ostart + output->pos : ostart; + U32 someMoreWork = 1; + + /* check expectations */ + DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%i, srcSize = %zu", (int)flushMode, input->size - input->pos); + assert(zcs != NULL); + if (zcs->appliedParams.inBufferMode == ZSTD_bm_stable) { + assert(input->pos >= zcs->stableIn_notConsumed); + input->pos -= zcs->stableIn_notConsumed; + if (ip) ip -= zcs->stableIn_notConsumed; + zcs->stableIn_notConsumed = 0; + } + if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) { + assert(zcs->inBuff != NULL); + assert(zcs->inBuffSize > 0); + } + if (zcs->appliedParams.outBufferMode == ZSTD_bm_buffered) { + assert(zcs->outBuff != NULL); + assert(zcs->outBuffSize > 0); + } + if (input->src == NULL) assert(input->size == 0); + assert(input->pos <= input->size); + if (output->dst == NULL) assert(output->size == 0); + assert(output->pos <= output->size); + assert((U32)flushMode <= (U32)ZSTD_e_end); + + while (someMoreWork) { + switch(zcs->streamStage) + { + case zcss_init: + RETURN_ERROR(init_missing, "call ZSTD_initCStream() first!"); + + case zcss_load: + if ( (flushMode == ZSTD_e_end) + && ( (size_t)(oend-op) >= ZSTD_compressBound((size_t)(iend-ip)) /* Enough output space */ + || zcs->appliedParams.outBufferMode == ZSTD_bm_stable) /* OR we are allowed to return dstSizeTooSmall */ + && (zcs->inBuffPos == 0) ) { + /* shortcut to compression pass directly into output buffer */ + size_t const cSize = ZSTD_compressEnd_public(zcs, + op, (size_t)(oend-op), + ip, (size_t)(iend-ip)); + DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize); + FORWARD_IF_ERROR(cSize, "ZSTD_compressEnd failed"); + ip = iend; + op += cSize; + zcs->frameEnded = 1; + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + someMoreWork = 0; break; + } + /* complete loading into inBuffer in buffered mode */ + if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) { + size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; + size_t const loaded = ZSTD_limitCopy( + zcs->inBuff + zcs->inBuffPos, toLoad, + ip, (size_t)(iend-ip)); + zcs->inBuffPos += loaded; + if (ip) ip += loaded; + if ( (flushMode == ZSTD_e_continue) + && (zcs->inBuffPos < zcs->inBuffTarget) ) { + /* not enough input to fill full block : stop here */ + someMoreWork = 0; break; + } + if ( (flushMode == ZSTD_e_flush) + && (zcs->inBuffPos == zcs->inToCompress) ) { + /* empty */ + someMoreWork = 0; break; + } + } else { + assert(zcs->appliedParams.inBufferMode == ZSTD_bm_stable); + if ( (flushMode == ZSTD_e_continue) + && ( (size_t)(iend - ip) < zcs->blockSizeMax) ) { + /* can't compress a full block : stop here */ + zcs->stableIn_notConsumed = (size_t)(iend - ip); + ip = iend; /* pretend to have consumed input */ + someMoreWork = 0; break; + } + if ( (flushMode == ZSTD_e_flush) + && (ip == iend) ) { + /* empty */ + someMoreWork = 0; break; + } + } + /* compress current block (note : this stage cannot be stopped in the middle) */ + DEBUGLOG(5, "stream compression stage (flushMode==%u)", flushMode); + { int const inputBuffered = (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered); + void* cDst; + size_t cSize; + size_t oSize = (size_t)(oend-op); + size_t const iSize = inputBuffered ? zcs->inBuffPos - zcs->inToCompress + : MIN((size_t)(iend - ip), zcs->blockSizeMax); + if (oSize >= ZSTD_compressBound(iSize) || zcs->appliedParams.outBufferMode == ZSTD_bm_stable) + cDst = op; /* compress into output buffer, to skip flush stage */ + else + cDst = zcs->outBuff, oSize = zcs->outBuffSize; + if (inputBuffered) { + unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend); + cSize = lastBlock ? + ZSTD_compressEnd_public(zcs, cDst, oSize, + zcs->inBuff + zcs->inToCompress, iSize) : + ZSTD_compressContinue_public(zcs, cDst, oSize, + zcs->inBuff + zcs->inToCompress, iSize); + FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed"); + zcs->frameEnded = lastBlock; + /* prepare next block */ + zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSizeMax; + if (zcs->inBuffTarget > zcs->inBuffSize) + zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSizeMax; + DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u", + (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize); + if (!lastBlock) + assert(zcs->inBuffTarget <= zcs->inBuffSize); + zcs->inToCompress = zcs->inBuffPos; + } else { /* !inputBuffered, hence ZSTD_bm_stable */ + unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip + iSize == iend); + cSize = lastBlock ? + ZSTD_compressEnd_public(zcs, cDst, oSize, ip, iSize) : + ZSTD_compressContinue_public(zcs, cDst, oSize, ip, iSize); + /* Consume the input prior to error checking to mirror buffered mode. */ + if (ip) ip += iSize; + FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed"); + zcs->frameEnded = lastBlock; + if (lastBlock) assert(ip == iend); + } + if (cDst == op) { /* no need to flush */ + op += cSize; + if (zcs->frameEnded) { + DEBUGLOG(5, "Frame completed directly in outBuffer"); + someMoreWork = 0; + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + } + break; + } + zcs->outBuffContentSize = cSize; + zcs->outBuffFlushedSize = 0; + zcs->streamStage = zcss_flush; /* pass-through to flush stage */ + } + ZSTD_FALLTHROUGH; + case zcss_flush: + DEBUGLOG(5, "flush stage"); + assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered); + { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize; + size_t const flushed = ZSTD_limitCopy(op, (size_t)(oend-op), + zcs->outBuff + zcs->outBuffFlushedSize, toFlush); + DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u", + (unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed); + if (flushed) + op += flushed; + zcs->outBuffFlushedSize += flushed; + if (toFlush!=flushed) { + /* flush not fully completed, presumably because dst is too small */ + assert(op==oend); + someMoreWork = 0; + break; + } + zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; + if (zcs->frameEnded) { + DEBUGLOG(5, "Frame completed on flush"); + someMoreWork = 0; + ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); + break; + } + zcs->streamStage = zcss_load; + break; + } + + default: /* impossible */ + assert(0); + } + } + + input->pos = (size_t)(ip - istart); + output->pos = (size_t)(op - ostart); + if (zcs->frameEnded) return 0; + return ZSTD_nextInputSizeHint(zcs); +} + +static size_t ZSTD_nextInputSizeHint_MTorST(const ZSTD_CCtx* cctx) +{ +#ifdef ZSTD_MULTITHREAD + if (cctx->appliedParams.nbWorkers >= 1) { + assert(cctx->mtctx != NULL); + return ZSTDMT_nextInputSizeHint(cctx->mtctx); + } +#endif + return ZSTD_nextInputSizeHint(cctx); + +} + +size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + FORWARD_IF_ERROR( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) , ""); + return ZSTD_nextInputSizeHint_MTorST(zcs); +} + +/* After a compression call set the expected input/output buffer. + * This is validated at the start of the next compression call. + */ +static void +ZSTD_setBufferExpectations(ZSTD_CCtx* cctx, const ZSTD_outBuffer* output, const ZSTD_inBuffer* input) +{ + DEBUGLOG(5, "ZSTD_setBufferExpectations (for advanced stable in/out modes)"); + if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) { + cctx->expectedInBuffer = *input; + } + if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) { + cctx->expectedOutBufferSize = output->size - output->pos; + } +} + +/* Validate that the input/output buffers match the expectations set by + * ZSTD_setBufferExpectations. + */ +static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx, + ZSTD_outBuffer const* output, + ZSTD_inBuffer const* input, + ZSTD_EndDirective endOp) +{ + if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) { + ZSTD_inBuffer const expect = cctx->expectedInBuffer; + if (expect.src != input->src || expect.pos != input->pos) + RETURN_ERROR(stabilityCondition_notRespected, "ZSTD_c_stableInBuffer enabled but input differs!"); + } + (void)endOp; + if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) { + size_t const outBufferSize = output->size - output->pos; + if (cctx->expectedOutBufferSize != outBufferSize) + RETURN_ERROR(stabilityCondition_notRespected, "ZSTD_c_stableOutBuffer enabled but output size differs!"); + } + return 0; +} + +/* + * If @endOp == ZSTD_e_end, @inSize becomes pledgedSrcSize. + * Otherwise, it's ignored. + * @return: 0 on success, or a ZSTD_error code otherwise. + */ +static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, + ZSTD_EndDirective endOp, + size_t inSize) +{ + ZSTD_CCtx_params params = cctx->requestedParams; + ZSTD_prefixDict const prefixDict = cctx->prefixDict; + FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */ + ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */ + assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */ + if (cctx->cdict && !cctx->localDict.cdict) { + /* Let the cdict's compression level take priority over the requested params. + * But do not take the cdict's compression level if the "cdict" is actually a localDict + * generated from ZSTD_initLocalDict(). + */ + params.compressionLevel = cctx->cdict->compressionLevel; + } + DEBUGLOG(4, "ZSTD_CCtx_init_compressStream2 : transparent init stage"); + if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1; /* auto-determine pledgedSrcSize */ + + { size_t const dictSize = prefixDict.dict + ? prefixDict.dictSize + : (cctx->cdict ? cctx->cdict->dictContentSize : 0); + ZSTD_CParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, ¶ms, cctx->pledgedSrcSizePlusOne - 1); + params.cParams = ZSTD_getCParamsFromCCtxParams( + ¶ms, cctx->pledgedSrcSizePlusOne-1, + dictSize, mode); + } + + params.postBlockSplitter = ZSTD_resolveBlockSplitterMode(params.postBlockSplitter, ¶ms.cParams); + params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, ¶ms.cParams); + params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, ¶ms.cParams); + params.validateSequences = ZSTD_resolveExternalSequenceValidation(params.validateSequences); + params.maxBlockSize = ZSTD_resolveMaxBlockSize(params.maxBlockSize); + params.searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(params.searchForExternalRepcodes, params.compressionLevel); + +#ifdef ZSTD_MULTITHREAD + /* If external matchfinder is enabled, make sure to fail before checking job size (for consistency) */ + RETURN_ERROR_IF( + ZSTD_hasExtSeqProd(¶ms) && params.nbWorkers >= 1, + parameter_combination_unsupported, + "External sequence producer isn't supported with nbWorkers >= 1" + ); + + if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) { + params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */ + } + if (params.nbWorkers > 0) { +# if ZSTD_TRACE + cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0; +# endif + /* mt context creation */ + if (cctx->mtctx == NULL) { + DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u", + params.nbWorkers); + cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem, cctx->pool); + RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!"); + } + /* mt compression */ + DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers); + FORWARD_IF_ERROR( ZSTDMT_initCStream_internal( + cctx->mtctx, + prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, + cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , ""); + cctx->dictID = cctx->cdict ? cctx->cdict->dictID : 0; + cctx->dictContentSize = cctx->cdict ? cctx->cdict->dictContentSize : prefixDict.dictSize; + cctx->consumedSrcSize = 0; + cctx->producedCSize = 0; + cctx->streamStage = zcss_load; + cctx->appliedParams = params; + } else +#endif /* ZSTD_MULTITHREAD */ + { U64 const pledgedSrcSize = cctx->pledgedSrcSizePlusOne - 1; + assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); + FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx, + prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, ZSTD_dtlm_fast, + cctx->cdict, + ¶ms, pledgedSrcSize, + ZSTDb_buffered) , ""); + assert(cctx->appliedParams.nbWorkers == 0); + cctx->inToCompress = 0; + cctx->inBuffPos = 0; + if (cctx->appliedParams.inBufferMode == ZSTD_bm_buffered) { + /* for small input: avoid automatic flush on reaching end of block, since + * it would require to add a 3-bytes null block to end frame + */ + cctx->inBuffTarget = cctx->blockSizeMax + (cctx->blockSizeMax == pledgedSrcSize); + } else { + cctx->inBuffTarget = 0; + } + cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0; + cctx->streamStage = zcss_load; + cctx->frameEnded = 0; + } + return 0; +} + +/* @return provides a minimum amount of data remaining to be flushed from internal buffers + */ +size_t ZSTD_compressStream2( ZSTD_CCtx* cctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp) +{ + DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp); + /* check conditions */ + RETURN_ERROR_IF(output->pos > output->size, dstSize_tooSmall, "invalid output buffer"); + RETURN_ERROR_IF(input->pos > input->size, srcSize_wrong, "invalid input buffer"); + RETURN_ERROR_IF((U32)endOp > (U32)ZSTD_e_end, parameter_outOfBound, "invalid endDirective"); + assert(cctx != NULL); + + /* transparent initialization stage */ + if (cctx->streamStage == zcss_init) { + size_t const inputSize = input->size - input->pos; /* no obligation to start from pos==0 */ + size_t const totalInputSize = inputSize + cctx->stableIn_notConsumed; + if ( (cctx->requestedParams.inBufferMode == ZSTD_bm_stable) /* input is presumed stable, across invocations */ + && (endOp == ZSTD_e_continue) /* no flush requested, more input to come */ + && (totalInputSize < ZSTD_BLOCKSIZE_MAX) ) { /* not even reached one block yet */ + if (cctx->stableIn_notConsumed) { /* not the first time */ + /* check stable source guarantees */ + RETURN_ERROR_IF(input->src != cctx->expectedInBuffer.src, stabilityCondition_notRespected, "stableInBuffer condition not respected: wrong src pointer"); + RETURN_ERROR_IF(input->pos != cctx->expectedInBuffer.size, stabilityCondition_notRespected, "stableInBuffer condition not respected: externally modified pos"); + } + /* pretend input was consumed, to give a sense forward progress */ + input->pos = input->size; + /* save stable inBuffer, for later control, and flush/end */ + cctx->expectedInBuffer = *input; + /* but actually input wasn't consumed, so keep track of position from where compression shall resume */ + cctx->stableIn_notConsumed += inputSize; + /* don't initialize yet, wait for the first block of flush() order, for better parameters adaptation */ + return ZSTD_FRAMEHEADERSIZE_MIN(cctx->requestedParams.format); /* at least some header to produce */ + } + FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, endOp, totalInputSize), "compressStream2 initialization failed"); + ZSTD_setBufferExpectations(cctx, output, input); /* Set initial buffer expectations now that we've initialized */ + } + /* end of transparent initialization stage */ + + FORWARD_IF_ERROR(ZSTD_checkBufferStability(cctx, output, input, endOp), "invalid buffers"); + /* compression stage */ +#ifdef ZSTD_MULTITHREAD + if (cctx->appliedParams.nbWorkers > 0) { + size_t flushMin; + if (cctx->cParamsChanged) { + ZSTDMT_updateCParams_whileCompressing(cctx->mtctx, &cctx->requestedParams); + cctx->cParamsChanged = 0; + } + if (cctx->stableIn_notConsumed) { + assert(cctx->appliedParams.inBufferMode == ZSTD_bm_stable); + /* some early data was skipped - make it available for consumption */ + assert(input->pos >= cctx->stableIn_notConsumed); + input->pos -= cctx->stableIn_notConsumed; + cctx->stableIn_notConsumed = 0; + } + for (;;) { + size_t const ipos = input->pos; + size_t const opos = output->pos; + flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); + cctx->consumedSrcSize += (U64)(input->pos - ipos); + cctx->producedCSize += (U64)(output->pos - opos); + if ( ZSTD_isError(flushMin) + || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */ + if (flushMin == 0) + ZSTD_CCtx_trace(cctx, 0); + ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only); + } + FORWARD_IF_ERROR(flushMin, "ZSTDMT_compressStream_generic failed"); + + if (endOp == ZSTD_e_continue) { + /* We only require some progress with ZSTD_e_continue, not maximal progress. + * We're done if we've consumed or produced any bytes, or either buffer is + * full. + */ + if (input->pos != ipos || output->pos != opos || input->pos == input->size || output->pos == output->size) + break; + } else { + assert(endOp == ZSTD_e_flush || endOp == ZSTD_e_end); + /* We require maximal progress. We're done when the flush is complete or the + * output buffer is full. + */ + if (flushMin == 0 || output->pos == output->size) + break; + } + } + DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic"); + /* Either we don't require maximum forward progress, we've finished the + * flush, or we are out of output space. + */ + assert(endOp == ZSTD_e_continue || flushMin == 0 || output->pos == output->size); + ZSTD_setBufferExpectations(cctx, output, input); + return flushMin; + } +#endif /* ZSTD_MULTITHREAD */ + FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) , ""); + DEBUGLOG(5, "completed ZSTD_compressStream2"); + ZSTD_setBufferExpectations(cctx, output, input); + return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */ +} + +size_t ZSTD_compressStream2_simpleArgs ( + ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, size_t* dstPos, + const void* src, size_t srcSize, size_t* srcPos, + ZSTD_EndDirective endOp) +{ + ZSTD_outBuffer output; + ZSTD_inBuffer input; + output.dst = dst; + output.size = dstCapacity; + output.pos = *dstPos; + input.src = src; + input.size = srcSize; + input.pos = *srcPos; + /* ZSTD_compressStream2() will check validity of dstPos and srcPos */ + { size_t const cErr = ZSTD_compressStream2(cctx, &output, &input, endOp); + *dstPos = output.pos; + *srcPos = input.pos; + return cErr; + } +} + +size_t ZSTD_compress2(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + ZSTD_bufferMode_e const originalInBufferMode = cctx->requestedParams.inBufferMode; + ZSTD_bufferMode_e const originalOutBufferMode = cctx->requestedParams.outBufferMode; + DEBUGLOG(4, "ZSTD_compress2 (srcSize=%u)", (unsigned)srcSize); + ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only); + /* Enable stable input/output buffers. */ + cctx->requestedParams.inBufferMode = ZSTD_bm_stable; + cctx->requestedParams.outBufferMode = ZSTD_bm_stable; + { size_t oPos = 0; + size_t iPos = 0; + size_t const result = ZSTD_compressStream2_simpleArgs(cctx, + dst, dstCapacity, &oPos, + src, srcSize, &iPos, + ZSTD_e_end); + /* Reset to the original values. */ + cctx->requestedParams.inBufferMode = originalInBufferMode; + cctx->requestedParams.outBufferMode = originalOutBufferMode; + + FORWARD_IF_ERROR(result, "ZSTD_compressStream2_simpleArgs failed"); + if (result != 0) { /* compression not completed, due to lack of output space */ + assert(oPos == dstCapacity); + RETURN_ERROR(dstSize_tooSmall, ""); + } + assert(iPos == srcSize); /* all input is expected consumed */ + return oPos; + } +} + +/* ZSTD_validateSequence() : + * @offBase : must use the format required by ZSTD_storeSeq() + * @returns a ZSTD error code if sequence is not valid + */ +static size_t +ZSTD_validateSequence(U32 offBase, U32 matchLength, U32 minMatch, + size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer) +{ + U32 const windowSize = 1u << windowLog; + /* posInSrc represents the amount of data the decoder would decode up to this point. + * As long as the amount of data decoded is less than or equal to window size, offsets may be + * larger than the total length of output decoded in order to reference the dict, even larger than + * window size. After output surpasses windowSize, we're limited to windowSize offsets again. + */ + size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize; + size_t const matchLenLowerBound = (minMatch == 3 || useSequenceProducer) ? 3 : 4; + RETURN_ERROR_IF(offBase > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!"); + /* Validate maxNbSeq is large enough for the given matchLength and minMatch */ + RETURN_ERROR_IF(matchLength < matchLenLowerBound, externalSequences_invalid, "Matchlength too small for the minMatch"); + return 0; +} + +/* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */ +static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0) +{ + U32 offBase = OFFSET_TO_OFFBASE(rawOffset); + + if (!ll0 && rawOffset == rep[0]) { + offBase = REPCODE1_TO_OFFBASE; + } else if (rawOffset == rep[1]) { + offBase = REPCODE_TO_OFFBASE(2 - ll0); + } else if (rawOffset == rep[2]) { + offBase = REPCODE_TO_OFFBASE(3 - ll0); + } else if (ll0 && rawOffset == rep[0] - 1) { + offBase = REPCODE3_TO_OFFBASE; + } + return offBase; +} + +/* This function scans through an array of ZSTD_Sequence, + * storing the sequences it reads, until it reaches a block delimiter. + * Note that the block delimiter includes the last literals of the block. + * @blockSize must be == sum(sequence_lengths). + * @returns @blockSize on success, and a ZSTD_error otherwise. + */ +static size_t +ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx, + ZSTD_SequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize, + ZSTD_ParamSwitch_e externalRepSearch) +{ + U32 idx = seqPos->idx; + U32 const startIdx = idx; + BYTE const* ip = (BYTE const*)(src); + const BYTE* const iend = ip + blockSize; + Repcodes_t updatedRepcodes; + U32 dictSize; + + DEBUGLOG(5, "ZSTD_transferSequences_wBlockDelim (blockSize = %zu)", blockSize); + + if (cctx->cdict) { + dictSize = (U32)cctx->cdict->dictContentSize; + } else if (cctx->prefixDict.dict) { + dictSize = (U32)cctx->prefixDict.dictSize; + } else { + dictSize = 0; + } + ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + for (; idx < inSeqsSize && (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0); ++idx) { + U32 const litLength = inSeqs[idx].litLength; + U32 const matchLength = inSeqs[idx].matchLength; + U32 offBase; + + if (externalRepSearch == ZSTD_ps_disable) { + offBase = OFFSET_TO_OFFBASE(inSeqs[idx].offset); + } else { + U32 const ll0 = (litLength == 0); + offBase = ZSTD_finalizeOffBase(inSeqs[idx].offset, updatedRepcodes.rep, ll0); + ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0); + } + + DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength); + if (cctx->appliedParams.validateSequences) { + seqPos->posInSrc += litLength + matchLength; + FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, + seqPos->posInSrc, + cctx->appliedParams.cParams.windowLog, dictSize, + ZSTD_hasExtSeqProd(&cctx->appliedParams)), + "Sequence validation failed"); + } + RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid, + "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); + ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength); + ip += matchLength + litLength; + } + RETURN_ERROR_IF(idx == inSeqsSize, externalSequences_invalid, "Block delimiter not found."); + + /* If we skipped repcode search while parsing, we need to update repcodes now */ + assert(externalRepSearch != ZSTD_ps_auto); + assert(idx >= startIdx); + if (externalRepSearch == ZSTD_ps_disable && idx != startIdx) { + U32* const rep = updatedRepcodes.rep; + U32 lastSeqIdx = idx - 1; /* index of last non-block-delimiter sequence */ + + if (lastSeqIdx >= startIdx + 2) { + rep[2] = inSeqs[lastSeqIdx - 2].offset; + rep[1] = inSeqs[lastSeqIdx - 1].offset; + rep[0] = inSeqs[lastSeqIdx].offset; + } else if (lastSeqIdx == startIdx + 1) { + rep[2] = rep[0]; + rep[1] = inSeqs[lastSeqIdx - 1].offset; + rep[0] = inSeqs[lastSeqIdx].offset; + } else { + assert(lastSeqIdx == startIdx); + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = inSeqs[lastSeqIdx].offset; + } + } + + ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t)); + + if (inSeqs[idx].litLength) { + DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength); + ZSTD_storeLastLiterals(&cctx->seqStore, ip, inSeqs[idx].litLength); + ip += inSeqs[idx].litLength; + seqPos->posInSrc += inSeqs[idx].litLength; + } + RETURN_ERROR_IF(ip != iend, externalSequences_invalid, "Blocksize doesn't agree with block delimiter!"); + seqPos->idx = idx+1; + return blockSize; +} + +/* + * This function attempts to scan through @blockSize bytes in @src + * represented by the sequences in @inSeqs, + * storing any (partial) sequences. + * + * Occasionally, we may want to reduce the actual number of bytes consumed from @src + * to avoid splitting a match, notably if it would produce a match smaller than MINMATCH. + * + * @returns the number of bytes consumed from @src, necessarily <= @blockSize. + * Otherwise, it may return a ZSTD error if something went wrong. + */ +static size_t +ZSTD_transferSequences_noDelim(ZSTD_CCtx* cctx, + ZSTD_SequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize, + ZSTD_ParamSwitch_e externalRepSearch) +{ + U32 idx = seqPos->idx; + U32 startPosInSequence = seqPos->posInSequence; + U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize; + size_t dictSize; + const BYTE* const istart = (const BYTE*)(src); + const BYTE* ip = istart; + const BYTE* iend = istart + blockSize; /* May be adjusted if we decide to process fewer than blockSize bytes */ + Repcodes_t updatedRepcodes; + U32 bytesAdjustment = 0; + U32 finalMatchSplit = 0; + + /* TODO(embg) support fast parsing mode in noBlockDelim mode */ + (void)externalRepSearch; + + if (cctx->cdict) { + dictSize = cctx->cdict->dictContentSize; + } else if (cctx->prefixDict.dict) { + dictSize = cctx->prefixDict.dictSize; + } else { + dictSize = 0; + } + DEBUGLOG(5, "ZSTD_transferSequences_noDelim: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize); + DEBUGLOG(5, "Start seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength); + ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) { + const ZSTD_Sequence currSeq = inSeqs[idx]; + U32 litLength = currSeq.litLength; + U32 matchLength = currSeq.matchLength; + U32 const rawOffset = currSeq.offset; + U32 offBase; + + /* Modify the sequence depending on where endPosInSequence lies */ + if (endPosInSequence >= currSeq.litLength + currSeq.matchLength) { + if (startPosInSequence >= litLength) { + startPosInSequence -= litLength; + litLength = 0; + matchLength -= startPosInSequence; + } else { + litLength -= startPosInSequence; + } + /* Move to the next sequence */ + endPosInSequence -= currSeq.litLength + currSeq.matchLength; + startPosInSequence = 0; + } else { + /* This is the final (partial) sequence we're adding from inSeqs, and endPosInSequence + does not reach the end of the match. So, we have to split the sequence */ + DEBUGLOG(6, "Require a split: diff: %u, idx: %u PIS: %u", + currSeq.litLength + currSeq.matchLength - endPosInSequence, idx, endPosInSequence); + if (endPosInSequence > litLength) { + U32 firstHalfMatchLength; + litLength = startPosInSequence >= litLength ? 0 : litLength - startPosInSequence; + firstHalfMatchLength = endPosInSequence - startPosInSequence - litLength; + if (matchLength > blockSize && firstHalfMatchLength >= cctx->appliedParams.cParams.minMatch) { + /* Only ever split the match if it is larger than the block size */ + U32 secondHalfMatchLength = currSeq.matchLength + currSeq.litLength - endPosInSequence; + if (secondHalfMatchLength < cctx->appliedParams.cParams.minMatch) { + /* Move the endPosInSequence backward so that it creates match of minMatch length */ + endPosInSequence -= cctx->appliedParams.cParams.minMatch - secondHalfMatchLength; + bytesAdjustment = cctx->appliedParams.cParams.minMatch - secondHalfMatchLength; + firstHalfMatchLength -= bytesAdjustment; + } + matchLength = firstHalfMatchLength; + /* Flag that we split the last match - after storing the sequence, exit the loop, + but keep the value of endPosInSequence */ + finalMatchSplit = 1; + } else { + /* Move the position in sequence backwards so that we don't split match, and break to store + * the last literals. We use the original currSeq.litLength as a marker for where endPosInSequence + * should go. We prefer to do this whenever it is not necessary to split the match, or if doing so + * would cause the first half of the match to be too small + */ + bytesAdjustment = endPosInSequence - currSeq.litLength; + endPosInSequence = currSeq.litLength; + break; + } + } else { + /* This sequence ends inside the literals, break to store the last literals */ + break; + } + } + /* Check if this offset can be represented with a repcode */ + { U32 const ll0 = (litLength == 0); + offBase = ZSTD_finalizeOffBase(rawOffset, updatedRepcodes.rep, ll0); + ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0); + } + + if (cctx->appliedParams.validateSequences) { + seqPos->posInSrc += litLength + matchLength; + FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, seqPos->posInSrc, + cctx->appliedParams.cParams.windowLog, dictSize, ZSTD_hasExtSeqProd(&cctx->appliedParams)), + "Sequence validation failed"); + } + DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength); + RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid, + "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); + ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength); + ip += matchLength + litLength; + if (!finalMatchSplit) + idx++; /* Next Sequence */ + } + DEBUGLOG(5, "Ending seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength); + assert(idx == inSeqsSize || endPosInSequence <= inSeqs[idx].litLength + inSeqs[idx].matchLength); + seqPos->idx = idx; + seqPos->posInSequence = endPosInSequence; + ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t)); + + iend -= bytesAdjustment; + if (ip != iend) { + /* Store any last literals */ + U32 const lastLLSize = (U32)(iend - ip); + assert(ip <= iend); + DEBUGLOG(6, "Storing last literals of size: %u", lastLLSize); + ZSTD_storeLastLiterals(&cctx->seqStore, ip, lastLLSize); + seqPos->posInSrc += lastLLSize; + } + + return (size_t)(iend-istart); +} + +/* @seqPos represents a position within @inSeqs, + * it is read and updated by this function, + * once the goal to produce a block of size @blockSize is reached. + * @return: nb of bytes consumed from @src, necessarily <= @blockSize. + */ +typedef size_t (*ZSTD_SequenceCopier_f)(ZSTD_CCtx* cctx, + ZSTD_SequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize, + ZSTD_ParamSwitch_e externalRepSearch); + +static ZSTD_SequenceCopier_f ZSTD_selectSequenceCopier(ZSTD_SequenceFormat_e mode) +{ + assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, (int)mode)); + if (mode == ZSTD_sf_explicitBlockDelimiters) { + return ZSTD_transferSequences_wBlockDelim; + } + assert(mode == ZSTD_sf_noBlockDelimiters); + return ZSTD_transferSequences_noDelim; +} + +/* Discover the size of next block by searching for the delimiter. + * Note that a block delimiter **must** exist in this mode, + * otherwise it's an input error. + * The block size retrieved will be later compared to ensure it remains within bounds */ +static size_t +blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD_SequencePosition seqPos) +{ + int end = 0; + size_t blockSize = 0; + size_t spos = seqPos.idx; + DEBUGLOG(6, "blockSize_explicitDelimiter : seq %zu / %zu", spos, inSeqsSize); + assert(spos <= inSeqsSize); + while (spos < inSeqsSize) { + end = (inSeqs[spos].offset == 0); + blockSize += inSeqs[spos].litLength + inSeqs[spos].matchLength; + if (end) { + if (inSeqs[spos].matchLength != 0) + RETURN_ERROR(externalSequences_invalid, "delimiter format error : both matchlength and offset must be == 0"); + break; + } + spos++; + } + if (!end) + RETURN_ERROR(externalSequences_invalid, "Reached end of sequences without finding a block delimiter"); + return blockSize; +} + +static size_t determine_blockSize(ZSTD_SequenceFormat_e mode, + size_t blockSize, size_t remaining, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + ZSTD_SequencePosition seqPos) +{ + DEBUGLOG(6, "determine_blockSize : remainingSize = %zu", remaining); + if (mode == ZSTD_sf_noBlockDelimiters) { + /* Note: more a "target" block size */ + return MIN(remaining, blockSize); + } + assert(mode == ZSTD_sf_explicitBlockDelimiters); + { size_t const explicitBlockSize = blockSize_explicitDelimiter(inSeqs, inSeqsSize, seqPos); + FORWARD_IF_ERROR(explicitBlockSize, "Error while determining block size with explicit delimiters"); + if (explicitBlockSize > blockSize) + RETURN_ERROR(externalSequences_invalid, "sequences incorrectly define a too large block"); + if (explicitBlockSize > remaining) + RETURN_ERROR(externalSequences_invalid, "sequences define a frame longer than source"); + return explicitBlockSize; + } +} + +/* Compress all provided sequences, block-by-block. + * + * Returns the cumulative size of all compressed blocks (including their headers), + * otherwise a ZSTD error. + */ +static size_t +ZSTD_compressSequences_internal(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize) +{ + size_t cSize = 0; + size_t remaining = srcSize; + ZSTD_SequencePosition seqPos = {0, 0, 0}; + + const BYTE* ip = (BYTE const*)src; + BYTE* op = (BYTE*)dst; + ZSTD_SequenceCopier_f const sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters); + + DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize); + /* Special case: empty frame */ + if (remaining == 0) { + U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1); + RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "No room for empty frame block header"); + MEM_writeLE32(op, cBlockHeader24); + op += ZSTD_blockHeaderSize; + dstCapacity -= ZSTD_blockHeaderSize; + cSize += ZSTD_blockHeaderSize; + } + + while (remaining) { + size_t compressedSeqsSize; + size_t cBlockSize; + size_t blockSize = determine_blockSize(cctx->appliedParams.blockDelimiters, + cctx->blockSizeMax, remaining, + inSeqs, inSeqsSize, seqPos); + U32 const lastBlock = (blockSize == remaining); + FORWARD_IF_ERROR(blockSize, "Error while trying to determine block size"); + assert(blockSize <= remaining); + ZSTD_resetSeqStore(&cctx->seqStore); + + blockSize = sequenceCopier(cctx, + &seqPos, inSeqs, inSeqsSize, + ip, blockSize, + cctx->appliedParams.searchForExternalRepcodes); + FORWARD_IF_ERROR(blockSize, "Bad sequence copy"); + + /* If blocks are too small, emit as a nocompress block */ + /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding + * additional 1. We need to revisit and change this logic to be more consistent */ + if (blockSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1+1) { + cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed"); + DEBUGLOG(5, "Block too small (%zu): data remains uncompressed: cSize=%zu", blockSize, cBlockSize); + cSize += cBlockSize; + ip += blockSize; + op += cBlockSize; + remaining -= blockSize; + dstCapacity -= cBlockSize; + continue; + } + + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "not enough dstCapacity to write a new compressed block"); + compressedSeqsSize = ZSTD_entropyCompressSeqStore(&cctx->seqStore, + &cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy, + &cctx->appliedParams, + op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize, + blockSize, + cctx->tmpWorkspace, cctx->tmpWkspSize /* statically allocated in resetCCtx */, + cctx->bmi2); + FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed"); + DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize); + + if (!cctx->isFirstBlock && + ZSTD_maybeRLE(&cctx->seqStore) && + ZSTD_isRLE(ip, blockSize)) { + /* Note: don't emit the first block as RLE even if it qualifies because + * doing so will cause the decoder (cli <= v1.4.3 only) to throw an (invalid) error + * "should consume all input error." + */ + compressedSeqsSize = 1; + } + + if (compressedSeqsSize == 0) { + /* ZSTD_noCompressBlock writes the block header as well */ + cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cBlockSize, "ZSTD_noCompressBlock failed"); + DEBUGLOG(5, "Writing out nocompress block, size: %zu", cBlockSize); + } else if (compressedSeqsSize == 1) { + cBlockSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cBlockSize, "ZSTD_rleCompressBlock failed"); + DEBUGLOG(5, "Writing out RLE block, size: %zu", cBlockSize); + } else { + U32 cBlockHeader; + /* Error checking and repcodes update */ + ZSTD_blockState_confirmRepcodesAndEntropyTables(&cctx->blockState); + if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + /* Write block header into beginning of block*/ + cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3); + MEM_writeLE24(op, cBlockHeader); + cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize; + DEBUGLOG(5, "Writing out compressed block, size: %zu", cBlockSize); + } + + cSize += cBlockSize; + + if (lastBlock) { + break; + } else { + ip += blockSize; + op += cBlockSize; + remaining -= blockSize; + dstCapacity -= cBlockSize; + cctx->isFirstBlock = 0; + } + DEBUGLOG(5, "cSize running total: %zu (remaining dstCapacity=%zu)", cSize, dstCapacity); + } + + DEBUGLOG(4, "cSize final total: %zu", cSize); + return cSize; +} + +size_t ZSTD_compressSequences(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize) +{ + BYTE* op = (BYTE*)dst; + size_t cSize = 0; + + /* Transparent initialization stage, same as compressStream2() */ + DEBUGLOG(4, "ZSTD_compressSequences (nbSeqs=%zu,dstCapacity=%zu)", inSeqsSize, dstCapacity); + assert(cctx != NULL); + FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, srcSize), "CCtx initialization failed"); + + /* Begin writing output, starting with frame header */ + { size_t const frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity, + &cctx->appliedParams, srcSize, cctx->dictID); + op += frameHeaderSize; + assert(frameHeaderSize <= dstCapacity); + dstCapacity -= frameHeaderSize; + cSize += frameHeaderSize; + } + if (cctx->appliedParams.fParams.checksumFlag && srcSize) { + XXH64_update(&cctx->xxhState, src, srcSize); + } + + /* Now generate compressed blocks */ + { size_t const cBlocksSize = ZSTD_compressSequences_internal(cctx, + op, dstCapacity, + inSeqs, inSeqsSize, + src, srcSize); + FORWARD_IF_ERROR(cBlocksSize, "Compressing blocks failed!"); + cSize += cBlocksSize; + assert(cBlocksSize <= dstCapacity); + dstCapacity -= cBlocksSize; + } + + /* Complete with frame checksum, if needed */ + if (cctx->appliedParams.fParams.checksumFlag) { + U32 const checksum = (U32) XXH64_digest(&cctx->xxhState); + RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum"); + DEBUGLOG(4, "Write checksum : %08X", (unsigned)checksum); + MEM_writeLE32((char*)dst + cSize, checksum); + cSize += 4; + } + + DEBUGLOG(4, "Final compressed size: %zu", cSize); + return cSize; +} + + +#if defined(__AVX2__) + +#include /* AVX2 intrinsics */ + +/* + * Convert 2 sequences per iteration, using AVX2 intrinsics: + * - offset -> offBase = offset + 2 + * - litLength -> (U16) litLength + * - matchLength -> (U16)(matchLength - 3) + * - rep is ignored + * Store only 8 bytes per SeqDef (offBase[4], litLength[2], mlBase[2]). + * + * At the end, instead of extracting two __m128i, + * we use _mm256_permute4x64_epi64(..., 0xE8) to move lane2 into lane1, + * then store the lower 16 bytes in one go. + * + * @returns 0 on succes, with no long length detected + * @returns > 0 if there is one long length (> 65535), + * indicating the position, and type. + */ +static size_t convertSequences_noRepcodes( + SeqDef* dstSeqs, + const ZSTD_Sequence* inSeqs, + size_t nbSequences) +{ + /* + * addition: + * For each 128-bit half: (offset+2, litLength+0, matchLength-3, rep+0) + */ + const __m256i addition = _mm256_setr_epi32( + ZSTD_REP_NUM, 0, -MINMATCH, 0, /* for sequence i */ + ZSTD_REP_NUM, 0, -MINMATCH, 0 /* for sequence i+1 */ + ); + + /* limit: check if there is a long length */ + const __m256i limit = _mm256_set1_epi32(65535); + + /* + * shuffle mask for byte-level rearrangement in each 128-bit half: + * + * Input layout (after addition) per 128-bit half: + * [ offset+2 (4 bytes) | litLength (4 bytes) | matchLength (4 bytes) | rep (4 bytes) ] + * We only need: + * offBase (4 bytes) = offset+2 + * litLength (2 bytes) = low 2 bytes of litLength + * mlBase (2 bytes) = low 2 bytes of (matchLength) + * => Bytes [0..3, 4..5, 8..9], zero the rest. + */ + const __m256i mask = _mm256_setr_epi8( + /* For the lower 128 bits => sequence i */ + 0, 1, 2, 3, /* offset+2 */ + 4, 5, /* litLength (16 bits) */ + 8, 9, /* matchLength (16 bits) */ + (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, + (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, + + /* For the upper 128 bits => sequence i+1 */ + 16,17,18,19, /* offset+2 */ + 20,21, /* litLength */ + 24,25, /* matchLength */ + (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, + (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80 + ); + + /* + * Next, we'll use _mm256_permute4x64_epi64(vshf, 0xE8). + * Explanation of 0xE8 = 11101000b => [lane0, lane2, lane2, lane3]. + * So the lower 128 bits become [lane0, lane2] => combining seq0 and seq1. + */ +#define PERM_LANE_0X_E8 0xE8 /* [0,2,2,3] in lane indices */ + + size_t longLen = 0, i = 0; + + /* AVX permutation depends on the specific definition of target structures */ + ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16); + ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, offset) == 0); + ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, litLength) == 4); + ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8); + ZSTD_STATIC_ASSERT(sizeof(SeqDef) == 8); + ZSTD_STATIC_ASSERT(offsetof(SeqDef, offBase) == 0); + ZSTD_STATIC_ASSERT(offsetof(SeqDef, litLength) == 4); + ZSTD_STATIC_ASSERT(offsetof(SeqDef, mlBase) == 6); + + /* Process 2 sequences per loop iteration */ + for (; i + 1 < nbSequences; i += 2) { + /* Load 2 ZSTD_Sequence (32 bytes) */ + __m256i vin = _mm256_loadu_si256((const __m256i*)(const void*)&inSeqs[i]); + + /* Add {2, 0, -3, 0} in each 128-bit half */ + __m256i vadd = _mm256_add_epi32(vin, addition); + + /* Check for long length */ + __m256i ll_cmp = _mm256_cmpgt_epi32(vadd, limit); /* 0xFFFFFFFF for element > 65535 */ + int ll_res = _mm256_movemask_epi8(ll_cmp); + + /* Shuffle bytes so each half gives us the 8 bytes we need */ + __m256i vshf = _mm256_shuffle_epi8(vadd, mask); + /* + * Now: + * Lane0 = seq0's 8 bytes + * Lane1 = 0 + * Lane2 = seq1's 8 bytes + * Lane3 = 0 + */ + + /* Permute 64-bit lanes => move Lane2 down into Lane1. */ + __m256i vperm = _mm256_permute4x64_epi64(vshf, PERM_LANE_0X_E8); + /* + * Now the lower 16 bytes (Lane0+Lane1) = [seq0, seq1]. + * The upper 16 bytes are [Lane2, Lane3] = [seq1, 0], but we won't use them. + */ + + /* Store only the lower 16 bytes => 2 SeqDef (8 bytes each) */ + _mm_storeu_si128((__m128i *)(void*)&dstSeqs[i], _mm256_castsi256_si128(vperm)); + /* + * This writes out 16 bytes total: + * - offset 0..7 => seq0 (offBase, litLength, mlBase) + * - offset 8..15 => seq1 (offBase, litLength, mlBase) + */ + + /* check (unlikely) long lengths > 65535 + * indices for lengths correspond to bits [4..7], [8..11], [20..23], [24..27] + * => combined mask = 0x0FF00FF0 + */ + if (UNLIKELY((ll_res & 0x0FF00FF0) != 0)) { + /* long length detected: let's figure out which one*/ + if (inSeqs[i].matchLength > 65535+MINMATCH) { + assert(longLen == 0); + longLen = i + 1; + } + if (inSeqs[i].litLength > 65535) { + assert(longLen == 0); + longLen = i + nbSequences + 1; + } + if (inSeqs[i+1].matchLength > 65535+MINMATCH) { + assert(longLen == 0); + longLen = i + 1 + 1; + } + if (inSeqs[i+1].litLength > 65535) { + assert(longLen == 0); + longLen = i + 1 + nbSequences + 1; + } + } + } + + /* Handle leftover if @nbSequences is odd */ + if (i < nbSequences) { + /* process last sequence */ + assert(i == nbSequences - 1); + dstSeqs[i].offBase = OFFSET_TO_OFFBASE(inSeqs[i].offset); + dstSeqs[i].litLength = (U16)inSeqs[i].litLength; + dstSeqs[i].mlBase = (U16)(inSeqs[i].matchLength - MINMATCH); + /* check (unlikely) long lengths > 65535 */ + if (UNLIKELY(inSeqs[i].matchLength > 65535+MINMATCH)) { + assert(longLen == 0); + longLen = i + 1; + } + if (UNLIKELY(inSeqs[i].litLength > 65535)) { + assert(longLen == 0); + longLen = i + nbSequences + 1; + } + } + + return longLen; +} + +/* the vector implementation could also be ported to SSSE3, + * but since this implementation is targeting modern systems (>= Sapphire Rapid), + * it's not useful to develop and maintain code for older pre-AVX2 platforms */ + +#else /* no AVX2 */ + +static size_t convertSequences_noRepcodes( + SeqDef* dstSeqs, + const ZSTD_Sequence* inSeqs, + size_t nbSequences) +{ + size_t longLen = 0; + size_t n; + for (n=0; n 65535 */ + if (UNLIKELY(inSeqs[n].matchLength > 65535+MINMATCH)) { + assert(longLen == 0); + longLen = n + 1; + } + if (UNLIKELY(inSeqs[n].litLength > 65535)) { + assert(longLen == 0); + longLen = n + nbSequences + 1; + } + } + return longLen; +} + +#endif + +/* + * Precondition: Sequences must end on an explicit Block Delimiter + * @return: 0 on success, or an error code. + * Note: Sequence validation functionality has been disabled (removed). + * This is helpful to generate a lean main pipeline, improving performance. + * It may be re-inserted later. + */ +size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx, + const ZSTD_Sequence* const inSeqs, size_t nbSequences, + int repcodeResolution) +{ + Repcodes_t updatedRepcodes; + size_t seqNb = 0; + + DEBUGLOG(5, "ZSTD_convertBlockSequences (nbSequences = %zu)", nbSequences); + + RETURN_ERROR_IF(nbSequences >= cctx->seqStore.maxNbSeq, externalSequences_invalid, + "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); + + ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + + /* check end condition */ + assert(nbSequences >= 1); + assert(inSeqs[nbSequences-1].matchLength == 0); + assert(inSeqs[nbSequences-1].offset == 0); + + /* Convert Sequences from public format to internal format */ + if (!repcodeResolution) { + size_t const longl = convertSequences_noRepcodes(cctx->seqStore.sequencesStart, inSeqs, nbSequences-1); + cctx->seqStore.sequences = cctx->seqStore.sequencesStart + nbSequences-1; + if (longl) { + DEBUGLOG(5, "long length"); + assert(cctx->seqStore.longLengthType == ZSTD_llt_none); + if (longl <= nbSequences-1) { + DEBUGLOG(5, "long match length detected at pos %zu", longl-1); + cctx->seqStore.longLengthType = ZSTD_llt_matchLength; + cctx->seqStore.longLengthPos = (U32)(longl-1); + } else { + DEBUGLOG(5, "long literals length detected at pos %zu", longl-nbSequences); + assert(longl <= 2* (nbSequences-1)); + cctx->seqStore.longLengthType = ZSTD_llt_literalLength; + cctx->seqStore.longLengthPos = (U32)(longl-(nbSequences-1)-1); + } + } + } else { + for (seqNb = 0; seqNb < nbSequences - 1 ; seqNb++) { + U32 const litLength = inSeqs[seqNb].litLength; + U32 const matchLength = inSeqs[seqNb].matchLength; + U32 const ll0 = (litLength == 0); + U32 const offBase = ZSTD_finalizeOffBase(inSeqs[seqNb].offset, updatedRepcodes.rep, ll0); + + DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength); + ZSTD_storeSeqOnly(&cctx->seqStore, litLength, offBase, matchLength); + ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0); + } + } + + /* If we skipped repcode search while parsing, we need to update repcodes now */ + if (!repcodeResolution && nbSequences > 1) { + U32* const rep = updatedRepcodes.rep; + + if (nbSequences >= 4) { + U32 lastSeqIdx = (U32)nbSequences - 2; /* index of last full sequence */ + rep[2] = inSeqs[lastSeqIdx - 2].offset; + rep[1] = inSeqs[lastSeqIdx - 1].offset; + rep[0] = inSeqs[lastSeqIdx].offset; + } else if (nbSequences == 3) { + rep[2] = rep[0]; + rep[1] = inSeqs[0].offset; + rep[0] = inSeqs[1].offset; + } else { + assert(nbSequences == 2); + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = inSeqs[0].offset; + } + } + + ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t)); + + return 0; +} + +#if defined(ZSTD_ARCH_X86_AVX2) + +BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs) +{ + size_t i; + __m256i const zeroVec = _mm256_setzero_si256(); + __m256i sumVec = zeroVec; /* accumulates match+lit in 32-bit lanes */ + ZSTD_ALIGNED(32) U32 tmp[8]; /* temporary buffer for reduction */ + size_t mSum = 0, lSum = 0; + ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16); + + /* Process 2 structs (32 bytes) at a time */ + for (i = 0; i + 2 <= nbSeqs; i += 2) { + /* Load two consecutive ZSTD_Sequence (8×4 = 32 bytes) */ + __m256i data = _mm256_loadu_si256((const __m256i*)(const void*)&seqs[i]); + /* check end of block signal */ + __m256i cmp = _mm256_cmpeq_epi32(data, zeroVec); + int cmp_res = _mm256_movemask_epi8(cmp); + /* indices for match lengths correspond to bits [8..11], [24..27] + * => combined mask = 0x0F000F00 */ + ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8); + if (cmp_res & 0x0F000F00) break; + /* Accumulate in sumVec */ + sumVec = _mm256_add_epi32(sumVec, data); + } + + /* Horizontal reduction */ + _mm256_store_si256((__m256i*)tmp, sumVec); + lSum = tmp[1] + tmp[5]; + mSum = tmp[2] + tmp[6]; + + /* Handle the leftover */ + for (; i < nbSeqs; i++) { + lSum += seqs[i].litLength; + mSum += seqs[i].matchLength; + if (seqs[i].matchLength == 0) break; /* end of block */ + } + + if (i==nbSeqs) { + /* reaching end of sequences: end of block signal was not present */ + BlockSummary bs; + bs.nbSequences = ERROR(externalSequences_invalid); + return bs; + } + { BlockSummary bs; + bs.nbSequences = i+1; + bs.blockSize = lSum + mSum; + bs.litSize = lSum; + return bs; + } +} + +#else + +BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs) +{ + size_t totalMatchSize = 0; + size_t litSize = 0; + size_t n; + assert(seqs); + for (n=0; nappliedParams.searchForExternalRepcodes == ZSTD_ps_enable); + assert(cctx->appliedParams.searchForExternalRepcodes != ZSTD_ps_auto); + + DEBUGLOG(4, "ZSTD_compressSequencesAndLiterals_internal: nbSeqs=%zu, litSize=%zu", nbSequences, litSize); + RETURN_ERROR_IF(nbSequences == 0, externalSequences_invalid, "Requires at least 1 end-of-block"); + + /* Special case: empty frame */ + if ((nbSequences == 1) && (inSeqs[0].litLength == 0)) { + U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1); + RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "No room for empty frame block header"); + MEM_writeLE24(op, cBlockHeader24); + op += ZSTD_blockHeaderSize; + dstCapacity -= ZSTD_blockHeaderSize; + cSize += ZSTD_blockHeaderSize; + } + + while (nbSequences) { + size_t compressedSeqsSize, cBlockSize, conversionStatus; + BlockSummary const block = ZSTD_get1BlockSummary(inSeqs, nbSequences); + U32 const lastBlock = (block.nbSequences == nbSequences); + FORWARD_IF_ERROR(block.nbSequences, "Error while trying to determine nb of sequences for a block"); + assert(block.nbSequences <= nbSequences); + RETURN_ERROR_IF(block.litSize > litSize, externalSequences_invalid, "discrepancy: Sequences require more literals than present in buffer"); + ZSTD_resetSeqStore(&cctx->seqStore); + + conversionStatus = ZSTD_convertBlockSequences(cctx, + inSeqs, block.nbSequences, + repcodeResolution); + FORWARD_IF_ERROR(conversionStatus, "Bad sequence conversion"); + inSeqs += block.nbSequences; + nbSequences -= block.nbSequences; + remaining -= block.blockSize; + + /* Note: when blockSize is very small, other variant send it uncompressed. + * Here, we still send the sequences, because we don't have the original source to send it uncompressed. + * One could imagine in theory reproducing the source from the sequences, + * but that's complex and costly memory intensive, and goes against the objectives of this variant. */ + + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "not enough dstCapacity to write a new compressed block"); + + compressedSeqsSize = ZSTD_entropyCompressSeqStore_internal( + op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize, + literals, block.litSize, + &cctx->seqStore, + &cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy, + &cctx->appliedParams, + cctx->tmpWorkspace, cctx->tmpWkspSize /* statically allocated in resetCCtx */, + cctx->bmi2); + FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed"); + /* note: the spec forbids for any compressed block to be larger than maximum block size */ + if (compressedSeqsSize > cctx->blockSizeMax) compressedSeqsSize = 0; + DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize); + litSize -= block.litSize; + literals = (const char*)literals + block.litSize; + + /* Note: difficult to check source for RLE block when only Literals are provided, + * but it could be considered from analyzing the sequence directly */ + + if (compressedSeqsSize == 0) { + /* Sending uncompressed blocks is out of reach, because the source is not provided. + * In theory, one could use the sequences to regenerate the source, like a decompressor, + * but it's complex, and memory hungry, killing the purpose of this variant. + * Current outcome: generate an error code. + */ + RETURN_ERROR(cannotProduce_uncompressedBlock, "ZSTD_compressSequencesAndLiterals cannot generate an uncompressed block"); + } else { + U32 cBlockHeader; + assert(compressedSeqsSize > 1); /* no RLE */ + /* Error checking and repcodes update */ + ZSTD_blockState_confirmRepcodesAndEntropyTables(&cctx->blockState); + if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + /* Write block header into beginning of block*/ + cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3); + MEM_writeLE24(op, cBlockHeader); + cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize; + DEBUGLOG(5, "Writing out compressed block, size: %zu", cBlockSize); + } + + cSize += cBlockSize; + op += cBlockSize; + dstCapacity -= cBlockSize; + cctx->isFirstBlock = 0; + DEBUGLOG(5, "cSize running total: %zu (remaining dstCapacity=%zu)", cSize, dstCapacity); + + if (lastBlock) { + assert(nbSequences == 0); + break; + } + } + + RETURN_ERROR_IF(litSize != 0, externalSequences_invalid, "literals must be entirely and exactly consumed"); + RETURN_ERROR_IF(remaining != 0, externalSequences_invalid, "Sequences must represent a total of exactly srcSize=%zu", srcSize); + DEBUGLOG(4, "cSize final total: %zu", cSize); + return cSize; +} + +size_t +ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* literals, size_t litSize, size_t litCapacity, + size_t decompressedSize) +{ + BYTE* op = (BYTE*)dst; + size_t cSize = 0; + + /* Transparent initialization stage, same as compressStream2() */ + DEBUGLOG(4, "ZSTD_compressSequencesAndLiterals (dstCapacity=%zu)", dstCapacity); + assert(cctx != NULL); + if (litCapacity < litSize) { + RETURN_ERROR(workSpace_tooSmall, "literals buffer is not large enough: must be at least 8 bytes larger than litSize (risk of read out-of-bound)"); + } + FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, decompressedSize), "CCtx initialization failed"); + + if (cctx->appliedParams.blockDelimiters == ZSTD_sf_noBlockDelimiters) { + RETURN_ERROR(frameParameter_unsupported, "This mode is only compatible with explicit delimiters"); + } + if (cctx->appliedParams.validateSequences) { + RETURN_ERROR(parameter_unsupported, "This mode is not compatible with Sequence validation"); + } + if (cctx->appliedParams.fParams.checksumFlag) { + RETURN_ERROR(frameParameter_unsupported, "this mode is not compatible with frame checksum"); + } + + /* Begin writing output, starting with frame header */ + { size_t const frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity, + &cctx->appliedParams, decompressedSize, cctx->dictID); + op += frameHeaderSize; + assert(frameHeaderSize <= dstCapacity); + dstCapacity -= frameHeaderSize; + cSize += frameHeaderSize; + } + + /* Now generate compressed blocks */ + { size_t const cBlocksSize = ZSTD_compressSequencesAndLiterals_internal(cctx, + op, dstCapacity, + inSeqs, inSeqsSize, + literals, litSize, decompressedSize); + FORWARD_IF_ERROR(cBlocksSize, "Compressing blocks failed!"); + cSize += cBlocksSize; + assert(cBlocksSize <= dstCapacity); + dstCapacity -= cBlocksSize; + } + + DEBUGLOG(4, "Final compressed size: %zu", cSize); + return cSize; +} + +/*====== Finalize ======*/ + +static ZSTD_inBuffer inBuffer_forEndFlush(const ZSTD_CStream* zcs) +{ + const ZSTD_inBuffer nullInput = { NULL, 0, 0 }; + const int stableInput = (zcs->appliedParams.inBufferMode == ZSTD_bm_stable); + return stableInput ? zcs->expectedInBuffer : nullInput; +} + +/*! ZSTD_flushStream() : + * @return : amount of data remaining to flush */ +size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) +{ + ZSTD_inBuffer input = inBuffer_forEndFlush(zcs); + input.size = input.pos; /* do not ingest more input during flush */ + return ZSTD_compressStream2(zcs, output, &input, ZSTD_e_flush); +} + +size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) +{ + ZSTD_inBuffer input = inBuffer_forEndFlush(zcs); + size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end); + FORWARD_IF_ERROR(remainingToFlush , "ZSTD_compressStream2(,,ZSTD_e_end) failed"); + if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush; /* minimal estimation */ + /* single thread mode : attempt to calculate remaining to flush more precisely */ + { size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE; + size_t const checksumSize = (size_t)(zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4); + size_t const toFlush = remainingToFlush + lastBlockSize + checksumSize; + DEBUGLOG(4, "ZSTD_endStream : remaining to flush : %u", (unsigned)toFlush); + return toFlush; + } +} + + +/*-===== Pre-defined compression levels =====-*/ +#include "clevels.h" + +int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } +int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; } +int ZSTD_defaultCLevel(void) { return ZSTD_CLEVEL_DEFAULT; } + +static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict); + switch (cParams.strategy) { + case ZSTD_fast: + case ZSTD_dfast: + break; + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG; + break; + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + } + return cParams; +} + +static int ZSTD_dedicatedDictSearch_isSupported( + ZSTD_compressionParameters const* cParams) +{ + return (cParams->strategy >= ZSTD_greedy) + && (cParams->strategy <= ZSTD_lazy2) + && (cParams->hashLog > cParams->chainLog) + && (cParams->chainLog <= 24); +} + +/** + * Reverses the adjustment applied to cparams when enabling dedicated dict + * search. This is used to recover the params set to be used in the working + * context. (Otherwise, those tables would also grow.) + */ +static void ZSTD_dedicatedDictSearch_revertCParams( + ZSTD_compressionParameters* cParams) { + switch (cParams->strategy) { + case ZSTD_fast: + case ZSTD_dfast: + break; + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG; + if (cParams->hashLog < ZSTD_HASHLOG_MIN) { + cParams->hashLog = ZSTD_HASHLOG_MIN; + } + break; + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + } +} + +static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + switch (mode) { + case ZSTD_cpm_unknown: + case ZSTD_cpm_noAttachDict: + case ZSTD_cpm_createCDict: + break; + case ZSTD_cpm_attachDict: + dictSize = 0; + break; + default: + assert(0); + break; + } + { int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN; + size_t const addedSize = unknown && dictSize > 0 ? 500 : 0; + return unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize; + } +} + +/*! ZSTD_getCParams_internal() : + * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. + * Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown. + * Use dictSize == 0 for unknown or unused. + * Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_CParamMode_e`. */ +static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode); + U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); + int row; + DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel); + + /* row */ + if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ + else if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */ + else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL; + else row = compressionLevel; + + { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row]; + DEBUGLOG(5, "ZSTD_getCParams_internal selected tableID: %u row: %u strat: %u", tableID, row, (U32)cp.strategy); + /* acceleration factor */ + if (compressionLevel < 0) { + int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel); + cp.targetLength = (unsigned)(-clampedCompressionLevel); + } + /* refine parameters based on srcSize & dictSize */ + return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize, mode, ZSTD_ps_auto); + } +} + +/*! ZSTD_getCParams() : + * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. + * Size values are optional, provide 0 if not known or unused */ +ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) +{ + if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); +} + +/*! ZSTD_getParams() : + * same idea as ZSTD_getCParams() + * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`). + * Fields of `ZSTD_frameParameters` are set to default values */ +static ZSTD_parameters +ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + ZSTD_parameters params; + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode); + DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel); + ZSTD_memset(¶ms, 0, sizeof(params)); + params.cParams = cParams; + params.fParams.contentSizeFlag = 1; + return params; +} + +/*! ZSTD_getParams() : + * same idea as ZSTD_getCParams() + * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`). + * Fields of `ZSTD_frameParameters` are set to default values */ +ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) +{ + if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); +} + +void ZSTD_registerSequenceProducer( + ZSTD_CCtx* zc, + void* extSeqProdState, + ZSTD_sequenceProducer_F extSeqProdFunc) +{ + assert(zc != NULL); + ZSTD_CCtxParams_registerSequenceProducer( + &zc->requestedParams, extSeqProdState, extSeqProdFunc + ); +} + +void ZSTD_CCtxParams_registerSequenceProducer( + ZSTD_CCtx_params* params, + void* extSeqProdState, + ZSTD_sequenceProducer_F extSeqProdFunc) +{ + assert(params != NULL); + if (extSeqProdFunc != NULL) { + params->extSeqProdFunc = extSeqProdFunc; + params->extSeqProdState = extSeqProdState; + } else { + params->extSeqProdFunc = NULL; + params->extSeqProdState = NULL; + } +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_internal.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_internal.h new file mode 100644 index 000000000..ca5e2a4c5 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_internal.h @@ -0,0 +1,1636 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This header contains definitions + * that shall **only** be used by modules within lib/compress. + */ + +#ifndef ZSTD_COMPRESS_H +#define ZSTD_COMPRESS_H + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/zstd_internal.h" +#include "zstd_cwksp.h" +#ifdef ZSTD_MULTITHREAD +# include "zstdmt_compress.h" +#endif +#include "../common/bits.h" /* ZSTD_highbit32, ZSTD_NbCommonBytes */ +#include "zstd_preSplit.h" /* ZSTD_SLIPBLOCK_WORKSPACESIZE */ + +/*-************************************* +* Constants +***************************************/ +#define kSearchStrength 8 +#define HASH_READ_SIZE 8 +#define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means "unsorted". + It could be confused for a real successor at index "1", if sorted as larger than its predecessor. + It's not a big deal though : candidate will just be sorted again. + Additionally, candidate position 1 will be lost. + But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss. + The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table reuse with a different strategy. + This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */ + + +/*-************************************* +* Context memory management +***************************************/ +typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e; +typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage; + +typedef struct ZSTD_prefixDict_s { + const void* dict; + size_t dictSize; + ZSTD_dictContentType_e dictContentType; +} ZSTD_prefixDict; + +typedef struct { + void* dictBuffer; + void const* dict; + size_t dictSize; + ZSTD_dictContentType_e dictContentType; + ZSTD_CDict* cdict; +} ZSTD_localDict; + +typedef struct { + HUF_CElt CTable[HUF_CTABLE_SIZE_ST(255)]; + HUF_repeat repeatMode; +} ZSTD_hufCTables_t; + +typedef struct { + FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; + FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]; + FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]; + FSE_repeat offcode_repeatMode; + FSE_repeat matchlength_repeatMode; + FSE_repeat litlength_repeatMode; +} ZSTD_fseCTables_t; + +typedef struct { + ZSTD_hufCTables_t huf; + ZSTD_fseCTables_t fse; +} ZSTD_entropyCTables_t; + +/*********************************************** +* Sequences * +***********************************************/ +typedef struct SeqDef_s { + U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */ + U16 litLength; + U16 mlBase; /* mlBase == matchLength - MINMATCH */ +} SeqDef; + +/* Controls whether seqStore has a single "long" litLength or matchLength. See SeqStore_t. */ +typedef enum { + ZSTD_llt_none = 0, /* no longLengthType */ + ZSTD_llt_literalLength = 1, /* represents a long literal */ + ZSTD_llt_matchLength = 2 /* represents a long match */ +} ZSTD_longLengthType_e; + +typedef struct { + SeqDef* sequencesStart; + SeqDef* sequences; /* ptr to end of sequences */ + BYTE* litStart; + BYTE* lit; /* ptr to end of literals */ + BYTE* llCode; + BYTE* mlCode; + BYTE* ofCode; + size_t maxNbSeq; + size_t maxNbLit; + + /* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength + * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment + * the existing value of the litLength or matchLength by 0x10000. + */ + ZSTD_longLengthType_e longLengthType; + U32 longLengthPos; /* Index of the sequence to apply long length modification to */ +} SeqStore_t; + +typedef struct { + U32 litLength; + U32 matchLength; +} ZSTD_SequenceLength; + +/** + * Returns the ZSTD_SequenceLength for the given sequences. It handles the decoding of long sequences + * indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength. + */ +MEM_STATIC ZSTD_SequenceLength ZSTD_getSequenceLength(SeqStore_t const* seqStore, SeqDef const* seq) +{ + ZSTD_SequenceLength seqLen; + seqLen.litLength = seq->litLength; + seqLen.matchLength = seq->mlBase + MINMATCH; + if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) { + if (seqStore->longLengthType == ZSTD_llt_literalLength) { + seqLen.litLength += 0x10000; + } + if (seqStore->longLengthType == ZSTD_llt_matchLength) { + seqLen.matchLength += 0x10000; + } + } + return seqLen; +} + +const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */ +int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */ + + +/*********************************************** +* Entropy buffer statistics structs and funcs * +***********************************************/ +/** ZSTD_hufCTablesMetadata_t : + * Stores Literals Block Type for a super-block in hType, and + * huffman tree description in hufDesBuffer. + * hufDesSize refers to the size of huffman tree description in bytes. + * This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */ +typedef struct { + SymbolEncodingType_e hType; + BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE]; + size_t hufDesSize; +} ZSTD_hufCTablesMetadata_t; + +/** ZSTD_fseCTablesMetadata_t : + * Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and + * fse tables in fseTablesBuffer. + * fseTablesSize refers to the size of fse tables in bytes. + * This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */ +typedef struct { + SymbolEncodingType_e llType; + SymbolEncodingType_e ofType; + SymbolEncodingType_e mlType; + BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE]; + size_t fseTablesSize; + size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */ +} ZSTD_fseCTablesMetadata_t; + +typedef struct { + ZSTD_hufCTablesMetadata_t hufMetadata; + ZSTD_fseCTablesMetadata_t fseMetadata; +} ZSTD_entropyCTablesMetadata_t; + +/** ZSTD_buildBlockEntropyStats() : + * Builds entropy for the block. + * @return : 0 on success or error code */ +size_t ZSTD_buildBlockEntropyStats( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize); + +/********************************* +* Compression internals structs * +*********************************/ + +typedef struct { + U32 off; /* Offset sumtype code for the match, using ZSTD_storeSeq() format */ + U32 len; /* Raw length of match */ +} ZSTD_match_t; + +typedef struct { + U32 offset; /* Offset of sequence */ + U32 litLength; /* Length of literals prior to match */ + U32 matchLength; /* Raw length of match */ +} rawSeq; + +typedef struct { + rawSeq* seq; /* The start of the sequences */ + size_t pos; /* The index in seq where reading stopped. pos <= size. */ + size_t posInSequence; /* The position within the sequence at seq[pos] where reading + stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */ + size_t size; /* The number of sequences. <= capacity. */ + size_t capacity; /* The capacity starting from `seq` pointer */ +} RawSeqStore_t; + +UNUSED_ATTR static const RawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0}; + +typedef struct { + int price; /* price from beginning of segment to this position */ + U32 off; /* offset of previous match */ + U32 mlen; /* length of previous match */ + U32 litlen; /* nb of literals since previous match */ + U32 rep[ZSTD_REP_NUM]; /* offset history after previous match */ +} ZSTD_optimal_t; + +typedef enum { zop_dynamic=0, zop_predef } ZSTD_OptPrice_e; + +#define ZSTD_OPT_SIZE (ZSTD_OPT_NUM+3) +typedef struct { + /* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */ + unsigned* litFreq; /* table of literals statistics, of size 256 */ + unsigned* litLengthFreq; /* table of litLength statistics, of size (MaxLL+1) */ + unsigned* matchLengthFreq; /* table of matchLength statistics, of size (MaxML+1) */ + unsigned* offCodeFreq; /* table of offCode statistics, of size (MaxOff+1) */ + ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_SIZE */ + ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_SIZE */ + + U32 litSum; /* nb of literals */ + U32 litLengthSum; /* nb of litLength codes */ + U32 matchLengthSum; /* nb of matchLength codes */ + U32 offCodeSum; /* nb of offset codes */ + U32 litSumBasePrice; /* to compare to log2(litfreq) */ + U32 litLengthSumBasePrice; /* to compare to log2(llfreq) */ + U32 matchLengthSumBasePrice;/* to compare to log2(mlfreq) */ + U32 offCodeSumBasePrice; /* to compare to log2(offreq) */ + ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */ + const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */ + ZSTD_ParamSwitch_e literalCompressionMode; +} optState_t; + +typedef struct { + ZSTD_entropyCTables_t entropy; + U32 rep[ZSTD_REP_NUM]; +} ZSTD_compressedBlockState_t; + +typedef struct { + BYTE const* nextSrc; /* next block here to continue on current prefix */ + BYTE const* base; /* All regular indexes relative to this position */ + BYTE const* dictBase; /* extDict indexes relative to this position */ + U32 dictLimit; /* below that point, need extDict */ + U32 lowLimit; /* below that point, no more valid data */ + U32 nbOverflowCorrections; /* Number of times overflow correction has run since + * ZSTD_window_init(). Useful for debugging coredumps + * and for ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY. + */ +} ZSTD_window_t; + +#define ZSTD_WINDOW_START_INDEX 2 + +typedef struct ZSTD_MatchState_t ZSTD_MatchState_t; + +#define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */ + +struct ZSTD_MatchState_t { + ZSTD_window_t window; /* State for window round buffer management */ + U32 loadedDictEnd; /* index of end of dictionary, within context's referential. + * When loadedDictEnd != 0, a dictionary is in use, and still valid. + * This relies on a mechanism to set loadedDictEnd=0 when dictionary is no longer within distance. + * Such mechanism is provided within ZSTD_window_enforceMaxDist() and ZSTD_checkDictValidity(). + * When dict referential is copied into active context (i.e. not attached), + * loadedDictEnd == dictSize, since referential starts from zero. + */ + U32 nextToUpdate; /* index from which to continue table update */ + U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */ + + U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/ + BYTE* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */ + U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */ + U64 hashSalt; /* For row-based matchFinder: salts the hash for reuse of tag table */ + U32 hashSaltEntropy; /* For row-based matchFinder: collects entropy for salt generation */ + + U32* hashTable; + U32* hashTable3; + U32* chainTable; + + int forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */ + + int dedicatedDictSearch; /* Indicates whether this matchState is using the + * dedicated dictionary search structure. + */ + optState_t opt; /* optimal parser state */ + const ZSTD_MatchState_t* dictMatchState; + ZSTD_compressionParameters cParams; + const RawSeqStore_t* ldmSeqStore; + + /* Controls prefetching in some dictMatchState matchfinders. + * This behavior is controlled from the cctx ms. + * This parameter has no effect in the cdict ms. */ + int prefetchCDictTables; + + /* When == 0, lazy match finders insert every position. + * When != 0, lazy match finders only insert positions they search. + * This allows them to skip much faster over incompressible data, + * at a small cost to compression ratio. + */ + int lazySkipping; +}; + +typedef struct { + ZSTD_compressedBlockState_t* prevCBlock; + ZSTD_compressedBlockState_t* nextCBlock; + ZSTD_MatchState_t matchState; +} ZSTD_blockState_t; + +typedef struct { + U32 offset; + U32 checksum; +} ldmEntry_t; + +typedef struct { + BYTE const* split; + U32 hash; + U32 checksum; + ldmEntry_t* bucket; +} ldmMatchCandidate_t; + +#define LDM_BATCH_SIZE 64 + +typedef struct { + ZSTD_window_t window; /* State for the window round buffer management */ + ldmEntry_t* hashTable; + U32 loadedDictEnd; + BYTE* bucketOffsets; /* Next position in bucket to insert entry */ + size_t splitIndices[LDM_BATCH_SIZE]; + ldmMatchCandidate_t matchCandidates[LDM_BATCH_SIZE]; +} ldmState_t; + +typedef struct { + ZSTD_ParamSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */ + U32 hashLog; /* Log size of hashTable */ + U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */ + U32 minMatchLength; /* Minimum match length */ + U32 hashRateLog; /* Log number of entries to skip */ + U32 windowLog; /* Window log for the LDM */ +} ldmParams_t; + +typedef struct { + int collectSequences; + ZSTD_Sequence* seqStart; + size_t seqIndex; + size_t maxSequences; +} SeqCollector; + +struct ZSTD_CCtx_params_s { + ZSTD_format_e format; + ZSTD_compressionParameters cParams; + ZSTD_frameParameters fParams; + + int compressionLevel; + int forceWindow; /* force back-references to respect limit of + * 1< 63) ? ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength]; +} + +/* ZSTD_MLcode() : + * note : mlBase = matchLength - MINMATCH; + * because it's the format it's stored in seqStore->sequences */ +MEM_STATIC U32 ZSTD_MLcode(U32 mlBase) +{ + static const BYTE ML_Code[128] = { 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, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, + 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 }; + static const U32 ML_deltaCode = 36; + return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase]; +} + +/* ZSTD_cParam_withinBounds: + * @return 1 if value is within cParam bounds, + * 0 otherwise */ +MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value) +{ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); + if (ZSTD_isError(bounds.error)) return 0; + if (value < bounds.lowerBound) return 0; + if (value > bounds.upperBound) return 0; + return 1; +} + +/* ZSTD_selectAddr: + * @return index >= lowLimit ? candidate : backup, + * tries to force branchless codegen. */ +MEM_STATIC const BYTE* +ZSTD_selectAddr(U32 index, U32 lowLimit, const BYTE* candidate, const BYTE* backup) +{ +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ( + "cmp %1, %2\n" + "cmova %3, %0\n" + : "+r"(candidate) + : "r"(index), "r"(lowLimit), "r"(backup) + ); + return candidate; +#else + return index >= lowLimit ? candidate : backup; +#endif +} + +/* ZSTD_noCompressBlock() : + * Writes uncompressed block to dst buffer from given src. + * Returns the size of the block */ +MEM_STATIC size_t +ZSTD_noCompressBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock) +{ + U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3); + DEBUGLOG(5, "ZSTD_noCompressBlock (srcSize=%zu, dstCapacity=%zu)", srcSize, dstCapacity); + RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity, + dstSize_tooSmall, "dst buf too small for uncompressed block"); + MEM_writeLE24(dst, cBlockHeader24); + ZSTD_memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize); + return ZSTD_blockHeaderSize + srcSize; +} + +MEM_STATIC size_t +ZSTD_rleCompressBlock(void* dst, size_t dstCapacity, BYTE src, size_t srcSize, U32 lastBlock) +{ + BYTE* const op = (BYTE*)dst; + U32 const cBlockHeader = lastBlock + (((U32)bt_rle)<<1) + (U32)(srcSize << 3); + RETURN_ERROR_IF(dstCapacity < 4, dstSize_tooSmall, ""); + MEM_writeLE24(op, cBlockHeader); + op[3] = src; + return 4; +} + + +/* ZSTD_minGain() : + * minimum compression required + * to generate a compress block or a compressed literals section. + * note : use same formula for both situations */ +MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat) +{ + U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6; + ZSTD_STATIC_ASSERT(ZSTD_btultra == 8); + assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat)); + return (srcSize >> minlog) + 2; +} + +MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxParams) +{ + switch (cctxParams->literalCompressionMode) { + case ZSTD_ps_enable: + return 0; + case ZSTD_ps_disable: + return 1; + default: + assert(0 /* impossible: pre-validated */); + ZSTD_FALLTHROUGH; + case ZSTD_ps_auto: + return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0); + } +} + +/*! ZSTD_safecopyLiterals() : + * memcpy() function that won't read beyond more than WILDCOPY_OVERLENGTH bytes past ilimit_w. + * Only called when the sequence ends past ilimit_w, so it only needs to be optimized for single + * large copies. + */ +static void +ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE const* ilimit_w) +{ + assert(iend > ilimit_w); + if (ip <= ilimit_w) { + ZSTD_wildcopy(op, ip, ilimit_w - ip, ZSTD_no_overlap); + op += ilimit_w - ip; + ip = ilimit_w; + } + while (ip < iend) *op++ = *ip++; +} + + +#define REPCODE1_TO_OFFBASE REPCODE_TO_OFFBASE(1) +#define REPCODE2_TO_OFFBASE REPCODE_TO_OFFBASE(2) +#define REPCODE3_TO_OFFBASE REPCODE_TO_OFFBASE(3) +#define REPCODE_TO_OFFBASE(r) (assert((r)>=1), assert((r)<=ZSTD_REP_NUM), (r)) /* accepts IDs 1,2,3 */ +#define OFFSET_TO_OFFBASE(o) (assert((o)>0), o + ZSTD_REP_NUM) +#define OFFBASE_IS_OFFSET(o) ((o) > ZSTD_REP_NUM) +#define OFFBASE_IS_REPCODE(o) ( 1 <= (o) && (o) <= ZSTD_REP_NUM) +#define OFFBASE_TO_OFFSET(o) (assert(OFFBASE_IS_OFFSET(o)), (o) - ZSTD_REP_NUM) +#define OFFBASE_TO_REPCODE(o) (assert(OFFBASE_IS_REPCODE(o)), (o)) /* returns ID 1,2,3 */ + +/*! ZSTD_storeSeqOnly() : + * Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t. + * Literals themselves are not copied, but @litPtr is updated. + * @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE(). + * @matchLength : must be >= MINMATCH +*/ +HINT_INLINE UNUSED_ATTR void +ZSTD_storeSeqOnly(SeqStore_t* seqStorePtr, + size_t litLength, + U32 offBase, + size_t matchLength) +{ + assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq); + + /* literal Length */ + assert(litLength <= ZSTD_BLOCKSIZE_MAX); + if (UNLIKELY(litLength>0xFFFF)) { + assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */ + seqStorePtr->longLengthType = ZSTD_llt_literalLength; + seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + } + seqStorePtr->sequences[0].litLength = (U16)litLength; + + /* match offset */ + seqStorePtr->sequences[0].offBase = offBase; + + /* match Length */ + assert(matchLength <= ZSTD_BLOCKSIZE_MAX); + assert(matchLength >= MINMATCH); + { size_t const mlBase = matchLength - MINMATCH; + if (UNLIKELY(mlBase>0xFFFF)) { + assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */ + seqStorePtr->longLengthType = ZSTD_llt_matchLength; + seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + } + seqStorePtr->sequences[0].mlBase = (U16)mlBase; + } + + seqStorePtr->sequences++; +} + +/*! ZSTD_storeSeq() : + * Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t. + * @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE(). + * @matchLength : must be >= MINMATCH + * Allowed to over-read literals up to litLimit. +*/ +HINT_INLINE UNUSED_ATTR void +ZSTD_storeSeq(SeqStore_t* seqStorePtr, + size_t litLength, const BYTE* literals, const BYTE* litLimit, + U32 offBase, + size_t matchLength) +{ + BYTE const* const litLimit_w = litLimit - WILDCOPY_OVERLENGTH; + BYTE const* const litEnd = literals + litLength; +#if defined(DEBUGLEVEL) && (DEBUGLEVEL >= 6) + static const BYTE* g_start = NULL; + if (g_start==NULL) g_start = (const BYTE*)literals; /* note : index only works for compression within a single segment */ + { U32 const pos = (U32)((const BYTE*)literals - g_start); + DEBUGLOG(6, "Cpos%7u :%3u literals, match%4u bytes at offBase%7u", + pos, (U32)litLength, (U32)matchLength, (U32)offBase); + } +#endif + assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq); + /* copy Literals */ + assert(seqStorePtr->maxNbLit <= 128 KB); + assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit); + assert(literals + litLength <= litLimit); + if (litEnd <= litLimit_w) { + /* Common case we can use wildcopy. + * First copy 16 bytes, because literals are likely short. + */ + ZSTD_STATIC_ASSERT(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(seqStorePtr->lit, literals); + if (litLength > 16) { + ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, (ptrdiff_t)litLength-16, ZSTD_no_overlap); + } + } else { + ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w); + } + seqStorePtr->lit += litLength; + + ZSTD_storeSeqOnly(seqStorePtr, litLength, offBase, matchLength); +} + +/* ZSTD_updateRep() : + * updates in-place @rep (array of repeat offsets) + * @offBase : sum-type, using numeric representation of ZSTD_storeSeq() + */ +MEM_STATIC void +ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0) +{ + if (OFFBASE_IS_OFFSET(offBase)) { /* full offset */ + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = OFFBASE_TO_OFFSET(offBase); + } else { /* repcode */ + U32 const repCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; + if (repCode > 0) { /* note : if repCode==0, no change */ + U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode]; + rep[2] = (repCode >= 2) ? rep[1] : rep[2]; + rep[1] = rep[0]; + rep[0] = currentOffset; + } else { /* repCode == 0 */ + /* nothing to do */ + } + } +} + +typedef struct repcodes_s { + U32 rep[3]; +} Repcodes_t; + +MEM_STATIC Repcodes_t +ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0) +{ + Repcodes_t newReps; + ZSTD_memcpy(&newReps, rep, sizeof(newReps)); + ZSTD_updateRep(newReps.rep, offBase, ll0); + return newReps; +} + + +/*-************************************* +* Match length counter +***************************************/ +MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit) +{ + const BYTE* const pStart = pIn; + const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1); + + if (pIn < pInLoopLimit) { + { size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); + if (diff) return ZSTD_NbCommonBytes(diff); } + pIn+=sizeof(size_t); pMatch+=sizeof(size_t); + while (pIn < pInLoopLimit) { + size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); + if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; } + pIn += ZSTD_NbCommonBytes(diff); + return (size_t)(pIn - pStart); + } } + if (MEM_64bits() && (pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; } + if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; } + if ((pIn> (32-h) ; } +MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h, 0); } /* only in zstd_opt.h */ +MEM_STATIC size_t ZSTD_hash3PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash3(MEM_readLE32(ptr), h, s); } + +static const U32 prime4bytes = 2654435761U; +static U32 ZSTD_hash4(U32 u, U32 h, U32 s) { assert(h <= 32); return ((u * prime4bytes) ^ s) >> (32-h) ; } +static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_readLE32(ptr), h, 0); } +static size_t ZSTD_hash4PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash4(MEM_readLE32(ptr), h, s); } + +static const U64 prime5bytes = 889523592379ULL; +static size_t ZSTD_hash5(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-40)) * prime5bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash5PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash5(MEM_readLE64(p), h, s); } + +static const U64 prime6bytes = 227718039650203ULL; +static size_t ZSTD_hash6(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-48)) * prime6bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash6PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash6(MEM_readLE64(p), h, s); } + +static const U64 prime7bytes = 58295818150454627ULL; +static size_t ZSTD_hash7(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-56)) * prime7bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash7PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash7(MEM_readLE64(p), h, s); } + +static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL; +static size_t ZSTD_hash8(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u) * prime8bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash8PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash8(MEM_readLE64(p), h, s); } + + +MEM_STATIC FORCE_INLINE_ATTR +size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) +{ + /* Although some of these hashes do support hBits up to 64, some do not. + * To be on the safe side, always avoid hBits > 32. */ + assert(hBits <= 32); + + switch(mls) + { + default: + case 4: return ZSTD_hash4Ptr(p, hBits); + case 5: return ZSTD_hash5Ptr(p, hBits); + case 6: return ZSTD_hash6Ptr(p, hBits); + case 7: return ZSTD_hash7Ptr(p, hBits); + case 8: return ZSTD_hash8Ptr(p, hBits); + } +} + +MEM_STATIC FORCE_INLINE_ATTR +size_t ZSTD_hashPtrSalted(const void* p, U32 hBits, U32 mls, const U64 hashSalt) { + /* Although some of these hashes do support hBits up to 64, some do not. + * To be on the safe side, always avoid hBits > 32. */ + assert(hBits <= 32); + + switch(mls) + { + default: + case 4: return ZSTD_hash4PtrS(p, hBits, (U32)hashSalt); + case 5: return ZSTD_hash5PtrS(p, hBits, hashSalt); + case 6: return ZSTD_hash6PtrS(p, hBits, hashSalt); + case 7: return ZSTD_hash7PtrS(p, hBits, hashSalt); + case 8: return ZSTD_hash8PtrS(p, hBits, hashSalt); + } +} + + +/** ZSTD_ipow() : + * Return base^exponent. + */ +static U64 ZSTD_ipow(U64 base, U64 exponent) +{ + U64 power = 1; + while (exponent) { + if (exponent & 1) power *= base; + exponent >>= 1; + base *= base; + } + return power; +} + +#define ZSTD_ROLL_HASH_CHAR_OFFSET 10 + +/** ZSTD_rollingHash_append() : + * Add the buffer to the hash value. + */ +static U64 ZSTD_rollingHash_append(U64 hash, void const* buf, size_t size) +{ + BYTE const* istart = (BYTE const*)buf; + size_t pos; + for (pos = 0; pos < size; ++pos) { + hash *= prime8bytes; + hash += istart[pos] + ZSTD_ROLL_HASH_CHAR_OFFSET; + } + return hash; +} + +/** ZSTD_rollingHash_compute() : + * Compute the rolling hash value of the buffer. + */ +MEM_STATIC U64 ZSTD_rollingHash_compute(void const* buf, size_t size) +{ + return ZSTD_rollingHash_append(0, buf, size); +} + +/** ZSTD_rollingHash_primePower() : + * Compute the primePower to be passed to ZSTD_rollingHash_rotate() for a hash + * over a window of length bytes. + */ +MEM_STATIC U64 ZSTD_rollingHash_primePower(U32 length) +{ + return ZSTD_ipow(prime8bytes, length - 1); +} + +/** ZSTD_rollingHash_rotate() : + * Rotate the rolling hash by one byte. + */ +MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64 primePower) +{ + hash -= (toRemove + ZSTD_ROLL_HASH_CHAR_OFFSET) * primePower; + hash *= prime8bytes; + hash += toAdd + ZSTD_ROLL_HASH_CHAR_OFFSET; + return hash; +} + +/*-************************************* +* Round buffer management +***************************************/ +/* Max @current value allowed: + * In 32-bit mode: we want to avoid crossing the 2 GB limit, + * reducing risks of side effects in case of signed operations on indexes. + * In 64-bit mode: we want to ensure that adding the maximum job size (512 MB) + * doesn't overflow U32 index capacity (4 GB) */ +#define ZSTD_CURRENT_MAX (MEM_64bits() ? 3500U MB : 2000U MB) +/* Maximum chunk size before overflow correction needs to be called again */ +#define ZSTD_CHUNKSIZE_MAX \ + ( ((U32)-1) /* Maximum ending current index */ \ + - ZSTD_CURRENT_MAX) /* Maximum beginning lowLimit */ + +/** + * ZSTD_window_clear(): + * Clears the window containing the history by simply setting it to empty. + */ +MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window) +{ + size_t const endT = (size_t)(window->nextSrc - window->base); + U32 const end = (U32)endT; + + window->lowLimit = end; + window->dictLimit = end; +} + +MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window) +{ + return window.dictLimit == ZSTD_WINDOW_START_INDEX && + window.lowLimit == ZSTD_WINDOW_START_INDEX && + (window.nextSrc - window.base) == ZSTD_WINDOW_START_INDEX; +} + +/** + * ZSTD_window_hasExtDict(): + * Returns non-zero if the window has a non-empty extDict. + */ +MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window) +{ + return window.lowLimit < window.dictLimit; +} + +/** + * ZSTD_matchState_dictMode(): + * Inspects the provided matchState and figures out what dictMode should be + * passed to the compressor. + */ +MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_MatchState_t *ms) +{ + return ZSTD_window_hasExtDict(ms->window) ? + ZSTD_extDict : + ms->dictMatchState != NULL ? + (ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) : + ZSTD_noDict; +} + +/* Defining this macro to non-zero tells zstd to run the overflow correction + * code much more frequently. This is very inefficient, and should only be + * used for tests and fuzzers. + */ +#ifndef ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY +# ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 1 +# else +# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 0 +# endif +#endif + +/** + * ZSTD_window_canOverflowCorrect(): + * Returns non-zero if the indices are large enough for overflow correction + * to work correctly without impacting compression ratio. + */ +MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window, + U32 cycleLog, + U32 maxDist, + U32 loadedDictEnd, + void const* src) +{ + U32 const cycleSize = 1u << cycleLog; + U32 const curr = (U32)((BYTE const*)src - window.base); + U32 const minIndexToOverflowCorrect = cycleSize + + MAX(maxDist, cycleSize) + + ZSTD_WINDOW_START_INDEX; + + /* Adjust the min index to backoff the overflow correction frequency, + * so we don't waste too much CPU in overflow correction. If this + * computation overflows we don't really care, we just need to make + * sure it is at least minIndexToOverflowCorrect. + */ + U32 const adjustment = window.nbOverflowCorrections + 1; + U32 const adjustedIndex = MAX(minIndexToOverflowCorrect * adjustment, + minIndexToOverflowCorrect); + U32 const indexLargeEnough = curr > adjustedIndex; + + /* Only overflow correct early if the dictionary is invalidated already, + * so we don't hurt compression ratio. + */ + U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd; + + return indexLargeEnough && dictionaryInvalidated; +} + +/** + * ZSTD_window_needOverflowCorrection(): + * Returns non-zero if the indices are getting too large and need overflow + * protection. + */ +MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window, + U32 cycleLog, + U32 maxDist, + U32 loadedDictEnd, + void const* src, + void const* srcEnd) +{ + U32 const curr = (U32)((BYTE const*)srcEnd - window.base); + if (ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) { + if (ZSTD_window_canOverflowCorrect(window, cycleLog, maxDist, loadedDictEnd, src)) { + return 1; + } + } + return curr > ZSTD_CURRENT_MAX; +} + +/** + * ZSTD_window_correctOverflow(): + * Reduces the indices to protect from index overflow. + * Returns the correction made to the indices, which must be applied to every + * stored index. + * + * The least significant cycleLog bits of the indices must remain the same, + * which may be 0. Every index up to maxDist in the past must be valid. + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, + U32 maxDist, void const* src) +{ + /* preemptive overflow correction: + * 1. correction is large enough: + * lowLimit > (3<<29) ==> current > 3<<29 + 1< (3<<29 + 1< (3<<29) - (1< (3<<29) - (1<<30) (NOTE: chainLog <= 30) + * > 1<<29 + * + * 2. (ip+ZSTD_CHUNKSIZE_MAX - cctx->base) doesn't overflow: + * After correction, current is less than (1<base < 1<<32. + * 3. (cctx->lowLimit + 1< 3<<29 + 1<base); + U32 const currentCycle = curr & cycleMask; + /* Ensure newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX. */ + U32 const currentCycleCorrection = currentCycle < ZSTD_WINDOW_START_INDEX + ? MAX(cycleSize, ZSTD_WINDOW_START_INDEX) + : 0; + U32 const newCurrent = currentCycle + + currentCycleCorrection + + MAX(maxDist, cycleSize); + U32 const correction = curr - newCurrent; + /* maxDist must be a power of two so that: + * (newCurrent & cycleMask) == (curr & cycleMask) + * This is required to not corrupt the chains / binary tree. + */ + assert((maxDist & (maxDist - 1)) == 0); + assert((curr & cycleMask) == (newCurrent & cycleMask)); + assert(curr > newCurrent); + if (!ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) { + /* Loose bound, should be around 1<<29 (see above) */ + assert(correction > 1<<28); + } + + window->base += correction; + window->dictBase += correction; + if (window->lowLimit < correction + ZSTD_WINDOW_START_INDEX) { + window->lowLimit = ZSTD_WINDOW_START_INDEX; + } else { + window->lowLimit -= correction; + } + if (window->dictLimit < correction + ZSTD_WINDOW_START_INDEX) { + window->dictLimit = ZSTD_WINDOW_START_INDEX; + } else { + window->dictLimit -= correction; + } + + /* Ensure we can still reference the full window. */ + assert(newCurrent >= maxDist); + assert(newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX); + /* Ensure that lowLimit and dictLimit didn't underflow. */ + assert(window->lowLimit <= newCurrent); + assert(window->dictLimit <= newCurrent); + + ++window->nbOverflowCorrections; + + DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction, + window->lowLimit); + return correction; +} + +/** + * ZSTD_window_enforceMaxDist(): + * Updates lowLimit so that: + * (srcEnd - base) - lowLimit == maxDist + loadedDictEnd + * + * It ensures index is valid as long as index >= lowLimit. + * This must be called before a block compression call. + * + * loadedDictEnd is only defined if a dictionary is in use for current compression. + * As the name implies, loadedDictEnd represents the index at end of dictionary. + * The value lies within context's referential, it can be directly compared to blockEndIdx. + * + * If loadedDictEndPtr is NULL, no dictionary is in use, and we use loadedDictEnd == 0. + * If loadedDictEndPtr is not NULL, we set it to zero after updating lowLimit. + * This is because dictionaries are allowed to be referenced fully + * as long as the last byte of the dictionary is in the window. + * Once input has progressed beyond window size, dictionary cannot be referenced anymore. + * + * In normal dict mode, the dictionary lies between lowLimit and dictLimit. + * In dictMatchState mode, lowLimit and dictLimit are the same, + * and the dictionary is below them. + * forceWindow and dictMatchState are therefore incompatible. + */ +MEM_STATIC void +ZSTD_window_enforceMaxDist(ZSTD_window_t* window, + const void* blockEnd, + U32 maxDist, + U32* loadedDictEndPtr, + const ZSTD_MatchState_t** dictMatchStatePtr) +{ + U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base); + U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0; + DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u", + (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd); + + /* - When there is no dictionary : loadedDictEnd == 0. + In which case, the test (blockEndIdx > maxDist) is merely to avoid + overflowing next operation `newLowLimit = blockEndIdx - maxDist`. + - When there is a standard dictionary : + Index referential is copied from the dictionary, + which means it starts from 0. + In which case, loadedDictEnd == dictSize, + and it makes sense to compare `blockEndIdx > maxDist + dictSize` + since `blockEndIdx` also starts from zero. + - When there is an attached dictionary : + loadedDictEnd is expressed within the referential of the context, + so it can be directly compared against blockEndIdx. + */ + if (blockEndIdx > maxDist + loadedDictEnd) { + U32 const newLowLimit = blockEndIdx - maxDist; + if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit; + if (window->dictLimit < window->lowLimit) { + DEBUGLOG(5, "Update dictLimit to match lowLimit, from %u to %u", + (unsigned)window->dictLimit, (unsigned)window->lowLimit); + window->dictLimit = window->lowLimit; + } + /* On reaching window size, dictionaries are invalidated */ + if (loadedDictEndPtr) *loadedDictEndPtr = 0; + if (dictMatchStatePtr) *dictMatchStatePtr = NULL; + } +} + +/* Similar to ZSTD_window_enforceMaxDist(), + * but only invalidates dictionary + * when input progresses beyond window size. + * assumption : loadedDictEndPtr and dictMatchStatePtr are valid (non NULL) + * loadedDictEnd uses same referential as window->base + * maxDist is the window size */ +MEM_STATIC void +ZSTD_checkDictValidity(const ZSTD_window_t* window, + const void* blockEnd, + U32 maxDist, + U32* loadedDictEndPtr, + const ZSTD_MatchState_t** dictMatchStatePtr) +{ + assert(loadedDictEndPtr != NULL); + assert(dictMatchStatePtr != NULL); + { U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base); + U32 const loadedDictEnd = *loadedDictEndPtr; + DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u", + (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd); + assert(blockEndIdx >= loadedDictEnd); + + if (blockEndIdx > loadedDictEnd + maxDist || loadedDictEnd != window->dictLimit) { + /* On reaching window size, dictionaries are invalidated. + * For simplification, if window size is reached anywhere within next block, + * the dictionary is invalidated for the full block. + * + * We also have to invalidate the dictionary if ZSTD_window_update() has detected + * non-contiguous segments, which means that loadedDictEnd != window->dictLimit. + * loadedDictEnd may be 0, if forceWindow is true, but in that case we never use + * dictMatchState, so setting it to NULL is not a problem. + */ + DEBUGLOG(6, "invalidating dictionary for current block (distance > windowSize)"); + *loadedDictEndPtr = 0; + *dictMatchStatePtr = NULL; + } else { + if (*loadedDictEndPtr != 0) { + DEBUGLOG(6, "dictionary considered valid for current block"); + } } } +} + +MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) { + ZSTD_memset(window, 0, sizeof(*window)); + window->base = (BYTE const*)" "; + window->dictBase = (BYTE const*)" "; + ZSTD_STATIC_ASSERT(ZSTD_DUBT_UNSORTED_MARK < ZSTD_WINDOW_START_INDEX); /* Start above ZSTD_DUBT_UNSORTED_MARK */ + window->dictLimit = ZSTD_WINDOW_START_INDEX; /* start from >0, so that 1st position is valid */ + window->lowLimit = ZSTD_WINDOW_START_INDEX; /* it ensures first and later CCtx usages compress the same */ + window->nextSrc = window->base + ZSTD_WINDOW_START_INDEX; /* see issue #1241 */ + window->nbOverflowCorrections = 0; +} + +/** + * ZSTD_window_update(): + * Updates the window by appending [src, src + srcSize) to the window. + * If it is not contiguous, the current prefix becomes the extDict, and we + * forget about the extDict. Handles overlap of the prefix and extDict. + * Returns non-zero if the segment is contiguous. + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_window_update(ZSTD_window_t* window, + const void* src, size_t srcSize, + int forceNonContiguous) +{ + BYTE const* const ip = (BYTE const*)src; + U32 contiguous = 1; + DEBUGLOG(5, "ZSTD_window_update"); + if (srcSize == 0) + return contiguous; + assert(window->base != NULL); + assert(window->dictBase != NULL); + /* Check if blocks follow each other */ + if (src != window->nextSrc || forceNonContiguous) { + /* not contiguous */ + size_t const distanceFromBase = (size_t)(window->nextSrc - window->base); + DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit); + window->lowLimit = window->dictLimit; + assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */ + window->dictLimit = (U32)distanceFromBase; + window->dictBase = window->base; + window->base = ip - distanceFromBase; + /* ms->nextToUpdate = window->dictLimit; */ + if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit; /* too small extDict */ + contiguous = 0; + } + window->nextSrc = ip + srcSize; + /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */ + if ( (ip+srcSize > window->dictBase + window->lowLimit) + & (ip < window->dictBase + window->dictLimit)) { + size_t const highInputIdx = (size_t)((ip + srcSize) - window->dictBase); + U32 const lowLimitMax = (highInputIdx > (size_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx; + assert(highInputIdx < UINT_MAX); + window->lowLimit = lowLimitMax; + DEBUGLOG(5, "Overlapping extDict and input : new lowLimit = %u", window->lowLimit); + } + return contiguous; +} + +/** + * Returns the lowest allowed match index. It may either be in the ext-dict or the prefix. + */ +MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog) +{ + U32 const maxDistance = 1U << windowLog; + U32 const lowestValid = ms->window.lowLimit; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + U32 const isDictionary = (ms->loadedDictEnd != 0); + /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary + * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't + * valid for the entire block. So this check is sufficient to find the lowest valid match index. + */ + U32 const matchLowest = isDictionary ? lowestValid : withinWindow; + return matchLowest; +} + +/** + * Returns the lowest allowed match index in the prefix. + */ +MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog) +{ + U32 const maxDistance = 1U << windowLog; + U32 const lowestValid = ms->window.dictLimit; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + U32 const isDictionary = (ms->loadedDictEnd != 0); + /* When computing the lowest prefix index we need to take the dictionary into account to handle + * the edge case where the dictionary and the source are contiguous in memory. + */ + U32 const matchLowest = isDictionary ? lowestValid : withinWindow; + return matchLowest; +} + +/* index_safety_check: + * intentional underflow : ensure repIndex isn't overlapping dict + prefix + * @return 1 if values are not overlapping, + * 0 otherwise */ +MEM_STATIC int ZSTD_index_overlap_check(const U32 prefixLowestIndex, const U32 repIndex) { + return ((U32)((prefixLowestIndex-1) - repIndex) >= 3); +} + + +/* debug functions */ +#if (DEBUGLEVEL>=2) + +MEM_STATIC double ZSTD_fWeight(U32 rawStat) +{ + U32 const fp_accuracy = 8; + U32 const fp_multiplier = (1 << fp_accuracy); + U32 const newStat = rawStat + 1; + U32 const hb = ZSTD_highbit32(newStat); + U32 const BWeight = hb * fp_multiplier; + U32 const FWeight = (newStat << fp_accuracy) >> hb; + U32 const weight = BWeight + FWeight; + assert(hb + fp_accuracy < 31); + return (double)weight / fp_multiplier; +} + +/* display a table content, + * listing each element, its frequency, and its predicted bit cost */ +MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max) +{ + unsigned u, sum; + for (u=0, sum=0; u<=max; u++) sum += table[u]; + DEBUGLOG(2, "total nb elts: %u", sum); + for (u=0; u<=max; u++) { + DEBUGLOG(2, "%2u: %5u (%.2f)", + u, table[u], ZSTD_fWeight(sum) - ZSTD_fWeight(table[u]) ); + } +} + +#endif + +/* Short Cache */ + +/* Normally, zstd matchfinders follow this flow: + * 1. Compute hash at ip + * 2. Load index from hashTable[hash] + * 3. Check if *ip == *(base + index) + * In dictionary compression, loading *(base + index) is often an L2 or even L3 miss. + * + * Short cache is an optimization which allows us to avoid step 3 most of the time + * when the data doesn't actually match. With short cache, the flow becomes: + * 1. Compute (hash, currentTag) at ip. currentTag is an 8-bit independent hash at ip. + * 2. Load (index, matchTag) from hashTable[hash]. See ZSTD_writeTaggedIndex to understand how this works. + * 3. Only if currentTag == matchTag, check *ip == *(base + index). Otherwise, continue. + * + * Currently, short cache is only implemented in CDict hashtables. Thus, its use is limited to + * dictMatchState matchfinders. + */ +#define ZSTD_SHORT_CACHE_TAG_BITS 8 +#define ZSTD_SHORT_CACHE_TAG_MASK ((1u << ZSTD_SHORT_CACHE_TAG_BITS) - 1) + +/* Helper function for ZSTD_fillHashTable and ZSTD_fillDoubleHashTable. + * Unpacks hashAndTag into (hash, tag), then packs (index, tag) into hashTable[hash]. */ +MEM_STATIC void ZSTD_writeTaggedIndex(U32* const hashTable, size_t hashAndTag, U32 index) { + size_t const hash = hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS; + U32 const tag = (U32)(hashAndTag & ZSTD_SHORT_CACHE_TAG_MASK); + assert(index >> (32 - ZSTD_SHORT_CACHE_TAG_BITS) == 0); + hashTable[hash] = (index << ZSTD_SHORT_CACHE_TAG_BITS) | tag; +} + +/* Helper function for short cache matchfinders. + * Unpacks tag1 and tag2 from lower bits of packedTag1 and packedTag2, then checks if the tags match. */ +MEM_STATIC int ZSTD_comparePackedTags(size_t packedTag1, size_t packedTag2) { + U32 const tag1 = packedTag1 & ZSTD_SHORT_CACHE_TAG_MASK; + U32 const tag2 = packedTag2 & ZSTD_SHORT_CACHE_TAG_MASK; + return tag1 == tag2; +} + +/* =============================================================== + * Shared internal declarations + * These prototypes may be called from sources not in lib/compress + * =============================================================== */ + +/* ZSTD_loadCEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * return : size of dictionary header (size of magic number + dict ID + entropy tables) + * assumptions : magic number supposed already checked + * and dictSize >= 8 */ +size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, + const void* const dict, size_t dictSize); + +void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs); + +typedef struct { + U32 idx; /* Index in array of ZSTD_Sequence */ + U32 posInSequence; /* Position within sequence at idx */ + size_t posInSrc; /* Number of bytes given by sequences provided so far */ +} ZSTD_SequencePosition; + +/* for benchmark */ +size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx, + const ZSTD_Sequence* const inSeqs, size_t nbSequences, + int const repcodeResolution); + +typedef struct { + size_t nbSequences; + size_t blockSize; + size_t litSize; +} BlockSummary; + +BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs); + +/* ============================================================== + * Private declarations + * These prototypes shall only be called from within lib/compress + * ============================================================== */ + +/* ZSTD_getCParamsFromCCtxParams() : + * cParams are built depending on compressionLevel, src size hints, + * LDM and manually set compression parameters. + * Note: srcSizeHint == 0 means 0! + */ +ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( + const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); + +/*! ZSTD_initCStream_internal() : + * Private use only. Init streaming operation. + * expects params to be valid. + * must receive dict, or cdict, or none, but not both. + * @return : 0, or an error code */ +size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, + const void* dict, size_t dictSize, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, unsigned long long pledgedSrcSize); + +void ZSTD_resetSeqStore(SeqStore_t* ssPtr); + +/*! ZSTD_getCParamsFromCDict() : + * as the name implies */ +ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict); + +/* ZSTD_compressBegin_advanced_internal() : + * Private use only. To be called from zstdmt_compress.c. */ +size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + unsigned long long pledgedSrcSize); + +/* ZSTD_compress_advanced_internal() : + * Private use only. To be called from zstdmt_compress.c. */ +size_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + const ZSTD_CCtx_params* params); + + +/* ZSTD_writeLastEmptyBlock() : + * output an empty Block with end-of-frame mark to complete a frame + * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h)) + * or an error code if `dstCapacity` is too small ( 1 */ +U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat); + +/** ZSTD_CCtx_trace() : + * Trace the end of a compression call. + */ +void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize); + +/* Returns 1 if an external sequence producer is registered, otherwise returns 0. */ +MEM_STATIC int ZSTD_hasExtSeqProd(const ZSTD_CCtx_params* params) { + return params->extSeqProdFunc != NULL; +} + +/* =============================================================== + * Deprecated definitions that are still used internally to avoid + * deprecation warnings. These functions are exactly equivalent to + * their public variants, but avoid the deprecation warnings. + * =============================================================== */ + +size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); + +size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + + +#endif /* ZSTD_COMPRESS_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_literals.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_literals.c new file mode 100644 index 000000000..06036de5d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_literals.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_literals.h" + + +/* ************************************************************** +* Debug Traces +****************************************************************/ +#if DEBUGLEVEL >= 2 + +static size_t showHexa(const void* src, size_t srcSize) +{ + const BYTE* const ip = (const BYTE*)src; + size_t u; + for (u=0; u31) + (srcSize>4095); + + DEBUGLOG(5, "ZSTD_noCompressLiterals: srcSize=%zu, dstCapacity=%zu", srcSize, dstCapacity); + + RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall, ""); + + switch(flSize) + { + case 1: /* 2 - 1 - 5 */ + ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3)); + break; + case 2: /* 2 - 2 - 12 */ + MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4))); + break; + case 3: /* 2 - 2 - 20 */ + MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4))); + break; + default: /* not necessary : flSize is {1,2,3} */ + assert(0); + } + + ZSTD_memcpy(ostart + flSize, src, srcSize); + DEBUGLOG(5, "Raw (uncompressed) literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize)); + return srcSize + flSize; +} + +static int allBytesIdentical(const void* src, size_t srcSize) +{ + assert(srcSize >= 1); + assert(src != NULL); + { const BYTE b = ((const BYTE*)src)[0]; + size_t p; + for (p=1; p31) + (srcSize>4095); + + assert(dstCapacity >= 4); (void)dstCapacity; + assert(allBytesIdentical(src, srcSize)); + + switch(flSize) + { + case 1: /* 2 - 1 - 5 */ + ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3)); + break; + case 2: /* 2 - 2 - 12 */ + MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4))); + break; + case 3: /* 2 - 2 - 20 */ + MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4))); + break; + default: /* not necessary : flSize is {1,2,3} */ + assert(0); + } + + ostart[flSize] = *(const BYTE*)src; + DEBUGLOG(5, "RLE : Repeated Literal (%02X: %u times) -> %u bytes encoded", ((const BYTE*)src)[0], (U32)srcSize, (U32)flSize + 1); + return flSize+1; +} + +/* ZSTD_minLiteralsToCompress() : + * returns minimal amount of literals + * for literal compression to even be attempted. + * Minimum is made tighter as compression strategy increases. + */ +static size_t +ZSTD_minLiteralsToCompress(ZSTD_strategy strategy, HUF_repeat huf_repeat) +{ + assert((int)strategy >= 0); + assert((int)strategy <= 9); + /* btultra2 : min 8 bytes; + * then 2x larger for each successive compression strategy + * max threshold 64 bytes */ + { int const shift = MIN(9-(int)strategy, 3); + size_t const mintc = (huf_repeat == HUF_repeat_valid) ? 6 : (size_t)8 << shift; + DEBUGLOG(7, "minLiteralsToCompress = %zu", mintc); + return mintc; + } +} + +size_t ZSTD_compressLiterals ( + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + void* entropyWorkspace, size_t entropyWorkspaceSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_strategy strategy, + int disableLiteralCompression, + int suspectUncompressible, + int bmi2) +{ + size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); + BYTE* const ostart = (BYTE*)dst; + U32 singleStream = srcSize < 256; + SymbolEncodingType_e hType = set_compressed; + size_t cLitSize; + + DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i, srcSize=%u, dstCapacity=%zu)", + disableLiteralCompression, (U32)srcSize, dstCapacity); + + DEBUGLOG(6, "Completed literals listing (%zu bytes)", showHexa(src, srcSize)); + + /* Prepare nextEntropy assuming reusing the existing table */ + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + + if (disableLiteralCompression) + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + + /* if too small, don't even attempt compression (speed opt) */ + if (srcSize < ZSTD_minLiteralsToCompress(strategy, prevHuf->repeatMode)) + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + + RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression"); + { HUF_repeat repeat = prevHuf->repeatMode; + int const flags = 0 + | (bmi2 ? HUF_flags_bmi2 : 0) + | (strategy < ZSTD_lazy && srcSize <= 1024 ? HUF_flags_preferRepeat : 0) + | (strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD ? HUF_flags_optimalDepth : 0) + | (suspectUncompressible ? HUF_flags_suspectUncompressible : 0); + + typedef size_t (*huf_compress_f)(void*, size_t, const void*, size_t, unsigned, unsigned, void*, size_t, HUF_CElt*, HUF_repeat*, int); + huf_compress_f huf_compress; + if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1; + huf_compress = singleStream ? HUF_compress1X_repeat : HUF_compress4X_repeat; + cLitSize = huf_compress(ostart+lhSize, dstCapacity-lhSize, + src, srcSize, + HUF_SYMBOLVALUE_MAX, LitHufLog, + entropyWorkspace, entropyWorkspaceSize, + (HUF_CElt*)nextHuf->CTable, + &repeat, flags); + DEBUGLOG(5, "%zu literals compressed into %zu bytes (before header)", srcSize, cLitSize); + if (repeat != HUF_repeat_none) { + /* reused the existing table */ + DEBUGLOG(5, "reusing statistics from previous huffman block"); + hType = set_repeat; + } + } + + { size_t const minGain = ZSTD_minGain(srcSize, strategy); + if ((cLitSize==0) || (cLitSize >= srcSize - minGain) || ERR_isError(cLitSize)) { + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + } } + if (cLitSize==1) { + /* A return value of 1 signals that the alphabet consists of a single symbol. + * However, in some rare circumstances, it could be the compressed size (a single byte). + * For that outcome to have a chance to happen, it's necessary that `srcSize < 8`. + * (it's also necessary to not generate statistics). + * Therefore, in such a case, actively check that all bytes are identical. */ + if ((srcSize >= 8) || allBytesIdentical(src, srcSize)) { + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize); + } } + + if (hType == set_compressed) { + /* using a newly constructed table */ + nextHuf->repeatMode = HUF_repeat_check; + } + + /* Build header */ + switch(lhSize) + { + case 3: /* 2 - 2 - 10 - 10 */ + if (!singleStream) assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14); + MEM_writeLE24(ostart, lhc); + break; + } + case 4: /* 2 - 2 - 14 - 14 */ + assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18); + MEM_writeLE32(ostart, lhc); + break; + } + case 5: /* 2 - 2 - 18 - 18 */ + assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22); + MEM_writeLE32(ostart, lhc); + ostart[4] = (BYTE)(cLitSize >> 10); + break; + } + default: /* not possible : lhSize is {3,4,5} */ + assert(0); + } + DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)srcSize, (U32)(lhSize+cLitSize)); + return lhSize+cLitSize; +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_literals.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_literals.h new file mode 100644 index 000000000..b060c8ad2 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_literals.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_LITERALS_H +#define ZSTD_COMPRESS_LITERALS_H + +#include "zstd_compress_internal.h" /* ZSTD_hufCTables_t, ZSTD_minGain() */ + + +size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* ZSTD_compressRleLiteralsBlock() : + * Conditions : + * - All bytes in @src are identical + * - dstCapacity >= 4 */ +size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* ZSTD_compressLiterals(): + * @entropyWorkspace: must be aligned on 4-bytes boundaries + * @entropyWorkspaceSize : must be >= HUF_WORKSPACE_SIZE + * @suspectUncompressible: sampling checks, to potentially skip huffman coding + */ +size_t ZSTD_compressLiterals (void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + void* entropyWorkspace, size_t entropyWorkspaceSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_strategy strategy, int disableLiteralCompression, + int suspectUncompressible, + int bmi2); + +#endif /* ZSTD_COMPRESS_LITERALS_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_sequences.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_sequences.c new file mode 100644 index 000000000..7beb9daa6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_sequences.c @@ -0,0 +1,442 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_sequences.h" + +/** + * -log2(x / 256) lookup table for x in [0, 256). + * If x == 0: Return 0 + * Else: Return floor(-log2(x / 256) * 256) + */ +static unsigned const kInverseProbabilityLog256[256] = { + 0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162, + 1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889, + 874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734, + 724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626, + 618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542, + 535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473, + 468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415, + 411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366, + 362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322, + 318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282, + 279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247, + 244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215, + 212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185, + 182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157, + 155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132, + 130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108, + 106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85, + 83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64, + 62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44, + 42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25, + 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7, + 5, 4, 2, 1, +}; + +static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) { + void const* ptr = ctable; + U16 const* u16ptr = (U16 const*)ptr; + U32 const maxSymbolValue = MEM_read16(u16ptr + 1); + return maxSymbolValue; +} + +/** + * Returns true if we should use ncount=-1 else we should + * use ncount=1 for low probability symbols instead. + */ +static unsigned ZSTD_useLowProbCount(size_t const nbSeq) +{ + /* Heuristic: This should cover most blocks <= 16K and + * start to fade out after 16K to about 32K depending on + * compressibility. + */ + return nbSeq >= 2048; +} + +/** + * Returns the cost in bytes of encoding the normalized count header. + * Returns an error if any of the helper functions return an error. + */ +static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max, + size_t const nbSeq, unsigned const FSELog) +{ + BYTE wksp[FSE_NCOUNTBOUND]; + S16 norm[MaxSeq + 1]; + const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max); + FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), ""); + return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog); +} + +/** + * Returns the cost in bits of encoding the distribution described by count + * using the entropy bound. + */ +static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total) +{ + unsigned cost = 0; + unsigned s; + + assert(total > 0); + for (s = 0; s <= max; ++s) { + unsigned norm = (unsigned)((256 * count[s]) / total); + if (count[s] != 0 && norm == 0) + norm = 1; + assert(count[s] < total); + cost += count[s] * kInverseProbabilityLog256[norm]; + } + return cost >> 8; +} + +/** + * Returns the cost in bits of encoding the distribution in count using ctable. + * Returns an error if ctable cannot represent all the symbols in count. + */ +size_t ZSTD_fseBitCost( + FSE_CTable const* ctable, + unsigned const* count, + unsigned const max) +{ + unsigned const kAccuracyLog = 8; + size_t cost = 0; + unsigned s; + FSE_CState_t cstate; + FSE_initCState(&cstate, ctable); + if (ZSTD_getFSEMaxSymbolValue(ctable) < max) { + DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u", + ZSTD_getFSEMaxSymbolValue(ctable), max); + return ERROR(GENERIC); + } + for (s = 0; s <= max; ++s) { + unsigned const tableLog = cstate.stateLog; + unsigned const badCost = (tableLog + 1) << kAccuracyLog; + unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog); + if (count[s] == 0) + continue; + if (bitCost >= badCost) { + DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s); + return ERROR(GENERIC); + } + cost += (size_t)count[s] * bitCost; + } + return cost >> kAccuracyLog; +} + +/** + * Returns the cost in bits of encoding the distribution in count using the + * table described by norm. The max symbol support by norm is assumed >= max. + * norm must be valid for every symbol with non-zero probability in count. + */ +size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog, + unsigned const* count, unsigned const max) +{ + unsigned const shift = 8 - accuracyLog; + size_t cost = 0; + unsigned s; + assert(accuracyLog <= 8); + for (s = 0; s <= max; ++s) { + unsigned const normAcc = (norm[s] != -1) ? (unsigned)norm[s] : 1; + unsigned const norm256 = normAcc << shift; + assert(norm256 > 0); + assert(norm256 < 256); + cost += count[s] * kInverseProbabilityLog256[norm256]; + } + return cost >> 8; +} + +SymbolEncodingType_e +ZSTD_selectEncodingType( + FSE_repeat* repeatMode, unsigned const* count, unsigned const max, + size_t const mostFrequent, size_t nbSeq, unsigned const FSELog, + FSE_CTable const* prevCTable, + short const* defaultNorm, U32 defaultNormLog, + ZSTD_DefaultPolicy_e const isDefaultAllowed, + ZSTD_strategy const strategy) +{ + ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0); + if (mostFrequent == nbSeq) { + *repeatMode = FSE_repeat_none; + if (isDefaultAllowed && nbSeq <= 2) { + /* Prefer set_basic over set_rle when there are 2 or fewer symbols, + * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol. + * If basic encoding isn't possible, always choose RLE. + */ + DEBUGLOG(5, "Selected set_basic"); + return set_basic; + } + DEBUGLOG(5, "Selected set_rle"); + return set_rle; + } + if (strategy < ZSTD_lazy) { + if (isDefaultAllowed) { + size_t const staticFse_nbSeq_max = 1000; + size_t const mult = 10 - strategy; + size_t const baseLog = 3; + size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */ + assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */ + assert(mult <= 9 && mult >= 7); + if ( (*repeatMode == FSE_repeat_valid) + && (nbSeq < staticFse_nbSeq_max) ) { + DEBUGLOG(5, "Selected set_repeat"); + return set_repeat; + } + if ( (nbSeq < dynamicFse_nbSeq_min) + || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) { + DEBUGLOG(5, "Selected set_basic"); + /* The format allows default tables to be repeated, but it isn't useful. + * When using simple heuristics to select encoding type, we don't want + * to confuse these tables with dictionaries. When running more careful + * analysis, we don't need to waste time checking both repeating tables + * and default tables. + */ + *repeatMode = FSE_repeat_none; + return set_basic; + } + } + } else { + size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC); + size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC); + size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog); + size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq); + + if (isDefaultAllowed) { + assert(!ZSTD_isError(basicCost)); + assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost))); + } + assert(!ZSTD_isError(NCountCost)); + assert(compressedCost < ERROR(maxCode)); + DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u", + (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost); + if (basicCost <= repeatCost && basicCost <= compressedCost) { + DEBUGLOG(5, "Selected set_basic"); + assert(isDefaultAllowed); + *repeatMode = FSE_repeat_none; + return set_basic; + } + if (repeatCost <= compressedCost) { + DEBUGLOG(5, "Selected set_repeat"); + assert(!ZSTD_isError(repeatCost)); + return set_repeat; + } + assert(compressedCost < basicCost && compressedCost < repeatCost); + } + DEBUGLOG(5, "Selected set_compressed"); + *repeatMode = FSE_repeat_check; + return set_compressed; +} + +typedef struct { + S16 norm[MaxSeq + 1]; + U32 wksp[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(MaxSeq, MaxFSELog)]; +} ZSTD_BuildCTableWksp; + +size_t +ZSTD_buildCTable(void* dst, size_t dstCapacity, + FSE_CTable* nextCTable, U32 FSELog, SymbolEncodingType_e type, + unsigned* count, U32 max, + const BYTE* codeTable, size_t nbSeq, + const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax, + const FSE_CTable* prevCTable, size_t prevCTableSize, + void* entropyWorkspace, size_t entropyWorkspaceSize) +{ + BYTE* op = (BYTE*)dst; + const BYTE* const oend = op + dstCapacity; + DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity); + + switch (type) { + case set_rle: + FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max), ""); + RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall, "not enough space"); + *op = codeTable[0]; + return 1; + case set_repeat: + ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize); + return 0; + case set_basic: + FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */ + return 0; + case set_compressed: { + ZSTD_BuildCTableWksp* wksp = (ZSTD_BuildCTableWksp*)entropyWorkspace; + size_t nbSeq_1 = nbSeq; + const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max); + if (count[codeTable[nbSeq-1]] > 1) { + count[codeTable[nbSeq-1]]--; + nbSeq_1--; + } + assert(nbSeq_1 > 1); + assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp)); + (void)entropyWorkspaceSize; + FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "FSE_normalizeCount failed"); + assert(oend >= op); + { size_t const NCountSize = FSE_writeNCount(op, (size_t)(oend - op), wksp->norm, max, tableLog); /* overflow protected */ + FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed"); + FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "FSE_buildCTable_wksp failed"); + return NCountSize; + } + } + default: assert(0); RETURN_ERROR(GENERIC, "impossible to reach"); + } +} + +FORCE_INLINE_TEMPLATE size_t +ZSTD_encodeSequences_body( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + BIT_CStream_t blockStream; + FSE_CState_t stateMatchLength; + FSE_CState_t stateOffsetBits; + FSE_CState_t stateLitLength; + + RETURN_ERROR_IF( + ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)), + dstSize_tooSmall, "not enough space remaining"); + DEBUGLOG(6, "available space for bitstream : %i (dstCapacity=%u)", + (int)(blockStream.endPtr - blockStream.startPtr), + (unsigned)dstCapacity); + + /* first symbols */ + FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]); + FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]); + FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]); + BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]); + if (MEM_32bits()) BIT_flushBits(&blockStream); + BIT_addBits(&blockStream, sequences[nbSeq-1].mlBase, ML_bits[mlCodeTable[nbSeq-1]]); + if (MEM_32bits()) BIT_flushBits(&blockStream); + if (longOffsets) { + U32 const ofBits = ofCodeTable[nbSeq-1]; + unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1); + if (extraBits) { + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, extraBits); + BIT_flushBits(&blockStream); + } + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase >> extraBits, + ofBits - extraBits); + } else { + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, ofCodeTable[nbSeq-1]); + } + BIT_flushBits(&blockStream); + + { size_t n; + for (n=nbSeq-2 ; n= 64-7-(LLFSELog+MLFSELog+OffFSELog))) + BIT_flushBits(&blockStream); /* (7)*/ + BIT_addBits(&blockStream, sequences[n].litLength, llBits); + if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream); + BIT_addBits(&blockStream, sequences[n].mlBase, mlBits); + if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream); + if (longOffsets) { + unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1); + if (extraBits) { + BIT_addBits(&blockStream, sequences[n].offBase, extraBits); + BIT_flushBits(&blockStream); /* (7)*/ + } + BIT_addBits(&blockStream, sequences[n].offBase >> extraBits, + ofBits - extraBits); /* 31 */ + } else { + BIT_addBits(&blockStream, sequences[n].offBase, ofBits); /* 31 */ + } + BIT_flushBits(&blockStream); /* (7)*/ + DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr)); + } } + + DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog); + FSE_flushCState(&blockStream, &stateMatchLength); + DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog); + FSE_flushCState(&blockStream, &stateOffsetBits); + DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog); + FSE_flushCState(&blockStream, &stateLitLength); + + { size_t const streamSize = BIT_closeCStream(&blockStream); + RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, "not enough space"); + return streamSize; + } +} + +static size_t +ZSTD_encodeSequences_default( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + return ZSTD_encodeSequences_body(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} + + +#if DYNAMIC_BMI2 + +static BMI2_TARGET_ATTRIBUTE size_t +ZSTD_encodeSequences_bmi2( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + return ZSTD_encodeSequences_body(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} + +#endif + +size_t ZSTD_encodeSequences( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2) +{ + DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity); +#if DYNAMIC_BMI2 + if (bmi2) { + return ZSTD_encodeSequences_bmi2(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); + } +#endif + (void)bmi2; + return ZSTD_encodeSequences_default(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_sequences.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_sequences.h new file mode 100644 index 000000000..4be8e91f2 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_sequences.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_SEQUENCES_H +#define ZSTD_COMPRESS_SEQUENCES_H + +#include "zstd_compress_internal.h" /* SeqDef */ +#include "../common/fse.h" /* FSE_repeat, FSE_CTable */ +#include "../common/zstd_internal.h" /* SymbolEncodingType_e, ZSTD_strategy */ + +typedef enum { + ZSTD_defaultDisallowed = 0, + ZSTD_defaultAllowed = 1 +} ZSTD_DefaultPolicy_e; + +SymbolEncodingType_e +ZSTD_selectEncodingType( + FSE_repeat* repeatMode, unsigned const* count, unsigned const max, + size_t const mostFrequent, size_t nbSeq, unsigned const FSELog, + FSE_CTable const* prevCTable, + short const* defaultNorm, U32 defaultNormLog, + ZSTD_DefaultPolicy_e const isDefaultAllowed, + ZSTD_strategy const strategy); + +size_t +ZSTD_buildCTable(void* dst, size_t dstCapacity, + FSE_CTable* nextCTable, U32 FSELog, SymbolEncodingType_e type, + unsigned* count, U32 max, + const BYTE* codeTable, size_t nbSeq, + const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax, + const FSE_CTable* prevCTable, size_t prevCTableSize, + void* entropyWorkspace, size_t entropyWorkspaceSize); + +size_t ZSTD_encodeSequences( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2); + +size_t ZSTD_fseBitCost( + FSE_CTable const* ctable, + unsigned const* count, + unsigned const max); + +size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog, + unsigned const* count, unsigned const max); +#endif /* ZSTD_COMPRESS_SEQUENCES_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_superblock.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_superblock.c new file mode 100644 index 000000000..6f57345be --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_superblock.c @@ -0,0 +1,688 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_superblock.h" + +#include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */ +#include "hist.h" /* HIST_countFast_wksp */ +#include "zstd_compress_internal.h" /* ZSTD_[huf|fse|entropy]CTablesMetadata_t */ +#include "zstd_compress_sequences.h" +#include "zstd_compress_literals.h" + +/** ZSTD_compressSubBlock_literal() : + * Compresses literals section for a sub-block. + * When we have to write the Huffman table we will sometimes choose a header + * size larger than necessary. This is because we have to pick the header size + * before we know the table size + compressed size, so we have a bound on the + * table size. If we guessed incorrectly, we fall back to uncompressed literals. + * + * We write the header when writeEntropy=1 and set entropyWritten=1 when we succeeded + * in writing the header, otherwise it is set to 0. + * + * hufMetadata->hType has literals block type info. + * If it is set_basic, all sub-blocks literals section will be Raw_Literals_Block. + * If it is set_rle, all sub-blocks literals section will be RLE_Literals_Block. + * If it is set_compressed, first sub-block's literals section will be Compressed_Literals_Block + * If it is set_compressed, first sub-block's literals section will be Treeless_Literals_Block + * and the following sub-blocks' literals sections will be Treeless_Literals_Block. + * @return : compressed size of literals section of a sub-block + * Or 0 if unable to compress. + * Or error code */ +static size_t +ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + const BYTE* literals, size_t litSize, + void* dst, size_t dstSize, + const int bmi2, int writeEntropy, int* entropyWritten) +{ + size_t const header = writeEntropy ? 200 : 0; + size_t const lhSize = 3 + (litSize >= (1 KB - header)) + (litSize >= (16 KB - header)); + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart + lhSize; + U32 const singleStream = lhSize == 3; + SymbolEncodingType_e hType = writeEntropy ? hufMetadata->hType : set_repeat; + size_t cLitSize = 0; + + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (litSize=%zu, lhSize=%zu, writeEntropy=%d)", litSize, lhSize, writeEntropy); + + *entropyWritten = 0; + if (litSize == 0 || hufMetadata->hType == set_basic) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } else if (hufMetadata->hType == set_rle) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using rle literal"); + return ZSTD_compressRleLiteralsBlock(dst, dstSize, literals, litSize); + } + + assert(litSize > 0); + assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat); + + if (writeEntropy && hufMetadata->hType == set_compressed) { + ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize); + op += hufMetadata->hufDesSize; + cLitSize += hufMetadata->hufDesSize; + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize); + } + + { int const flags = bmi2 ? HUF_flags_bmi2 : 0; + const size_t cSize = singleStream ? HUF_compress1X_usingCTable(op, (size_t)(oend-op), literals, litSize, hufTable, flags) + : HUF_compress4X_usingCTable(op, (size_t)(oend-op), literals, litSize, hufTable, flags); + op += cSize; + cLitSize += cSize; + if (cSize == 0 || ERR_isError(cSize)) { + DEBUGLOG(5, "Failed to write entropy tables %s", ZSTD_getErrorName(cSize)); + return 0; + } + /* If we expand and we aren't writing a header then emit uncompressed */ + if (!writeEntropy && cLitSize >= litSize) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal because uncompressible"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } + /* If we are writing headers then allow expansion that doesn't change our header size. */ + if (lhSize < (size_t)(3 + (cLitSize >= 1 KB) + (cLitSize >= 16 KB))) { + assert(cLitSize > litSize); + DEBUGLOG(5, "Literals expanded beyond allowed header size"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (cSize=%zu)", cSize); + } + + /* Build header */ + switch(lhSize) + { + case 3: /* 2 - 2 - 10 - 10 */ + { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<14); + MEM_writeLE24(ostart, lhc); + break; + } + case 4: /* 2 - 2 - 14 - 14 */ + { U32 const lhc = hType + (2 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<18); + MEM_writeLE32(ostart, lhc); + break; + } + case 5: /* 2 - 2 - 18 - 18 */ + { U32 const lhc = hType + (3 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<22); + MEM_writeLE32(ostart, lhc); + ostart[4] = (BYTE)(cLitSize >> 10); + break; + } + default: /* not possible : lhSize is {3,4,5} */ + assert(0); + } + *entropyWritten = 1; + DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)litSize, (U32)(op-ostart)); + return (size_t)(op-ostart); +} + +static size_t +ZSTD_seqDecompressedSize(SeqStore_t const* seqStore, + const SeqDef* sequences, size_t nbSeqs, + size_t litSize, int lastSubBlock) +{ + size_t matchLengthSum = 0; + size_t litLengthSum = 0; + size_t n; + for (n=0; nllType, fseMetadata->ofType, and fseMetadata->mlType have + * symbol compression modes for the super-block. + * The first successfully compressed block will have these in its header. + * We set entropyWritten=1 when we succeed in compressing the sequences. + * The following sub-blocks will always have repeat mode. + * @return : compressed size of sequences section of a sub-block + * Or 0 if it is unable to compress + * Or error code. */ +static size_t +ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + const SeqDef* sequences, size_t nbSeq, + const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const int bmi2, int writeEntropy, int* entropyWritten) +{ + const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + BYTE* seqHead; + + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (nbSeq=%zu, writeEntropy=%d, longOffsets=%d)", nbSeq, writeEntropy, longOffsets); + + *entropyWritten = 0; + /* Sequences Header */ + RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/, + dstSize_tooSmall, ""); + if (nbSeq < 128) + *op++ = (BYTE)nbSeq; + else if (nbSeq < LONGNBSEQ) + op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2; + else + op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3; + if (nbSeq==0) { + return (size_t)(op - ostart); + } + + /* seqHead : flags for FSE encoding type */ + seqHead = op++; + + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (seqHeadSize=%u)", (unsigned)(op-ostart)); + + if (writeEntropy) { + const U32 LLtype = fseMetadata->llType; + const U32 Offtype = fseMetadata->ofType; + const U32 MLtype = fseMetadata->mlType; + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize); + *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2)); + ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize); + op += fseMetadata->fseTablesSize; + } else { + const U32 repeat = set_repeat; + *seqHead = (BYTE)((repeat<<6) + (repeat<<4) + (repeat<<2)); + } + + { size_t const bitstreamSize = ZSTD_encodeSequences( + op, (size_t)(oend - op), + fseTables->matchlengthCTable, mlCode, + fseTables->offcodeCTable, ofCode, + fseTables->litlengthCTable, llCode, + sequences, nbSeq, + longOffsets, bmi2); + FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed"); + op += bitstreamSize; + /* zstd versions <= 1.3.4 mistakenly report corruption when + * FSE_readNCount() receives a buffer < 4 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1146. + * This can happen when the last set_compressed table present is 2 + * bytes and the bitstream is only one byte. + * In this exceedingly rare case, we will simply emit an uncompressed + * block, since it isn't worth optimizing. + */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (writeEntropy && fseMetadata->lastCountSize && fseMetadata->lastCountSize + bitstreamSize < 4) { + /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */ + assert(fseMetadata->lastCountSize + bitstreamSize == 3); + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by " + "emitting an uncompressed block."); + return 0; + } +#endif + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (bitstreamSize=%zu)", bitstreamSize); + } + + /* zstd versions <= 1.4.0 mistakenly report error when + * sequences section body size is less than 3 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1664. + * This can happen when the previous sequences section block is compressed + * with rle mode and the current block's sequences section is compressed + * with repeat mode where sequences section body size can be 1 byte. + */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (op-seqHead < 4) { + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.4.0 by emitting " + "an uncompressed block when sequences are < 4 bytes"); + return 0; + } +#endif + + *entropyWritten = 1; + return (size_t)(op - ostart); +} + +/** ZSTD_compressSubBlock() : + * Compresses a single sub-block. + * @return : compressed size of the sub-block + * Or 0 if it failed to compress. */ +static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + const SeqDef* sequences, size_t nbSeq, + const BYTE* literals, size_t litSize, + const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const int bmi2, + int writeLitEntropy, int writeSeqEntropy, + int* litEntropyWritten, int* seqEntropyWritten, + U32 lastBlock) +{ + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart + ZSTD_blockHeaderSize; + DEBUGLOG(5, "ZSTD_compressSubBlock (litSize=%zu, nbSeq=%zu, writeLitEntropy=%d, writeSeqEntropy=%d, lastBlock=%d)", + litSize, nbSeq, writeLitEntropy, writeSeqEntropy, lastBlock); + { size_t cLitSize = ZSTD_compressSubBlock_literal((const HUF_CElt*)entropy->huf.CTable, + &entropyMetadata->hufMetadata, literals, litSize, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, litEntropyWritten); + FORWARD_IF_ERROR(cLitSize, "ZSTD_compressSubBlock_literal failed"); + if (cLitSize == 0) return 0; + op += cLitSize; + } + { size_t cSeqSize = ZSTD_compressSubBlock_sequences(&entropy->fse, + &entropyMetadata->fseMetadata, + sequences, nbSeq, + llCode, mlCode, ofCode, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeSeqEntropy, seqEntropyWritten); + FORWARD_IF_ERROR(cSeqSize, "ZSTD_compressSubBlock_sequences failed"); + if (cSeqSize == 0) return 0; + op += cSeqSize; + } + /* Write block header */ + { size_t cSize = (size_t)(op-ostart) - ZSTD_blockHeaderSize; + U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(ostart, cBlockHeader24); + } + return (size_t)(op-ostart); +} + +static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t litSize, + const ZSTD_hufCTables_t* huf, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + unsigned* const countWksp = (unsigned*)workspace; + unsigned maxSymbolValue = 255; + size_t literalSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */ + + if (hufMetadata->hType == set_basic) return litSize; + else if (hufMetadata->hType == set_rle) return 1; + else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) { + size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize); + if (ZSTD_isError(largest)) return litSize; + { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue); + if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize; + return cLitSizeEstimate + literalSectionHeaderSize; + } } + assert(0); /* impossible */ + return 0; +} + +static size_t ZSTD_estimateSubBlockSize_symbolType(SymbolEncodingType_e type, + const BYTE* codeTable, unsigned maxCode, + size_t nbSeq, const FSE_CTable* fseCTable, + const U8* additionalBits, + short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, + void* workspace, size_t wkspSize) +{ + unsigned* const countWksp = (unsigned*)workspace; + const BYTE* ctp = codeTable; + const BYTE* const ctStart = ctp; + const BYTE* const ctEnd = ctStart + nbSeq; + size_t cSymbolTypeSizeEstimateInBits = 0; + unsigned max = maxCode; + + HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */ + if (type == set_basic) { + /* We selected this encoding type, so it must be valid. */ + assert(max <= defaultMax); + cSymbolTypeSizeEstimateInBits = max <= defaultMax + ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max) + : ERROR(GENERIC); + } else if (type == set_rle) { + cSymbolTypeSizeEstimateInBits = 0; + } else if (type == set_compressed || type == set_repeat) { + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); + } + if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) return nbSeq * 10; + while (ctp < ctEnd) { + if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp]; + else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */ + ctp++; + } + return cSymbolTypeSizeEstimateInBits / 8; +} + +static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + size_t const sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */ + size_t cSeqSizeEstimate = 0; + if (nbSeq == 0) return sequencesSectionHeaderSize; + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff, + nbSeq, fseTables->offcodeCTable, NULL, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL, + nbSeq, fseTables->litlengthCTable, LL_bits, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML, + nbSeq, fseTables->matchlengthCTable, ML_bits, + ML_defaultNorm, ML_defaultNormLog, MaxML, + workspace, wkspSize); + if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; + return cSeqSizeEstimate + sequencesSectionHeaderSize; +} + +typedef struct { + size_t estLitSize; + size_t estBlockSize; +} EstimatedBlockSize; +static EstimatedBlockSize ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize, + const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize, + int writeLitEntropy, int writeSeqEntropy) +{ + EstimatedBlockSize ebs; + ebs.estLitSize = ZSTD_estimateSubBlockSize_literal(literals, litSize, + &entropy->huf, &entropyMetadata->hufMetadata, + workspace, wkspSize, writeLitEntropy); + ebs.estBlockSize = ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, + nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, + workspace, wkspSize, writeSeqEntropy); + ebs.estBlockSize += ebs.estLitSize + ZSTD_blockHeaderSize; + return ebs; +} + +static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const* fseMetadata) +{ + if (fseMetadata->llType == set_compressed || fseMetadata->llType == set_rle) + return 1; + if (fseMetadata->mlType == set_compressed || fseMetadata->mlType == set_rle) + return 1; + if (fseMetadata->ofType == set_compressed || fseMetadata->ofType == set_rle) + return 1; + return 0; +} + +static size_t countLiterals(SeqStore_t const* seqStore, const SeqDef* sp, size_t seqCount) +{ + size_t n, total = 0; + assert(sp != NULL); + for (n=0; n %zu bytes", seqCount, (const void*)sp, total); + return total; +} + +#define BYTESCALE 256 + +static size_t sizeBlockSequences(const SeqDef* sp, size_t nbSeqs, + size_t targetBudget, size_t avgLitCost, size_t avgSeqCost, + int firstSubBlock) +{ + size_t n, budget = 0, inSize=0; + /* entropy headers */ + size_t const headerSize = (size_t)firstSubBlock * 120 * BYTESCALE; /* generous estimate */ + assert(firstSubBlock==0 || firstSubBlock==1); + budget += headerSize; + + /* first sequence => at least one sequence*/ + budget += sp[0].litLength * avgLitCost + avgSeqCost; + if (budget > targetBudget) return 1; + inSize = sp[0].litLength + (sp[0].mlBase+MINMATCH); + + /* loop over sequences */ + for (n=1; n targetBudget) + /* though continue to expand until the sub-block is deemed compressible */ + && (budget < inSize * BYTESCALE) ) + break; + } + + return n; +} + +/** ZSTD_compressSubBlock_multi() : + * Breaks super-block into multiple sub-blocks and compresses them. + * Entropy will be written into the first block. + * The following blocks use repeat_mode to compress. + * Sub-blocks are all compressed, except the last one when beneficial. + * @return : compressed size of the super block (which features multiple ZSTD blocks) + * or 0 if it failed to compress. */ +static size_t ZSTD_compressSubBlock_multi(const SeqStore_t* seqStorePtr, + const ZSTD_compressedBlockState_t* prevCBlock, + ZSTD_compressedBlockState_t* nextCBlock, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const int bmi2, U32 lastBlock, + void* workspace, size_t wkspSize) +{ + const SeqDef* const sstart = seqStorePtr->sequencesStart; + const SeqDef* const send = seqStorePtr->sequences; + const SeqDef* sp = sstart; /* tracks progresses within seqStorePtr->sequences */ + size_t const nbSeqs = (size_t)(send - sstart); + const BYTE* const lstart = seqStorePtr->litStart; + const BYTE* const lend = seqStorePtr->lit; + const BYTE* lp = lstart; + size_t const nbLiterals = (size_t)(lend - lstart); + BYTE const* ip = (BYTE const*)src; + BYTE const* const iend = ip + srcSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + const BYTE* llCodePtr = seqStorePtr->llCode; + const BYTE* mlCodePtr = seqStorePtr->mlCode; + const BYTE* ofCodePtr = seqStorePtr->ofCode; + size_t const minTarget = ZSTD_TARGETCBLOCKSIZE_MIN; /* enforce minimum size, to reduce undesirable side effects */ + size_t const targetCBlockSize = MAX(minTarget, cctxParams->targetCBlockSize); + int writeLitEntropy = (entropyMetadata->hufMetadata.hType == set_compressed); + int writeSeqEntropy = 1; + + DEBUGLOG(5, "ZSTD_compressSubBlock_multi (srcSize=%u, litSize=%u, nbSeq=%u)", + (unsigned)srcSize, (unsigned)(lend-lstart), (unsigned)(send-sstart)); + + /* let's start by a general estimation for the full block */ + if (nbSeqs > 0) { + EstimatedBlockSize const ebs = + ZSTD_estimateSubBlockSize(lp, nbLiterals, + ofCodePtr, llCodePtr, mlCodePtr, nbSeqs, + &nextCBlock->entropy, entropyMetadata, + workspace, wkspSize, + writeLitEntropy, writeSeqEntropy); + /* quick estimation */ + size_t const avgLitCost = nbLiterals ? (ebs.estLitSize * BYTESCALE) / nbLiterals : BYTESCALE; + size_t const avgSeqCost = ((ebs.estBlockSize - ebs.estLitSize) * BYTESCALE) / nbSeqs; + const size_t nbSubBlocks = MAX((ebs.estBlockSize + (targetCBlockSize/2)) / targetCBlockSize, 1); + size_t n, avgBlockBudget, blockBudgetSupp=0; + avgBlockBudget = (ebs.estBlockSize * BYTESCALE) / nbSubBlocks; + DEBUGLOG(5, "estimated fullblock size=%u bytes ; avgLitCost=%.2f ; avgSeqCost=%.2f ; targetCBlockSize=%u, nbSubBlocks=%u ; avgBlockBudget=%.0f bytes", + (unsigned)ebs.estBlockSize, (double)avgLitCost/BYTESCALE, (double)avgSeqCost/BYTESCALE, + (unsigned)targetCBlockSize, (unsigned)nbSubBlocks, (double)avgBlockBudget/BYTESCALE); + /* simplification: if estimates states that the full superblock doesn't compress, just bail out immediately + * this will result in the production of a single uncompressed block covering @srcSize.*/ + if (ebs.estBlockSize > srcSize) return 0; + + /* compress and write sub-blocks */ + assert(nbSubBlocks>0); + for (n=0; n < nbSubBlocks-1; n++) { + /* determine nb of sequences for current sub-block + nbLiterals from next sequence */ + size_t const seqCount = sizeBlockSequences(sp, (size_t)(send-sp), + avgBlockBudget + blockBudgetSupp, avgLitCost, avgSeqCost, n==0); + /* if reached last sequence : break to last sub-block (simplification) */ + assert(seqCount <= (size_t)(send-sp)); + if (sp + seqCount == send) break; + assert(seqCount > 0); + /* compress sub-block */ + { int litEntropyWritten = 0; + int seqEntropyWritten = 0; + size_t litSize = countLiterals(seqStorePtr, sp, seqCount); + const size_t decompressedSize = + ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, 0); + size_t const cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, + sp, seqCount, + lp, litSize, + llCodePtr, mlCodePtr, ofCodePtr, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, writeSeqEntropy, + &litEntropyWritten, &seqEntropyWritten, + 0); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); + + /* check compressibility, update state components */ + if (cSize > 0 && cSize < decompressedSize) { + DEBUGLOG(5, "Committed sub-block compressing %u bytes => %u bytes", + (unsigned)decompressedSize, (unsigned)cSize); + assert(ip + decompressedSize <= iend); + ip += decompressedSize; + lp += litSize; + op += cSize; + llCodePtr += seqCount; + mlCodePtr += seqCount; + ofCodePtr += seqCount; + /* Entropy only needs to be written once */ + if (litEntropyWritten) { + writeLitEntropy = 0; + } + if (seqEntropyWritten) { + writeSeqEntropy = 0; + } + sp += seqCount; + blockBudgetSupp = 0; + } } + /* otherwise : do not compress yet, coalesce current sub-block with following one */ + } + } /* if (nbSeqs > 0) */ + + /* write last block */ + DEBUGLOG(5, "Generate last sub-block: %u sequences remaining", (unsigned)(send - sp)); + { int litEntropyWritten = 0; + int seqEntropyWritten = 0; + size_t litSize = (size_t)(lend - lp); + size_t seqCount = (size_t)(send - sp); + const size_t decompressedSize = + ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, 1); + size_t const cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, + sp, seqCount, + lp, litSize, + llCodePtr, mlCodePtr, ofCodePtr, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, writeSeqEntropy, + &litEntropyWritten, &seqEntropyWritten, + lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); + + /* update pointers, the nb of literals borrowed from next sequence must be preserved */ + if (cSize > 0 && cSize < decompressedSize) { + DEBUGLOG(5, "Last sub-block compressed %u bytes => %u bytes", + (unsigned)decompressedSize, (unsigned)cSize); + assert(ip + decompressedSize <= iend); + ip += decompressedSize; + lp += litSize; + op += cSize; + llCodePtr += seqCount; + mlCodePtr += seqCount; + ofCodePtr += seqCount; + /* Entropy only needs to be written once */ + if (litEntropyWritten) { + writeLitEntropy = 0; + } + if (seqEntropyWritten) { + writeSeqEntropy = 0; + } + sp += seqCount; + } + } + + + if (writeLitEntropy) { + DEBUGLOG(5, "Literal entropy tables were never written"); + ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf)); + } + if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) { + /* If we haven't written our entropy tables, then we've violated our contract and + * must emit an uncompressed block. + */ + DEBUGLOG(5, "Sequence entropy tables were never written => cancel, emit an uncompressed block"); + return 0; + } + + if (ip < iend) { + /* some data left : last part of the block sent uncompressed */ + size_t const rSize = (size_t)((iend - ip)); + size_t const cSize = ZSTD_noCompressBlock(op, (size_t)(oend - op), ip, rSize, lastBlock); + DEBUGLOG(5, "Generate last uncompressed sub-block of %u bytes", (unsigned)(rSize)); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + assert(cSize != 0); + op += cSize; + /* We have to regenerate the repcodes because we've skipped some sequences */ + if (sp < send) { + const SeqDef* seq; + Repcodes_t rep; + ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep)); + for (seq = sstart; seq < sp; ++seq) { + ZSTD_updateRep(rep.rep, seq->offBase, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0); + } + ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep)); + } + } + + DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed all subBlocks: total compressed size = %u", + (unsigned)(op-ostart)); + return (size_t)(op-ostart); +} + +size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned lastBlock) +{ + ZSTD_entropyCTablesMetadata_t entropyMetadata; + + FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(&zc->seqStore, + &zc->blockState.prevCBlock->entropy, + &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + &entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */), ""); + + return ZSTD_compressSubBlock_multi(&zc->seqStore, + zc->blockState.prevCBlock, + zc->blockState.nextCBlock, + &entropyMetadata, + &zc->appliedParams, + dst, dstCapacity, + src, srcSize, + zc->bmi2, lastBlock, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */); +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_superblock.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_superblock.h new file mode 100644 index 000000000..8e494f0d5 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_compress_superblock.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_ADVANCED_H +#define ZSTD_COMPRESS_ADVANCED_H + +/*-************************************* +* Dependencies +***************************************/ + +#include "../zstd.h" /* ZSTD_CCtx */ + +/*-************************************* +* Target Compressed Block Size +***************************************/ + +/* ZSTD_compressSuperBlock() : + * Used to compress a super block when targetCBlockSize is being used. + * The given block will be compressed into multiple sub blocks that are around targetCBlockSize. */ +size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + void const* src, size_t srcSize, + unsigned lastBlock); + +#endif /* ZSTD_COMPRESS_ADVANCED_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_cwksp.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_cwksp.h new file mode 100644 index 000000000..77518002d --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_cwksp.h @@ -0,0 +1,765 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CWKSP_H +#define ZSTD_CWKSP_H + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customFree */ +#include "../common/zstd_internal.h" +#include "../common/portability_macros.h" +#include "../common/compiler.h" /* ZS2_isPower2 */ + +/*-************************************* +* Constants +***************************************/ + +/* Since the workspace is effectively its own little malloc implementation / + * arena, when we run under ASAN, we should similarly insert redzones between + * each internal element of the workspace, so ASAN will catch overruns that + * reach outside an object but that stay inside the workspace. + * + * This defines the size of that redzone. + */ +#ifndef ZSTD_CWKSP_ASAN_REDZONE_SIZE +#define ZSTD_CWKSP_ASAN_REDZONE_SIZE 128 +#endif + + +/* Set our tables and aligneds to align by 64 bytes */ +#define ZSTD_CWKSP_ALIGNMENT_BYTES 64 + +/*-************************************* +* Structures +***************************************/ +typedef enum { + ZSTD_cwksp_alloc_objects, + ZSTD_cwksp_alloc_aligned_init_once, + ZSTD_cwksp_alloc_aligned, + ZSTD_cwksp_alloc_buffers +} ZSTD_cwksp_alloc_phase_e; + +/** + * Used to describe whether the workspace is statically allocated (and will not + * necessarily ever be freed), or if it's dynamically allocated and we can + * expect a well-formed caller to free this. + */ +typedef enum { + ZSTD_cwksp_dynamic_alloc, + ZSTD_cwksp_static_alloc +} ZSTD_cwksp_static_alloc_e; + +/** + * Zstd fits all its internal datastructures into a single continuous buffer, + * so that it only needs to perform a single OS allocation (or so that a buffer + * can be provided to it and it can perform no allocations at all). This buffer + * is called the workspace. + * + * Several optimizations complicate that process of allocating memory ranges + * from this workspace for each internal datastructure: + * + * - These different internal datastructures have different setup requirements: + * + * - The static objects need to be cleared once and can then be trivially + * reused for each compression. + * + * - Various buffers don't need to be initialized at all--they are always + * written into before they're read. + * + * - The matchstate tables have a unique requirement that they don't need + * their memory to be totally cleared, but they do need the memory to have + * some bound, i.e., a guarantee that all values in the memory they've been + * allocated is less than some maximum value (which is the starting value + * for the indices that they will then use for compression). When this + * guarantee is provided to them, they can use the memory without any setup + * work. When it can't, they have to clear the area. + * + * - These buffers also have different alignment requirements. + * + * - We would like to reuse the objects in the workspace for multiple + * compressions without having to perform any expensive reallocation or + * reinitialization work. + * + * - We would like to be able to efficiently reuse the workspace across + * multiple compressions **even when the compression parameters change** and + * we need to resize some of the objects (where possible). + * + * To attempt to manage this buffer, given these constraints, the ZSTD_cwksp + * abstraction was created. It works as follows: + * + * Workspace Layout: + * + * [ ... workspace ... ] + * [objects][tables ->] free space [<- buffers][<- aligned][<- init once] + * + * The various objects that live in the workspace are divided into the + * following categories, and are allocated separately: + * + * - Static objects: this is optionally the enclosing ZSTD_CCtx or ZSTD_CDict, + * so that literally everything fits in a single buffer. Note: if present, + * this must be the first object in the workspace, since ZSTD_customFree{CCtx, + * CDict}() rely on a pointer comparison to see whether one or two frees are + * required. + * + * - Fixed size objects: these are fixed-size, fixed-count objects that are + * nonetheless "dynamically" allocated in the workspace so that we can + * control how they're initialized separately from the broader ZSTD_CCtx. + * Examples: + * - Entropy Workspace + * - 2 x ZSTD_compressedBlockState_t + * - CDict dictionary contents + * + * - Tables: these are any of several different datastructures (hash tables, + * chain tables, binary trees) that all respect a common format: they are + * uint32_t arrays, all of whose values are between 0 and (nextSrc - base). + * Their sizes depend on the cparams. These tables are 64-byte aligned. + * + * - Init once: these buffers require to be initialized at least once before + * use. They should be used when we want to skip memory initialization + * while not triggering memory checkers (like Valgrind) when reading from + * from this memory without writing to it first. + * These buffers should be used carefully as they might contain data + * from previous compressions. + * Buffers are aligned to 64 bytes. + * + * - Aligned: these buffers don't require any initialization before they're + * used. The user of the buffer should make sure they write into a buffer + * location before reading from it. + * Buffers are aligned to 64 bytes. + * + * - Buffers: these buffers are used for various purposes that don't require + * any alignment or initialization before they're used. This means they can + * be moved around at no cost for a new compression. + * + * Allocating Memory: + * + * The various types of objects must be allocated in order, so they can be + * correctly packed into the workspace buffer. That order is: + * + * 1. Objects + * 2. Init once / Tables + * 3. Aligned / Tables + * 4. Buffers / Tables + * + * Attempts to reserve objects of different types out of order will fail. + */ +typedef struct { + void* workspace; + void* workspaceEnd; + + void* objectEnd; + void* tableEnd; + void* tableValidEnd; + void* allocStart; + void* initOnceStart; + + BYTE allocFailed; + int workspaceOversizedDuration; + ZSTD_cwksp_alloc_phase_e phase; + ZSTD_cwksp_static_alloc_e isStatic; +} ZSTD_cwksp; + +/*-************************************* +* Functions +***************************************/ + +MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws); +MEM_STATIC void* ZSTD_cwksp_initialAllocStart(ZSTD_cwksp* ws); + +MEM_STATIC void ZSTD_cwksp_assert_internal_consistency(ZSTD_cwksp* ws) { + (void)ws; + assert(ws->workspace <= ws->objectEnd); + assert(ws->objectEnd <= ws->tableEnd); + assert(ws->objectEnd <= ws->tableValidEnd); + assert(ws->tableEnd <= ws->allocStart); + assert(ws->tableValidEnd <= ws->allocStart); + assert(ws->allocStart <= ws->workspaceEnd); + assert(ws->initOnceStart <= ZSTD_cwksp_initialAllocStart(ws)); + assert(ws->workspace <= ws->initOnceStart); +#if ZSTD_MEMORY_SANITIZER + { + intptr_t const offset = __msan_test_shadow(ws->initOnceStart, + (U8*)ZSTD_cwksp_initialAllocStart(ws) - (U8*)ws->initOnceStart); + (void)offset; +#if defined(ZSTD_MSAN_PRINT) + if(offset!=-1) { + __msan_print_shadow((U8*)ws->initOnceStart + offset - 8, 32); + } +#endif + assert(offset==-1); + }; +#endif +} + +/** + * Align must be a power of 2. + */ +MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t align) { + size_t const mask = align - 1; + assert(ZSTD_isPower2(align)); + return (size + mask) & ~mask; +} + +/** + * Use this to determine how much space in the workspace we will consume to + * allocate this object. (Normally it should be exactly the size of the object, + * but under special conditions, like ASAN, where we pad each object, it might + * be larger.) + * + * Since tables aren't currently redzoned, you don't need to call through this + * to figure out how much space you need for the matchState tables. Everything + * else is though. + * + * Do not use for sizing aligned buffers. Instead, use ZSTD_cwksp_aligned64_alloc_size(). + */ +MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) { + if (size == 0) + return 0; +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#else + return size; +#endif +} + +MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size, size_t alignment) { + return ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(size, alignment)); +} + +/** + * Returns an adjusted alloc size that is the nearest larger multiple of 64 bytes. + * Used to determine the number of bytes required for a given "aligned". + */ +MEM_STATIC size_t ZSTD_cwksp_aligned64_alloc_size(size_t size) { + return ZSTD_cwksp_aligned_alloc_size(size, ZSTD_CWKSP_ALIGNMENT_BYTES); +} + +/** + * Returns the amount of additional space the cwksp must allocate + * for internal purposes (currently only alignment). + */ +MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void) { + /* For alignment, the wksp will always allocate an additional 2*ZSTD_CWKSP_ALIGNMENT_BYTES + * bytes to align the beginning of tables section and end of buffers; + */ + size_t const slackSpace = ZSTD_CWKSP_ALIGNMENT_BYTES * 2; + return slackSpace; +} + + +/** + * Return the number of additional bytes required to align a pointer to the given number of bytes. + * alignBytes must be a power of two. + */ +MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void* ptr, const size_t alignBytes) { + size_t const alignBytesMask = alignBytes - 1; + size_t const bytes = (alignBytes - ((size_t)ptr & (alignBytesMask))) & alignBytesMask; + assert(ZSTD_isPower2(alignBytes)); + assert(bytes < alignBytes); + return bytes; +} + +/** + * Returns the initial value for allocStart which is used to determine the position from + * which we can allocate from the end of the workspace. + */ +MEM_STATIC void* ZSTD_cwksp_initialAllocStart(ZSTD_cwksp* ws) +{ + char* endPtr = (char*)ws->workspaceEnd; + assert(ZSTD_isPower2(ZSTD_CWKSP_ALIGNMENT_BYTES)); + endPtr = endPtr - ((size_t)endPtr % ZSTD_CWKSP_ALIGNMENT_BYTES); + return (void*)endPtr; +} + +/** + * Internal function. Do not use directly. + * Reserves the given number of bytes within the aligned/buffer segment of the wksp, + * which counts from the end of the wksp (as opposed to the object/table segment). + * + * Returns a pointer to the beginning of that space. + */ +MEM_STATIC void* +ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t const bytes) +{ + void* const alloc = (BYTE*)ws->allocStart - bytes; + void* const bottom = ws->tableEnd; + DEBUGLOG(5, "cwksp: reserving [0x%p]:%zd bytes; %zd bytes remaining", + alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes); + ZSTD_cwksp_assert_internal_consistency(ws); + assert(alloc >= bottom); + if (alloc < bottom) { + DEBUGLOG(4, "cwksp: alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + /* the area is reserved from the end of wksp. + * If it overlaps with tableValidEnd, it voids guarantees on values' range */ + if (alloc < ws->tableValidEnd) { + ws->tableValidEnd = alloc; + } + ws->allocStart = alloc; + return alloc; +} + +/** + * Moves the cwksp to the next phase, and does any necessary allocations. + * cwksp initialization must necessarily go through each phase in order. + * Returns a 0 on success, or zstd error + */ +MEM_STATIC size_t +ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase) +{ + assert(phase >= ws->phase); + if (phase > ws->phase) { + /* Going from allocating objects to allocating initOnce / tables */ + if (ws->phase < ZSTD_cwksp_alloc_aligned_init_once && + phase >= ZSTD_cwksp_alloc_aligned_init_once) { + ws->tableValidEnd = ws->objectEnd; + ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws); + + { /* Align the start of the tables to 64 bytes. Use [0, 63] bytes */ + void *const alloc = ws->objectEnd; + size_t const bytesToAlign = ZSTD_cwksp_bytes_to_align_ptr(alloc, ZSTD_CWKSP_ALIGNMENT_BYTES); + void *const objectEnd = (BYTE *) alloc + bytesToAlign; + DEBUGLOG(5, "reserving table alignment addtl space: %zu", bytesToAlign); + RETURN_ERROR_IF(objectEnd > ws->workspaceEnd, memory_allocation, + "table phase - alignment initial allocation failed!"); + ws->objectEnd = objectEnd; + ws->tableEnd = objectEnd; /* table area starts being empty */ + if (ws->tableValidEnd < ws->tableEnd) { + ws->tableValidEnd = ws->tableEnd; + } + } + } + ws->phase = phase; + ZSTD_cwksp_assert_internal_consistency(ws); + } + return 0; +} + +/** + * Returns whether this object/buffer/etc was allocated in this workspace. + */ +MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr) +{ + return (ptr != NULL) && (ws->workspace <= ptr) && (ptr < ws->workspaceEnd); +} + +/** + * Internal function. Do not use directly. + */ +MEM_STATIC void* +ZSTD_cwksp_reserve_internal(ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase) +{ + void* alloc; + if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase)) || bytes == 0) { + return NULL; + } + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* over-reserve space */ + bytes += 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#endif + + alloc = ZSTD_cwksp_reserve_internal_buffer_space(ws, bytes); + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on + * either size. */ + if (alloc) { + alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + /* We need to keep the redzone poisoned while unpoisoning the bytes that + * are actually allocated. */ + __asan_unpoison_memory_region(alloc, bytes - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE); + } + } +#endif + + return alloc; +} + +/** + * Reserves and returns unaligned memory. + */ +MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes) +{ + return (BYTE*)ZSTD_cwksp_reserve_internal(ws, bytes, ZSTD_cwksp_alloc_buffers); +} + +/** + * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). + * This memory has been initialized at least once in the past. + * This doesn't mean it has been initialized this time, and it might contain data from previous + * operations. + * The main usage is for algorithms that might need read access into uninitialized memory. + * The algorithm must maintain safety under these conditions and must make sure it doesn't + * leak any of the past data (directly or in side channels). + */ +MEM_STATIC void* ZSTD_cwksp_reserve_aligned_init_once(ZSTD_cwksp* ws, size_t bytes) +{ + size_t const alignedBytes = ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES); + void* ptr = ZSTD_cwksp_reserve_internal(ws, alignedBytes, ZSTD_cwksp_alloc_aligned_init_once); + assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + if(ptr && ptr < ws->initOnceStart) { + /* We assume the memory following the current allocation is either: + * 1. Not usable as initOnce memory (end of workspace) + * 2. Another initOnce buffer that has been allocated before (and so was previously memset) + * 3. An ASAN redzone, in which case we don't want to write on it + * For these reasons it should be fine to not explicitly zero every byte up to ws->initOnceStart. + * Note that we assume here that MSAN and ASAN cannot run in the same time. */ + ZSTD_memset(ptr, 0, MIN((size_t)((U8*)ws->initOnceStart - (U8*)ptr), alignedBytes)); + ws->initOnceStart = ptr; + } +#if ZSTD_MEMORY_SANITIZER + assert(__msan_test_shadow(ptr, bytes) == -1); +#endif + return ptr; +} + +/** + * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). + */ +MEM_STATIC void* ZSTD_cwksp_reserve_aligned64(ZSTD_cwksp* ws, size_t bytes) +{ + void* const ptr = ZSTD_cwksp_reserve_internal(ws, + ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES), + ZSTD_cwksp_alloc_aligned); + assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + return ptr; +} + +/** + * Aligned on 64 bytes. These buffers have the special property that + * their values remain constrained, allowing us to reuse them without + * memset()-ing them. + */ +MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) +{ + const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned_init_once; + void* alloc; + void* end; + void* top; + + /* We can only start allocating tables after we are done reserving space for objects at the + * start of the workspace */ + if(ws->phase < phase) { + if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase))) { + return NULL; + } + } + alloc = ws->tableEnd; + end = (BYTE *)alloc + bytes; + top = ws->allocStart; + + DEBUGLOG(5, "cwksp: reserving %p table %zd bytes, %zd bytes remaining", + alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes); + assert((bytes & (sizeof(U32)-1)) == 0); + ZSTD_cwksp_assert_internal_consistency(ws); + assert(end <= top); + if (end > top) { + DEBUGLOG(4, "cwksp: table alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + ws->tableEnd = end; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } +#endif + + assert((bytes & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + assert(((size_t)alloc & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + return alloc; +} + +/** + * Aligned on sizeof(void*). + * Note : should happen only once, at workspace first initialization + */ +MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) +{ + size_t const roundedBytes = ZSTD_cwksp_align(bytes, sizeof(void*)); + void* alloc = ws->objectEnd; + void* end = (BYTE*)alloc + roundedBytes; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* over-reserve space */ + end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#endif + + DEBUGLOG(4, + "cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining", + alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes); + assert((size_t)alloc % ZSTD_ALIGNOF(void*) == 0); + assert(bytes % ZSTD_ALIGNOF(void*) == 0); + ZSTD_cwksp_assert_internal_consistency(ws); + /* we must be in the first phase, no advance is possible */ + if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) { + DEBUGLOG(3, "cwksp: object alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + ws->objectEnd = end; + ws->tableEnd = end; + ws->tableValidEnd = end; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on + * either size. */ + alloc = (BYTE*)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } +#endif + + return alloc; +} +/** + * with alignment control + * Note : should happen only once, at workspace first initialization + */ +MEM_STATIC void* ZSTD_cwksp_reserve_object_aligned(ZSTD_cwksp* ws, size_t byteSize, size_t alignment) +{ + size_t const mask = alignment - 1; + size_t const surplus = (alignment > sizeof(void*)) ? alignment - sizeof(void*) : 0; + void* const start = ZSTD_cwksp_reserve_object(ws, byteSize + surplus); + if (start == NULL) return NULL; + if (surplus == 0) return start; + assert(ZSTD_isPower2(alignment)); + return (void*)(((size_t)start + surplus) & ~mask); +} + +MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) +{ + DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty"); + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the table reuse logic is sound, and that we don't + * access table space that we haven't cleaned, we re-"poison" the table + * space every time we mark it dirty. + * Since tableValidEnd space and initOnce space may overlap we don't poison + * the initOnce portion as it break its promise. This means that this poisoning + * check isn't always applied fully. */ + { + size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd; + assert(__msan_test_shadow(ws->objectEnd, size) == -1); + if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) { + __msan_poison(ws->objectEnd, size); + } else { + assert(ws->initOnceStart >= ws->objectEnd); + __msan_poison(ws->objectEnd, (BYTE*)ws->initOnceStart - (BYTE*)ws->objectEnd); + } + } +#endif + + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + ws->tableValidEnd = ws->objectEnd; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC void ZSTD_cwksp_mark_tables_clean(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_clean"); + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + if (ws->tableValidEnd < ws->tableEnd) { + ws->tableValidEnd = ws->tableEnd; + } + ZSTD_cwksp_assert_internal_consistency(ws); +} + +/** + * Zero the part of the allocated tables not already marked clean. + */ +MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: ZSTD_cwksp_clean_tables"); + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + if (ws->tableValidEnd < ws->tableEnd) { + ZSTD_memset(ws->tableValidEnd, 0, (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd)); + } + ZSTD_cwksp_mark_tables_clean(ws); +} + +/** + * Invalidates table allocations. + * All other allocations remain valid. + */ +MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) +{ + DEBUGLOG(4, "cwksp: clearing tables!"); + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* We don't do this when the workspace is statically allocated, because + * when that is the case, we have no capability to hook into the end of the + * workspace's lifecycle to unpoison the memory. + */ + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd; + __asan_poison_memory_region(ws->objectEnd, size); + } +#endif + + ws->tableEnd = ws->objectEnd; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +/** + * Invalidates all buffer, aligned, and table allocations. + * Object allocations remain valid. + */ +MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: clearing!"); + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the context reuse logic is sound, and that we don't + * access stuff that this compression hasn't initialized, we re-"poison" + * the workspace except for the areas in which we expect memory reuse + * without initialization (objects, valid tables area and init once + * memory). */ + { + if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) { + size_t size = (BYTE*)ws->initOnceStart - (BYTE*)ws->tableValidEnd; + __msan_poison(ws->tableValidEnd, size); + } + } +#endif + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* We don't do this when the workspace is statically allocated, because + * when that is the case, we have no capability to hook into the end of the + * workspace's lifecycle to unpoison the memory. + */ + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd; + __asan_poison_memory_region(ws->objectEnd, size); + } +#endif + + ws->tableEnd = ws->objectEnd; + ws->allocStart = ZSTD_cwksp_initialAllocStart(ws); + ws->allocFailed = 0; + if (ws->phase > ZSTD_cwksp_alloc_aligned_init_once) { + ws->phase = ZSTD_cwksp_alloc_aligned_init_once; + } + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace); +} + +MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace) + + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart); +} + +/** + * The provided workspace takes ownership of the buffer [start, start+size). + * Any existing values in the workspace are ignored (the previously managed + * buffer, if present, must be separately freed). + */ +MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size, ZSTD_cwksp_static_alloc_e isStatic) { + DEBUGLOG(4, "cwksp: init'ing workspace with %zd bytes", size); + assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */ + ws->workspace = start; + ws->workspaceEnd = (BYTE*)start + size; + ws->objectEnd = ws->workspace; + ws->tableValidEnd = ws->objectEnd; + ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws); + ws->phase = ZSTD_cwksp_alloc_objects; + ws->isStatic = isStatic; + ZSTD_cwksp_clear(ws); + ws->workspaceOversizedDuration = 0; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) { + void* workspace = ZSTD_customMalloc(size, customMem); + DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size); + RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!"); + ZSTD_cwksp_init(ws, workspace, size, ZSTD_cwksp_dynamic_alloc); + return 0; +} + +MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) { + void *ptr = ws->workspace; + DEBUGLOG(4, "cwksp: freeing workspace"); +#if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE) + if (ptr != NULL && customMem.customFree != NULL) { + __msan_unpoison(ptr, ZSTD_cwksp_sizeof(ws)); + } +#endif + ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp)); + ZSTD_customFree(ptr, customMem); +} + +/** + * Moves the management of a workspace from one cwksp to another. The src cwksp + * is left in an invalid state (src must be re-init()'ed before it's used again). + */ +MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) { + *dst = *src; + ZSTD_memset(src, 0, sizeof(ZSTD_cwksp)); +} + +MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) { + return ws->allocFailed; +} + +/*-************************************* +* Functions Checking Free Space +***************************************/ + +/* ZSTD_alignmentSpaceWithinBounds() : + * Returns if the estimated space needed for a wksp is within an acceptable limit of the + * actual amount of space used. + */ +MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp *const ws, size_t const estimatedSpace) { + /* We have an alignment space between objects and tables between tables and buffers, so we can have up to twice + * the alignment bytes difference between estimation and actual usage */ + return (estimatedSpace - ZSTD_cwksp_slack_space_required()) <= ZSTD_cwksp_used(ws) && + ZSTD_cwksp_used(ws) <= estimatedSpace; +} + + +MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->allocStart - (BYTE*)ws->tableEnd); +} + +MEM_STATIC int ZSTD_cwksp_check_available(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_available_space(ws) >= additionalNeededSpace; +} + +MEM_STATIC int ZSTD_cwksp_check_too_large(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_check_available( + ws, additionalNeededSpace * ZSTD_WORKSPACETOOLARGE_FACTOR); +} + +MEM_STATIC int ZSTD_cwksp_check_wasteful(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_check_too_large(ws, additionalNeededSpace) + && ws->workspaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION; +} + +MEM_STATIC void ZSTD_cwksp_bump_oversized_duration( + ZSTD_cwksp* ws, size_t additionalNeededSpace) { + if (ZSTD_cwksp_check_too_large(ws, additionalNeededSpace)) { + ws->workspaceOversizedDuration++; + } else { + ws->workspaceOversizedDuration = 0; + } +} + +#endif /* ZSTD_CWKSP_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_double_fast.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_double_fast.c new file mode 100644 index 000000000..1a266e7d9 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_double_fast.c @@ -0,0 +1,778 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "zstd_double_fast.h" + +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillDoubleHashTableForCDict(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashLarge = ms->hashTable; + U32 const hBitsL = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + U32 const mls = cParams->minMatch; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Always insert every fastHashFillStep position into the hash tables. + * Insert the other positions into the large hash table if their entry + * is empty. + */ + for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + U32 i; + for (i = 0; i < fastHashFillStep; ++i) { + size_t const smHashAndTag = ZSTD_hashPtr(ip + i, hBitsS, mls); + size_t const lgHashAndTag = ZSTD_hashPtr(ip + i, hBitsL, 8); + if (i == 0) { + ZSTD_writeTaggedIndex(hashSmall, smHashAndTag, curr + i); + } + if (i == 0 || hashLarge[lgHashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) { + ZSTD_writeTaggedIndex(hashLarge, lgHashAndTag, curr + i); + } + /* Only load extra positions for ZSTD_dtlm_full */ + if (dtlm == ZSTD_dtlm_fast) + break; + } } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillDoubleHashTableForCCtx(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashLarge = ms->hashTable; + U32 const hBitsL = cParams->hashLog; + U32 const mls = cParams->minMatch; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Always insert every fastHashFillStep position into the hash tables. + * Insert the other positions into the large hash table if their entry + * is empty. + */ + for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + U32 i; + for (i = 0; i < fastHashFillStep; ++i) { + size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls); + size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8); + if (i == 0) + hashSmall[smHash] = curr + i; + if (i == 0 || hashLarge[lgHash] == 0) + hashLarge[lgHash] = curr + i; + /* Only load extra positions for ZSTD_dtlm_full */ + if (dtlm == ZSTD_dtlm_fast) + break; + } } +} + +void ZSTD_fillDoubleHashTable(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + if (tfp == ZSTD_tfp_forCDict) { + ZSTD_fillDoubleHashTableForCDict(ms, end, dtlm); + } else { + ZSTD_fillDoubleHashTableForCCtx(ms, end, dtlm); + } +} + + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_noDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + const U32 hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + const U32 hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + /* presumes that, if there is a dictionary, it must be using Attach mode */ + const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixLowest = base + prefixLowestIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + size_t mLength; + U32 offset; + U32 curr; + + /* how many positions to search before increasing step size */ + const size_t kStepIncr = 1 << kSearchStrength; + /* the position at which to increment the step size if no match is found */ + const BYTE* nextStep; + size_t step; /* the current step size */ + + size_t hl0; /* the long hash at ip */ + size_t hl1; /* the long hash at ip1 */ + + U32 idxl0; /* the long match index for ip */ + U32 idxl1; /* the long match index for ip1 */ + + const BYTE* matchl0; /* the long match for ip */ + const BYTE* matchs0; /* the short match for ip */ + const BYTE* matchl1; /* the long match for ip1 */ + const BYTE* matchs0_safe; /* matchs0 or safe address */ + + const BYTE* ip = istart; /* the current position */ + const BYTE* ip1; /* the next position */ + /* Array of ~random data, should have low probability of matching data + * we load from here instead of from tables, if matchl0/matchl1 are + * invalid indices. Used to avoid unpredictable branches. */ + const BYTE dummy[] = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0xe2,0xb4}; + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_noDict_generic"); + + /* init */ + ip += ((ip - prefixLowest) == 0); + { + U32 const current = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog); + U32 const maxRep = current - windowLow; + if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + + /* Outer Loop: one iteration per match found and stored */ + while (1) { + step = 1; + nextStep = ip + kStepIncr; + ip1 = ip + step; + + if (ip1 > ilimit) { + goto _cleanup; + } + + hl0 = ZSTD_hashPtr(ip, hBitsL, 8); + idxl0 = hashLong[hl0]; + matchl0 = base + idxl0; + + /* Inner Loop: one iteration per search / position */ + do { + const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 idxs0 = hashSmall[hs0]; + curr = (U32)(ip-base); + matchs0 = base + idxs0; + + hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */ + + /* check noDict repcode */ + if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { + mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + goto _match_stored; + } + + hl1 = ZSTD_hashPtr(ip1, hBitsL, 8); + + /* idxl0 > prefixLowestIndex is a (somewhat) unpredictable branch. + * However expression below complies into conditional move. Since + * match is unlikely and we only *branch* on idxl0 > prefixLowestIndex + * if there is a match, all branches become predictable. */ + { const BYTE* const matchl0_safe = ZSTD_selectAddr(idxl0, prefixLowestIndex, matchl0, &dummy[0]); + + /* check prefix long match */ + if (MEM_read64(matchl0_safe) == MEM_read64(ip) && matchl0_safe == matchl0) { + mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8; + offset = (U32)(ip-matchl0); + while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */ + goto _match_found; + } } + + idxl1 = hashLong[hl1]; + matchl1 = base + idxl1; + + /* Same optimization as matchl0 above */ + matchs0_safe = ZSTD_selectAddr(idxs0, prefixLowestIndex, matchs0, &dummy[0]); + + /* check prefix short match */ + if(MEM_read32(matchs0_safe) == MEM_read32(ip) && matchs0_safe == matchs0) { + goto _search_next_long; + } + + if (ip1 >= nextStep) { + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + step++; + nextStep += kStepIncr; + } + ip = ip1; + ip1 += step; + + hl0 = hl1; + idxl0 = idxl1; + matchl0 = matchl1; + #if defined(__aarch64__) + PREFETCH_L1(ip+256); + #endif + } while (ip1 <= ilimit); + +_cleanup: + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_search_next_long: + + /* short match found: let's check for a longer one */ + mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; + offset = (U32)(ip - matchs0); + + /* check long match at +1 position */ + if ((idxl1 > prefixLowestIndex) && (MEM_read64(matchl1) == MEM_read64(ip1))) { + size_t const l1len = ZSTD_count(ip1+8, matchl1+8, iend) + 8; + if (l1len > mLength) { + /* use the long match instead */ + ip = ip1; + mLength = l1len; + offset = (U32)(ip-matchl1); + matchs0 = matchl1; + } + } + + while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* complete backward */ + + /* fall-through */ + +_match_found: /* requires ip, offset, mLength */ + offset_2 = offset_1; + offset_1 = offset; + + if (step < 4) { + /* It is unsafe to write this value back to the hashtable when ip1 is + * greater than or equal to the new ip we will have after we're done + * processing this match. Rather than perform that test directly + * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler + * more predictable test. The minmatch even if we take a short match is + * 4 bytes, so as long as step, the distance between ip and ip1 + * (initially) is less than 4, we know ip1 < new ip. */ + hashLong[hl1] = (U32)(ip1 - base); + } + + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while ( (ip <= ilimit) + && ( (offset_2>0) + & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, rLength); + ip += rLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + } + } +} + + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + const U32 hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + const U32 hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + /* presumes that, if there is a dictionary, it must be using Attach mode */ + const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixLowest = base + prefixLowestIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dictCParams = &dms->cParams; + const U32* const dictHashLong = dms->hashTable; + const U32* const dictHashSmall = dms->chainTable; + const U32 dictStartIndex = dms->window.dictLimit; + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dms->window.nextSrc; + const U32 dictIndexDelta = prefixLowestIndex - (U32)(dictEnd - dictBase); + const U32 dictHBitsL = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + const U32 dictHBitsS = dictCParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS; + const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictStart)); + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_dictMatchState_generic"); + + /* if a dictionary is attached, it must be within window range */ + assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex); + + if (ms->prefetchCDictTables) { + size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32); + size_t const chainTableBytes = (((size_t)1) << dictCParams->chainLog) * sizeof(U32); + PREFETCH_AREA(dictHashLong, hashTableBytes); + PREFETCH_AREA(dictHashSmall, chainTableBytes); + } + + /* init */ + ip += (dictAndPrefixLength == 0); + + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + + /* Main Search Loop */ + while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ + size_t mLength; + U32 offset; + size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8); + size_t const h = ZSTD_hashPtr(ip, hBitsS, mls); + size_t const dictHashAndTagL = ZSTD_hashPtr(ip, dictHBitsL, 8); + size_t const dictHashAndTagS = ZSTD_hashPtr(ip, dictHBitsS, mls); + U32 const dictMatchIndexAndTagL = dictHashLong[dictHashAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS]; + U32 const dictMatchIndexAndTagS = dictHashSmall[dictHashAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS]; + int const dictTagsMatchL = ZSTD_comparePackedTags(dictMatchIndexAndTagL, dictHashAndTagL); + int const dictTagsMatchS = ZSTD_comparePackedTags(dictMatchIndexAndTagS, dictHashAndTagS); + U32 const curr = (U32)(ip-base); + U32 const matchIndexL = hashLong[h2]; + U32 matchIndexS = hashSmall[h]; + const BYTE* matchLong = base + matchIndexL; + const BYTE* match = base + matchIndexS; + const U32 repIndex = curr + 1 - offset_1; + const BYTE* repMatch = (repIndex < prefixLowestIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + hashLong[h2] = hashSmall[h] = curr; /* update hash tables */ + + /* check repcode */ + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + goto _match_stored; + } + + if ((matchIndexL >= prefixLowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) { + /* check prefix long match */ + mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8; + offset = (U32)(ip-matchLong); + while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + goto _match_found; + } else if (dictTagsMatchL) { + /* check dictMatchState long match */ + U32 const dictMatchIndexL = dictMatchIndexAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatchL = dictBase + dictMatchIndexL; + assert(dictMatchL < dictEnd); + + if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) { + mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8; + offset = (U32)(curr - dictMatchIndexL - dictIndexDelta); + while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */ + goto _match_found; + } } + + if (matchIndexS > prefixLowestIndex) { + /* short match candidate */ + if (MEM_read32(match) == MEM_read32(ip)) { + goto _search_next_long; + } + } else if (dictTagsMatchS) { + /* check dictMatchState short match */ + U32 const dictMatchIndexS = dictMatchIndexAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS; + match = dictBase + dictMatchIndexS; + matchIndexS = dictMatchIndexS + dictIndexDelta; + + if (match > dictStart && MEM_read32(match) == MEM_read32(ip)) { + goto _search_next_long; + } } + + ip += ((ip-anchor) >> kSearchStrength) + 1; +#if defined(__aarch64__) + PREFETCH_L1(ip+256); +#endif + continue; + +_search_next_long: + { size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8); + size_t const dictHashAndTagL3 = ZSTD_hashPtr(ip+1, dictHBitsL, 8); + U32 const matchIndexL3 = hashLong[hl3]; + U32 const dictMatchIndexAndTagL3 = dictHashLong[dictHashAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS]; + int const dictTagsMatchL3 = ZSTD_comparePackedTags(dictMatchIndexAndTagL3, dictHashAndTagL3); + const BYTE* matchL3 = base + matchIndexL3; + hashLong[hl3] = curr + 1; + + /* check prefix long +1 match */ + if ((matchIndexL3 >= prefixLowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1))) { + mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8; + ip++; + offset = (U32)(ip-matchL3); + while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */ + goto _match_found; + } else if (dictTagsMatchL3) { + /* check dict long +1 match */ + U32 const dictMatchIndexL3 = dictMatchIndexAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3; + assert(dictMatchL3 < dictEnd); + if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) { + mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8; + ip++; + offset = (U32)(curr + 1 - dictMatchIndexL3 - dictIndexDelta); + while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */ + goto _match_found; + } } } + + /* if no long +1 match, explore the short match we found */ + if (matchIndexS < prefixLowestIndex) { + mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4; + offset = (U32)(curr - matchIndexS); + while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } else { + mLength = ZSTD_count(ip+4, match+4, iend) + 4; + offset = (U32)(ip - match); + while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } + +_match_found: + offset_2 = offset_1; + offset_1 = offset; + + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixLowestIndex ? + dictBase + repIndex2 - dictIndexDelta : + base + repIndex2; + if ( (ZSTD_index_overlap_check(prefixLowestIndex, repIndex2)) + && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4; + U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2; + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2; + ip += repLength2; + anchor = ip; + continue; + } + break; + } + } + } /* while (ip < ilimit) */ + + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + +#define ZSTD_GEN_DFAST_FN(dictMode, mls) \ + static size_t ZSTD_compressBlock_doubleFast_##dictMode##_##mls( \ + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ + void const* src, size_t srcSize) \ + { \ + return ZSTD_compressBlock_doubleFast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls); \ + } + +ZSTD_GEN_DFAST_FN(noDict, 4) +ZSTD_GEN_DFAST_FN(noDict, 5) +ZSTD_GEN_DFAST_FN(noDict, 6) +ZSTD_GEN_DFAST_FN(noDict, 7) + +ZSTD_GEN_DFAST_FN(dictMatchState, 4) +ZSTD_GEN_DFAST_FN(dictMatchState, 5) +ZSTD_GEN_DFAST_FN(dictMatchState, 6) +ZSTD_GEN_DFAST_FN(dictMatchState, 7) + + +size_t ZSTD_compressBlock_doubleFast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + const U32 mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_noDict_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_noDict_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_noDict_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_noDict_7(ms, seqStore, rep, src, srcSize); + } +} + + +size_t ZSTD_compressBlock_doubleFast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + const U32 mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_dictMatchState_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_dictMatchState_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_dictMatchState_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_dictMatchState_7(ms, seqStore, rep, src, srcSize); + } +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + U32 const hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + const BYTE* const base = ms->window.base; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog); + const U32 dictStartIndex = lowLimit; + const U32 dictLimit = ms->window.dictLimit; + const U32 prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dictBase + prefixStartIndex; + U32 offset_1=rep[0], offset_2=rep[1]; + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)", srcSize); + + /* if extDict is invalidated due to maxDistance, switch to "regular" variant */ + if (prefixStartIndex == dictStartIndex) + return ZSTD_compressBlock_doubleFast(ms, seqStore, rep, src, srcSize); + + /* Search Loop */ + while (ip < ilimit) { /* < instead of <=, because (ip+1) */ + const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 matchIndex = hashSmall[hSmall]; + const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base; + const BYTE* match = matchBase + matchIndex; + + const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8); + const U32 matchLongIndex = hashLong[hLong]; + const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base; + const BYTE* matchLong = matchLongBase + matchLongIndex; + + const U32 curr = (U32)(ip-base); + const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */ + const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + size_t mLength; + hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */ + + if (((ZSTD_index_overlap_check(prefixStartIndex, repIndex)) + & (offset_1 <= curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */ + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + } else { + if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) { + const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart; + U32 offset; + mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8; + offset = curr - matchLongIndex; + while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + + } else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) { + size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8); + U32 const matchIndex3 = hashLong[h3]; + const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base; + const BYTE* match3 = match3Base + matchIndex3; + U32 offset; + hashLong[h3] = curr + 1; + if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) { + const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart; + mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8; + ip++; + offset = curr+1 - matchIndex3; + while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */ + } else { + const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart; + mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4; + offset = curr - matchIndex; + while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + + } else { + ip += ((ip-anchor) >> kSearchStrength) + 1; + continue; + } } + + /* move to next sequence start */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; + if ( ((ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) + & (offset_2 <= current2 - dictStartIndex)) + && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2; + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2; + ip += repLength2; + anchor = ip; + continue; + } + break; + } } } + + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + +ZSTD_GEN_DFAST_FN(extDict, 4) +ZSTD_GEN_DFAST_FN(extDict, 5) +ZSTD_GEN_DFAST_FN(extDict, 6) +ZSTD_GEN_DFAST_FN(extDict, 7) + +size_t ZSTD_compressBlock_doubleFast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_extDict_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_extDict_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_extDict_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_extDict_7(ms, seqStore, rep, src, srcSize); + } +} + +#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_double_fast.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_double_fast.h new file mode 100644 index 000000000..cd562fea8 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_double_fast.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_DOUBLE_FAST_H +#define ZSTD_DOUBLE_FAST_H + +#include "../common/mem.h" /* U32 */ +#include "zstd_compress_internal.h" /* ZSTD_CCtx, size_t */ + +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + +void ZSTD_fillDoubleHashTable(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp); + +size_t ZSTD_compressBlock_doubleFast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_doubleFast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_doubleFast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST ZSTD_compressBlock_doubleFast +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE ZSTD_compressBlock_doubleFast_dictMatchState +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT ZSTD_compressBlock_doubleFast_extDict +#else +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST NULL +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT NULL +#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */ + +#endif /* ZSTD_DOUBLE_FAST_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_fast.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_fast.c new file mode 100644 index 000000000..ee25bcbac --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_fast.c @@ -0,0 +1,985 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" /* ZSTD_hashPtr, ZSTD_count, ZSTD_storeSeq */ +#include "zstd_fast.h" + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillHashTableForCDict(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hBits = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + U32 const mls = cParams->minMatch; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Currently, we always use ZSTD_dtlm_full for filling CDict tables. + * Feel free to remove this assert if there's a good reason! */ + assert(dtlm == ZSTD_dtlm_full); + + /* Always insert every fastHashFillStep position into the hash table. + * Insert the other positions if their hash entry is empty. + */ + for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + { size_t const hashAndTag = ZSTD_hashPtr(ip, hBits, mls); + ZSTD_writeTaggedIndex(hashTable, hashAndTag, curr); } + + if (dtlm == ZSTD_dtlm_fast) continue; + /* Only load extra positions for ZSTD_dtlm_full */ + { U32 p; + for (p = 1; p < fastHashFillStep; ++p) { + size_t const hashAndTag = ZSTD_hashPtr(ip + p, hBits, mls); + if (hashTable[hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) { /* not yet filled */ + ZSTD_writeTaggedIndex(hashTable, hashAndTag, curr + p); + } } } } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillHashTableForCCtx(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hBits = cParams->hashLog; + U32 const mls = cParams->minMatch; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Currently, we always use ZSTD_dtlm_fast for filling CCtx tables. + * Feel free to remove this assert if there's a good reason! */ + assert(dtlm == ZSTD_dtlm_fast); + + /* Always insert every fastHashFillStep position into the hash table. + * Insert the other positions if their hash entry is empty. + */ + for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls); + hashTable[hash0] = curr; + if (dtlm == ZSTD_dtlm_fast) continue; + /* Only load extra positions for ZSTD_dtlm_full */ + { U32 p; + for (p = 1; p < fastHashFillStep; ++p) { + size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls); + if (hashTable[hash] == 0) { /* not yet filled */ + hashTable[hash] = curr + p; + } } } } +} + +void ZSTD_fillHashTable(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + if (tfp == ZSTD_tfp_forCDict) { + ZSTD_fillHashTableForCDict(ms, end, dtlm); + } else { + ZSTD_fillHashTableForCCtx(ms, end, dtlm); + } +} + + +typedef int (*ZSTD_match4Found) (const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit); + +static int +ZSTD_match4Found_cmov(const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit) +{ + /* Array of ~random data, should have low probability of matching data. + * Load from here if the index is invalid. + * Used to avoid unpredictable branches. */ + static const BYTE dummy[] = {0x12,0x34,0x56,0x78}; + + /* currentIdx >= lowLimit is a (somewhat) unpredictable branch. + * However expression below compiles into conditional move. + */ + const BYTE* mvalAddr = ZSTD_selectAddr(matchIdx, idxLowLimit, matchAddress, dummy); + /* Note: this used to be written as : return test1 && test2; + * Unfortunately, once inlined, these tests become branches, + * in which case it becomes critical that they are executed in the right order (test1 then test2). + * So we have to write these tests in a specific manner to ensure their ordering. + */ + if (MEM_read32(currentPtr) != MEM_read32(mvalAddr)) return 0; + /* force ordering of these tests, which matters once the function is inlined, as they become branches */ +#if defined(__GNUC__) + __asm__(""); +#endif + return matchIdx >= idxLowLimit; +} + +static int +ZSTD_match4Found_branch(const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit) +{ + /* using a branch instead of a cmov, + * because it's faster in scenarios where matchIdx >= idxLowLimit is generally true, + * aka almost all candidates are within range */ + U32 mval; + if (matchIdx >= idxLowLimit) { + mval = MEM_read32(matchAddress); + } else { + mval = MEM_read32(currentPtr) ^ 1; /* guaranteed to not match. */ + } + + return (MEM_read32(currentPtr) == mval); +} + + +/** + * If you squint hard enough (and ignore repcodes), the search operation at any + * given position is broken into 4 stages: + * + * 1. Hash (map position to hash value via input read) + * 2. Lookup (map hash val to index via hashtable read) + * 3. Load (map index to value at that position via input read) + * 4. Compare + * + * Each of these steps involves a memory read at an address which is computed + * from the previous step. This means these steps must be sequenced and their + * latencies are cumulative. + * + * Rather than do 1->2->3->4 sequentially for a single position before moving + * onto the next, this implementation interleaves these operations across the + * next few positions: + * + * R = Repcode Read & Compare + * H = Hash + * T = Table Lookup + * M = Match Read & Compare + * + * Pos | Time --> + * ----+------------------- + * N | ... M + * N+1 | ... TM + * N+2 | R H T M + * N+3 | H TM + * N+4 | R H T M + * N+5 | H ... + * N+6 | R ... + * + * This is very much analogous to the pipelining of execution in a CPU. And just + * like a CPU, we have to dump the pipeline when we find a match (i.e., take a + * branch). + * + * When this happens, we throw away our current state, and do the following prep + * to re-enter the loop: + * + * Pos | Time --> + * ----+------------------- + * N | H T + * N+1 | H + * + * This is also the work we do at the beginning to enter the loop initially. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_noDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls, int useCmov) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1; /* min 2 */ + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + + const BYTE* anchor = istart; + const BYTE* ip0 = istart; + const BYTE* ip1; + const BYTE* ip2; + const BYTE* ip3; + U32 current0; + + U32 rep_offset1 = rep[0]; + U32 rep_offset2 = rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + size_t hash0; /* hash for ip0 */ + size_t hash1; /* hash for ip1 */ + U32 matchIdx; /* match idx for ip0 */ + + U32 offcode; + const BYTE* match0; + size_t mLength; + + /* ip0 and ip1 are always adjacent. The targetLength skipping and + * uncompressibility acceleration is applied to every other position, + * matching the behavior of #1562. step therefore represents the gap + * between pairs of positions, from ip0 to ip2 or ip1 to ip3. */ + size_t step; + const BYTE* nextStep; + const size_t kStepIncr = (1 << (kSearchStrength - 1)); + const ZSTD_match4Found matchFound = useCmov ? ZSTD_match4Found_cmov : ZSTD_match4Found_branch; + + DEBUGLOG(5, "ZSTD_compressBlock_fast_generic"); + ip0 += (ip0 == prefixStart); + { U32 const curr = (U32)(ip0 - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); + U32 const maxRep = curr - windowLow; + if (rep_offset2 > maxRep) offsetSaved2 = rep_offset2, rep_offset2 = 0; + if (rep_offset1 > maxRep) offsetSaved1 = rep_offset1, rep_offset1 = 0; + } + + /* start each op */ +_start: /* Requires: ip0 */ + + step = stepSize; + nextStep = ip0 + kStepIncr; + + /* calculate positions, ip0 - anchor == 0, so we skip step calc */ + ip1 = ip0 + 1; + ip2 = ip0 + step; + ip3 = ip2 + 1; + + if (ip3 >= ilimit) { + goto _cleanup; + } + + hash0 = ZSTD_hashPtr(ip0, hlog, mls); + hash1 = ZSTD_hashPtr(ip1, hlog, mls); + + matchIdx = hashTable[hash0]; + + do { + /* load repcode match for ip[2]*/ + const U32 rval = MEM_read32(ip2 - rep_offset1); + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + /* check repcode at ip[2] */ + if ((MEM_read32(ip2) == rval) & (rep_offset1 > 0)) { + ip0 = ip2; + match0 = ip0 - rep_offset1; + mLength = ip0[-1] == match0[-1]; + ip0 -= mLength; + match0 -= mLength; + offcode = REPCODE1_TO_OFFBASE; + mLength += 4; + + /* Write next hash table entry: it's already calculated. + * This write is known to be safe because ip1 is before the + * repcode (ip2). */ + hashTable[hash1] = (U32)(ip1 - base); + + goto _match; + } + + if (matchFound(ip0, base + matchIdx, matchIdx, prefixStartIndex)) { + /* Write next hash table entry (it's already calculated). + * This write is known to be safe because the ip1 == ip0 + 1, + * so searching will resume after ip1 */ + hashTable[hash1] = (U32)(ip1 - base); + + goto _offset; + } + + /* lookup ip[1] */ + matchIdx = hashTable[hash1]; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip3; + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + if (matchFound(ip0, base + matchIdx, matchIdx, prefixStartIndex)) { + /* Write next hash table entry, since it's already calculated */ + if (step <= 4) { + /* Avoid writing an index if it's >= position where search will resume. + * The minimum possible match has length 4, so search can resume at ip0 + 4. + */ + hashTable[hash1] = (U32)(ip1 - base); + } + goto _offset; + } + + /* lookup ip[1] */ + matchIdx = hashTable[hash1]; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip0 + step; + ip3 = ip1 + step; + + /* calculate step */ + if (ip2 >= nextStep) { + step++; + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + nextStep += kStepIncr; + } + } while (ip3 < ilimit); + +_cleanup: + /* Note that there are probably still a couple positions one could search. + * However, it seems to be a meaningful performance hit to try to search + * them. So let's not. */ + + /* When the repcodes are outside of the prefix, we set them to zero before the loop. + * When the offsets are still zero, we need to restore them after the block to have a correct + * repcode history. If only one offset was invalid, it is easy. The tricky case is when both + * offsets were invalid. We need to figure out which offset to refill with. + * - If both offsets are zero they are in the same order. + * - If both offsets are non-zero, we won't restore the offsets from `offsetSaved[12]`. + * - If only one is zero, we need to decide which offset to restore. + * - If rep_offset1 is non-zero, then rep_offset2 must be offsetSaved1. + * - It is impossible for rep_offset2 to be non-zero. + * + * So if rep_offset1 started invalid (offsetSaved1 != 0) and became valid (rep_offset1 != 0), then + * set rep[0] = rep_offset1 and rep[1] = offsetSaved1. + */ + offsetSaved2 = ((offsetSaved1 != 0) && (rep_offset1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = rep_offset1 ? rep_offset1 : offsetSaved1; + rep[1] = rep_offset2 ? rep_offset2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_offset: /* Requires: ip0, idx */ + + /* Compute the offset code. */ + match0 = base + matchIdx; + rep_offset2 = rep_offset1; + rep_offset1 = (U32)(ip0-match0); + offcode = OFFSET_TO_OFFBASE(rep_offset1); + mLength = 4; + + /* Count the backwards match length. */ + while (((ip0>anchor) & (match0>prefixStart)) && (ip0[-1] == match0[-1])) { + ip0--; + match0--; + mLength++; + } + +_match: /* Requires: ip0, match0, offcode */ + + /* Count the forward length. */ + mLength += ZSTD_count(ip0 + mLength, match0 + mLength, iend); + + ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength); + + ip0 += mLength; + anchor = ip0; + + /* Fill table and check for immediate repcode. */ + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+current0+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + if (rep_offset2 > 0) { /* rep_offset2==0 means rep_offset2 is invalidated */ + while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - rep_offset2)) ) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip0+4, ip0+4-rep_offset2, iend) + 4; + { U32 const tmpOff = rep_offset2; rep_offset2 = rep_offset1; rep_offset1 = tmpOff; } /* swap rep_offset2 <=> rep_offset1 */ + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base); + ip0 += rLength; + ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, REPCODE1_TO_OFFBASE, rLength); + anchor = ip0; + continue; /* faster when present (confirmed on gcc-8) ... (?) */ + } } } + + goto _start; +} + +#define ZSTD_GEN_FAST_FN(dictMode, mml, cmov) \ + static size_t ZSTD_compressBlock_fast_##dictMode##_##mml##_##cmov( \ + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ + void const* src, size_t srcSize) \ + { \ + return ZSTD_compressBlock_fast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mml, cmov); \ + } + +ZSTD_GEN_FAST_FN(noDict, 4, 1) +ZSTD_GEN_FAST_FN(noDict, 5, 1) +ZSTD_GEN_FAST_FN(noDict, 6, 1) +ZSTD_GEN_FAST_FN(noDict, 7, 1) + +ZSTD_GEN_FAST_FN(noDict, 4, 0) +ZSTD_GEN_FAST_FN(noDict, 5, 0) +ZSTD_GEN_FAST_FN(noDict, 6, 0) +ZSTD_GEN_FAST_FN(noDict, 7, 0) + +size_t ZSTD_compressBlock_fast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mml = ms->cParams.minMatch; + /* use cmov when "candidate in range" branch is likely unpredictable */ + int const useCmov = ms->cParams.windowLog < 19; + assert(ms->dictMatchState == NULL); + if (useCmov) { + switch(mml) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_noDict_4_1(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_noDict_5_1(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_noDict_6_1(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_noDict_7_1(ms, seqStore, rep, src, srcSize); + } + } else { + /* use a branch instead */ + switch(mml) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_noDict_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_noDict_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_noDict_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_noDict_7_0(ms, seqStore, rep, src, srcSize); + } + } +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_dictMatchState_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls, U32 const hasStep) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + /* support stepSize of 0 */ + U32 const stepSize = cParams->targetLength + !(cParams->targetLength); + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip0 = istart; + const BYTE* ip1 = ip0 + stepSize; /* we assert below that stepSize >= 1 */ + const BYTE* anchor = istart; + const U32 prefixStartIndex = ms->window.dictLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dictCParams = &dms->cParams ; + const U32* const dictHashTable = dms->hashTable; + const U32 dictStartIndex = dms->window.dictLimit; + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dms->window.nextSrc; + const U32 dictIndexDelta = prefixStartIndex - (U32)(dictEnd - dictBase); + const U32 dictAndPrefixLength = (U32)(istart - prefixStart + dictEnd - dictStart); + const U32 dictHBits = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + + /* if a dictionary is still attached, it necessarily means that + * it is within window size. So we just check it. */ + const U32 maxDistance = 1U << cParams->windowLog; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + assert(endIndex - prefixStartIndex <= maxDistance); + (void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */ + + (void)hasStep; /* not currently specialized on whether it's accelerated */ + + /* ensure there will be no underflow + * when translating a dict index into a local index */ + assert(prefixStartIndex >= (U32)(dictEnd - dictBase)); + + if (ms->prefetchCDictTables) { + size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32); + PREFETCH_AREA(dictHashTable, hashTableBytes); + } + + /* init */ + DEBUGLOG(5, "ZSTD_compressBlock_fast_dictMatchState_generic"); + ip0 += (dictAndPrefixLength == 0); + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + + /* Outer search loop */ + assert(stepSize >= 1); + while (ip1 <= ilimit) { /* repcode check at (ip0 + 1) is safe because ip0 < ip1 */ + size_t mLength; + size_t hash0 = ZSTD_hashPtr(ip0, hlog, mls); + + size_t const dictHashAndTag0 = ZSTD_hashPtr(ip0, dictHBits, mls); + U32 dictMatchIndexAndTag = dictHashTable[dictHashAndTag0 >> ZSTD_SHORT_CACHE_TAG_BITS]; + int dictTagsMatch = ZSTD_comparePackedTags(dictMatchIndexAndTag, dictHashAndTag0); + + U32 matchIndex = hashTable[hash0]; + U32 curr = (U32)(ip0 - base); + size_t step = stepSize; + const size_t kStepIncr = 1 << kSearchStrength; + const BYTE* nextStep = ip0 + kStepIncr; + + /* Inner search loop */ + while (1) { + const BYTE* match = base + matchIndex; + const U32 repIndex = curr + 1 - offset_1; + const BYTE* repMatch = (repIndex < prefixStartIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + const size_t hash1 = ZSTD_hashPtr(ip1, hlog, mls); + size_t const dictHashAndTag1 = ZSTD_hashPtr(ip1, dictHBits, mls); + hashTable[hash0] = curr; /* update hash table */ + + if ((ZSTD_index_overlap_check(prefixStartIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip0 + 1))) { + const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip0 + 1 + 4, repMatch + 4, iend, repMatchEnd, prefixStart) + 4; + ip0++; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + break; + } + + if (dictTagsMatch) { + /* Found a possible dict match */ + const U32 dictMatchIndex = dictMatchIndexAndTag >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatch = dictBase + dictMatchIndex; + if (dictMatchIndex > dictStartIndex && + MEM_read32(dictMatch) == MEM_read32(ip0)) { + /* To replicate extDict parse behavior, we only use dict matches when the normal matchIndex is invalid */ + if (matchIndex <= prefixStartIndex) { + U32 const offset = (U32) (curr - dictMatchIndex - dictIndexDelta); + mLength = ZSTD_count_2segments(ip0 + 4, dictMatch + 4, iend, dictEnd, prefixStart) + 4; + while (((ip0 > anchor) & (dictMatch > dictStart)) + && (ip0[-1] == dictMatch[-1])) { + ip0--; + dictMatch--; + mLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + break; + } + } + } + + if (ZSTD_match4Found_cmov(ip0, match, matchIndex, prefixStartIndex)) { + /* found a regular match of size >= 4 */ + U32 const offset = (U32) (ip0 - match); + mLength = ZSTD_count(ip0 + 4, match + 4, iend) + 4; + while (((ip0 > anchor) & (match > prefixStart)) + && (ip0[-1] == match[-1])) { + ip0--; + match--; + mLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + break; + } + + /* Prepare for next iteration */ + dictMatchIndexAndTag = dictHashTable[dictHashAndTag1 >> ZSTD_SHORT_CACHE_TAG_BITS]; + dictTagsMatch = ZSTD_comparePackedTags(dictMatchIndexAndTag, dictHashAndTag1); + matchIndex = hashTable[hash1]; + + if (ip1 >= nextStep) { + step++; + nextStep += kStepIncr; + } + ip0 = ip1; + ip1 = ip1 + step; + if (ip1 > ilimit) goto _cleanup; + + curr = (U32)(ip0 - base); + hash0 = hash1; + } /* end inner search loop */ + + /* match found */ + assert(mLength); + ip0 += mLength; + anchor = ip0; + + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+curr+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; /* here because curr+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + /* check immediate repcode */ + while (ip0 <= ilimit) { + U32 const current2 = (U32)(ip0-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? + dictBase - dictIndexDelta + repIndex2 : + base + repIndex2; + if ( (ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) + && (MEM_read32(repMatch2) == MEM_read32(ip0))) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip0+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = current2; + ip0 += repLength2; + anchor = ip0; + continue; + } + break; + } + } + + /* Prepare for next iteration */ + assert(ip0 == anchor); + ip1 = ip0 + stepSize; + } + +_cleanup: + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + + +ZSTD_GEN_FAST_FN(dictMatchState, 4, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 5, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 6, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 7, 0) + +size_t ZSTD_compressBlock_fast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + assert(ms->dictMatchState != NULL); + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_dictMatchState_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_dictMatchState_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_dictMatchState_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_dictMatchState_7_0(ms, seqStore, rep, src, srcSize); + } +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls, U32 const hasStep) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + /* support stepSize of 0 */ + size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const istart = (const BYTE*)src; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog); + const U32 dictStartIndex = lowLimit; + const BYTE* const dictStart = dictBase + dictStartIndex; + const U32 dictLimit = ms->window.dictLimit; + const U32 prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const dictEnd = dictBase + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + U32 offset_1=rep[0], offset_2=rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + const BYTE* ip0 = istart; + const BYTE* ip1; + const BYTE* ip2; + const BYTE* ip3; + U32 current0; + + + size_t hash0; /* hash for ip0 */ + size_t hash1; /* hash for ip1 */ + U32 idx; /* match idx for ip0 */ + const BYTE* idxBase; /* base pointer for idx */ + + U32 offcode; + const BYTE* match0; + size_t mLength; + const BYTE* matchEnd = 0; /* initialize to avoid warning, assert != 0 later */ + + size_t step; + const BYTE* nextStep; + const size_t kStepIncr = (1 << (kSearchStrength - 1)); + + (void)hasStep; /* not currently specialized on whether it's accelerated */ + + DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic (offset_1=%u)", offset_1); + + /* switch to "regular" variant if extDict is invalidated due to maxDistance */ + if (prefixStartIndex == dictStartIndex) + return ZSTD_compressBlock_fast(ms, seqStore, rep, src, srcSize); + + { U32 const curr = (U32)(ip0 - base); + U32 const maxRep = curr - dictStartIndex; + if (offset_2 >= maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 >= maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + + /* start each op */ +_start: /* Requires: ip0 */ + + step = stepSize; + nextStep = ip0 + kStepIncr; + + /* calculate positions, ip0 - anchor == 0, so we skip step calc */ + ip1 = ip0 + 1; + ip2 = ip0 + step; + ip3 = ip2 + 1; + + if (ip3 >= ilimit) { + goto _cleanup; + } + + hash0 = ZSTD_hashPtr(ip0, hlog, mls); + hash1 = ZSTD_hashPtr(ip1, hlog, mls); + + idx = hashTable[hash0]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + do { + { /* load repcode match for ip[2] */ + U32 const current2 = (U32)(ip2 - base); + U32 const repIndex = current2 - offset_1; + const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base; + U32 rval; + if ( ((U32)(prefixStartIndex - repIndex) >= 4) /* intentional underflow */ + & (offset_1 > 0) ) { + rval = MEM_read32(repBase + repIndex); + } else { + rval = MEM_read32(ip2) ^ 1; /* guaranteed to not match. */ + } + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + /* check repcode at ip[2] */ + if (MEM_read32(ip2) == rval) { + ip0 = ip2; + match0 = repBase + repIndex; + matchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + assert((match0 != prefixStart) & (match0 != dictStart)); + mLength = ip0[-1] == match0[-1]; + ip0 -= mLength; + match0 -= mLength; + offcode = REPCODE1_TO_OFFBASE; + mLength += 4; + goto _match; + } } + + { /* load match for ip[0] */ + U32 const mval = idx >= dictStartIndex ? + MEM_read32(idxBase + idx) : + MEM_read32(ip0) ^ 1; /* guaranteed not to match */ + + /* check match at ip[0] */ + if (MEM_read32(ip0) == mval) { + /* found a match! */ + goto _offset; + } } + + /* lookup ip[1] */ + idx = hashTable[hash1]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip3; + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + { /* load match for ip[0] */ + U32 const mval = idx >= dictStartIndex ? + MEM_read32(idxBase + idx) : + MEM_read32(ip0) ^ 1; /* guaranteed not to match */ + + /* check match at ip[0] */ + if (MEM_read32(ip0) == mval) { + /* found a match! */ + goto _offset; + } } + + /* lookup ip[1] */ + idx = hashTable[hash1]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip0 + step; + ip3 = ip1 + step; + + /* calculate step */ + if (ip2 >= nextStep) { + step++; + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + nextStep += kStepIncr; + } + } while (ip3 < ilimit); + +_cleanup: + /* Note that there are probably still a couple positions we could search. + * However, it seems to be a meaningful performance hit to try to search + * them. So let's not. */ + + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_offset: /* Requires: ip0, idx, idxBase */ + + /* Compute the offset code. */ + { U32 const offset = current0 - idx; + const BYTE* const lowMatchPtr = idx < prefixStartIndex ? dictStart : prefixStart; + matchEnd = idx < prefixStartIndex ? dictEnd : iend; + match0 = idxBase + idx; + offset_2 = offset_1; + offset_1 = offset; + offcode = OFFSET_TO_OFFBASE(offset); + mLength = 4; + + /* Count the backwards match length. */ + while (((ip0>anchor) & (match0>lowMatchPtr)) && (ip0[-1] == match0[-1])) { + ip0--; + match0--; + mLength++; + } } + +_match: /* Requires: ip0, match0, offcode, matchEnd */ + + /* Count the forward length. */ + assert(matchEnd != 0); + mLength += ZSTD_count_2segments(ip0 + mLength, match0 + mLength, iend, matchEnd, prefixStart); + + ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength); + + ip0 += mLength; + anchor = ip0; + + /* write next hash table entry */ + if (ip1 < ip0) { + hashTable[hash1] = (U32)(ip1 - base); + } + + /* Fill table and check for immediate repcode. */ + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+current0+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + while (ip0 <= ilimit) { + U32 const repIndex2 = (U32)(ip0-base) - offset_2; + const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; + if ( ((ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) & (offset_2 > 0)) + && (MEM_read32(repMatch2) == MEM_read32(ip0)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip0+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + { U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; } /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base); + ip0 += repLength2; + anchor = ip0; + continue; + } + break; + } } + + goto _start; +} + +ZSTD_GEN_FAST_FN(extDict, 4, 0) +ZSTD_GEN_FAST_FN(extDict, 5, 0) +ZSTD_GEN_FAST_FN(extDict, 6, 0) +ZSTD_GEN_FAST_FN(extDict, 7, 0) + +size_t ZSTD_compressBlock_fast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + assert(ms->dictMatchState == NULL); + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_extDict_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_extDict_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_extDict_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_extDict_7_0(ms, seqStore, rep, src, srcSize); + } +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_fast.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_fast.h new file mode 100644 index 000000000..216821ac3 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_fast.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_FAST_H +#define ZSTD_FAST_H + +#include "../common/mem.h" /* U32 */ +#include "zstd_compress_internal.h" + +void ZSTD_fillHashTable(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp); +size_t ZSTD_compressBlock_fast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_fast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_fast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#endif /* ZSTD_FAST_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_lazy.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_lazy.c new file mode 100644 index 000000000..272ebe0ec --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_lazy.c @@ -0,0 +1,2199 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "zstd_lazy.h" +#include "../common/bits.h" /* ZSTD_countTrailingZeros64 */ + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) + +#define kLazySkippingStep 8 + + +/*-************************************* +* Binary Tree search +***************************************/ + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_updateDUBT(ZSTD_MatchState_t* ms, + const BYTE* ip, const BYTE* iend, + U32 mls) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + + if (idx != target) + DEBUGLOG(7, "ZSTD_updateDUBT, from %u to %u (dictLimit:%u)", + idx, target, ms->window.dictLimit); + assert(ip + 8 <= iend); /* condition for ZSTD_hashPtr */ + (void)iend; + + assert(idx >= ms->window.dictLimit); /* condition for valid base+idx */ + for ( ; idx < target ; idx++) { + size_t const h = ZSTD_hashPtr(base + idx, hashLog, mls); /* assumption : ip + 8 <= iend */ + U32 const matchIndex = hashTable[h]; + + U32* const nextCandidatePtr = bt + 2*(idx&btMask); + U32* const sortMarkPtr = nextCandidatePtr + 1; + + DEBUGLOG(8, "ZSTD_updateDUBT: insert %u", idx); + hashTable[h] = idx; /* Update Hash Table */ + *nextCandidatePtr = matchIndex; /* update BT like a chain */ + *sortMarkPtr = ZSTD_DUBT_UNSORTED_MARK; + } + ms->nextToUpdate = target; +} + + +/** ZSTD_insertDUBT1() : + * sort one already inserted but unsorted position + * assumption : curr >= btlow == (curr - btmask) + * doesn't fail */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_insertDUBT1(const ZSTD_MatchState_t* ms, + U32 curr, const BYTE* inputEnd, + U32 nbCompares, U32 btLow, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const ip = (curr>=dictLimit) ? base + curr : dictBase + curr; + const BYTE* const iend = (curr>=dictLimit) ? inputEnd : dictBase + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* match; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = smallerPtr + 1; + U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */ + U32 dummy32; /* to be nullified at the end */ + U32 const windowValid = ms->window.lowLimit; + U32 const maxDistance = 1U << cParams->windowLog; + U32 const windowLow = (curr - windowValid > maxDistance) ? curr - maxDistance : windowValid; + + + DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)", + curr, dictLimit, windowLow); + assert(curr >= btLow); + assert(ip < iend); /* condition for ZSTD_count */ + + for (; nbCompares && (matchIndex > windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(matchIndex < curr); + /* note : all candidates are now supposed sorted, + * but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK + * when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */ + + if ( (dictMode != ZSTD_extDict) + || (matchIndex+matchLength >= dictLimit) /* both in current segment*/ + || (curr < dictLimit) /* both in extDict */) { + const BYTE* const mBase = ( (dictMode != ZSTD_extDict) + || (matchIndex+matchLength >= dictLimit)) ? + base : dictBase; + assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */ + || (curr < dictLimit) ); + match = mBase + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* preparation for next read of match[matchLength] */ + } + + DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ", + curr, matchIndex, (U32)matchLength); + + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */ + } + + if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */ + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is smaller : next => %u", + matchIndex, btLow, nextPtr[1]); + smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is larger => %u", + matchIndex, btLow, nextPtr[0]); + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_DUBT_findBetterDictMatch ( + const ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + size_t* offsetPtr, + size_t bestLength, + U32 nbCompares, + U32 const mls, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_MatchState_t * const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dmsCParams = &dms->cParams; + const U32 * const dictHashTable = dms->hashTable; + U32 const hashLog = dmsCParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 dictMatchIndex = dictHashTable[h]; + + const BYTE* const base = ms->window.base; + const BYTE* const prefixStart = base + ms->window.dictLimit; + U32 const curr = (U32)(ip-base); + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictEnd = dms->window.nextSrc; + U32 const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base); + U32 const dictLowLimit = dms->window.lowLimit; + U32 const dictIndexDelta = ms->window.lowLimit - dictHighLimit; + + U32* const dictBt = dms->chainTable; + U32 const btLog = dmsCParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 const btLow = (btMask >= dictHighLimit - dictLowLimit) ? dictLowLimit : dictHighLimit - btMask; + + size_t commonLengthSmaller=0, commonLengthLarger=0; + + (void)dictMode; + assert(dictMode == ZSTD_dictMatchState); + + for (; nbCompares && (dictMatchIndex > dictLowLimit); --nbCompares) { + U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match = dictBase + dictMatchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (dictMatchIndex+matchLength >= dictHighLimit) + match = base + dictMatchIndex + dictIndexDelta; /* to prepare for next usage of match[matchLength] */ + + if (matchLength > bestLength) { + U32 matchIndex = dictMatchIndex + dictIndexDelta; + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) { + DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)", + curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, OFFSET_TO_OFFBASE(curr - matchIndex), dictMatchIndex, matchIndex); + bestLength = matchLength, *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + } + if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */ + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + } + + if (match[matchLength] < ip[matchLength]) { + if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */ + commonLengthLarger = matchLength; + dictMatchIndex = nextPtr[0]; + } + } + + if (bestLength >= MINMATCH) { + U32 const mIndex = curr - (U32)OFFBASE_TO_OFFSET(*offsetPtr); (void)mIndex; + DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)", + curr, (U32)bestLength, (U32)*offsetPtr, mIndex); + } + return bestLength; + +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_DUBT_findBestMatch(ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + size_t* offBasePtr, + U32 const mls, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 matchIndex = hashTable[h]; + + const BYTE* const base = ms->window.base; + U32 const curr = (U32)(ip-base); + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog); + + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 const btLow = (btMask >= curr) ? 0 : curr - btMask; + U32 const unsortLimit = MAX(btLow, windowLow); + + U32* nextCandidate = bt + 2*(matchIndex&btMask); + U32* unsortedMark = bt + 2*(matchIndex&btMask) + 1; + U32 nbCompares = 1U << cParams->searchLog; + U32 nbCandidates = nbCompares; + U32 previousCandidate = 0; + + DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", curr); + assert(ip <= iend-8); /* required for h calculation */ + assert(dictMode != ZSTD_dedicatedDictSearch); + + /* reach end of unsorted candidates list */ + while ( (matchIndex > unsortLimit) + && (*unsortedMark == ZSTD_DUBT_UNSORTED_MARK) + && (nbCandidates > 1) ) { + DEBUGLOG(8, "ZSTD_DUBT_findBestMatch: candidate %u is unsorted", + matchIndex); + *unsortedMark = previousCandidate; /* the unsortedMark becomes a reversed chain, to move up back to original position */ + previousCandidate = matchIndex; + matchIndex = *nextCandidate; + nextCandidate = bt + 2*(matchIndex&btMask); + unsortedMark = bt + 2*(matchIndex&btMask) + 1; + nbCandidates --; + } + + /* nullify last candidate if it's still unsorted + * simplification, detrimental to compression ratio, beneficial for speed */ + if ( (matchIndex > unsortLimit) + && (*unsortedMark==ZSTD_DUBT_UNSORTED_MARK) ) { + DEBUGLOG(7, "ZSTD_DUBT_findBestMatch: nullify last unsorted candidate %u", + matchIndex); + *nextCandidate = *unsortedMark = 0; + } + + /* batch sort stacked candidates */ + matchIndex = previousCandidate; + while (matchIndex) { /* will end on matchIndex == 0 */ + U32* const nextCandidateIdxPtr = bt + 2*(matchIndex&btMask) + 1; + U32 const nextCandidateIdx = *nextCandidateIdxPtr; + ZSTD_insertDUBT1(ms, matchIndex, iend, + nbCandidates, unsortLimit, dictMode); + matchIndex = nextCandidateIdx; + nbCandidates++; + } + + /* find longest match */ + { size_t commonLengthSmaller = 0, commonLengthLarger = 0; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = bt + 2*(curr&btMask) + 1; + U32 matchEndIdx = curr + 8 + 1; + U32 dummy32; /* to be nullified at the end */ + size_t bestLength = 0; + + matchIndex = hashTable[h]; + hashTable[h] = curr; /* Update Hash Table */ + + for (; nbCompares && (matchIndex > windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match; + + if ((dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit)) { + match = base + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr - matchIndex + 1) - ZSTD_highbit32((U32)*offBasePtr)) ) + bestLength = matchLength, *offBasePtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + if (dictMode == ZSTD_dictMatchState) { + nbCompares = 0; /* in addition to avoiding checking any + * further in this loop, make sure we + * skip checking in the dictionary. */ + } + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + } + + if (match[matchLength] < ip[matchLength]) { + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + + assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dictMatchState && nbCompares) { + bestLength = ZSTD_DUBT_findBetterDictMatch( + ms, ip, iend, + offBasePtr, bestLength, nbCompares, + mls, dictMode); + } + + assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */ + ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ + if (bestLength >= MINMATCH) { + U32 const mIndex = curr - (U32)OFFBASE_TO_OFFSET(*offBasePtr); (void)mIndex; + DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)", + curr, (U32)bestLength, (U32)*offBasePtr, mIndex); + } + return bestLength; + } +} + + +/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_BtFindBestMatch( ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offBasePtr, + const U32 mls /* template */, + const ZSTD_dictMode_e dictMode) +{ + DEBUGLOG(7, "ZSTD_BtFindBestMatch"); + if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */ + ZSTD_updateDUBT(ms, ip, iLimit, mls); + return ZSTD_DUBT_findBestMatch(ms, ip, iLimit, offBasePtr, mls, dictMode); +} + +/*********************************** +* Dedicated dict search +***********************************/ + +void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_MatchState_t* ms, const BYTE* const ip) +{ + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32* const hashTable = ms->hashTable; + U32* const chainTable = ms->chainTable; + U32 const chainSize = 1 << ms->cParams.chainLog; + U32 idx = ms->nextToUpdate; + U32 const minChain = chainSize < target - idx ? target - chainSize : idx; + U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 const cacheSize = bucketSize - 1; + U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize; + U32 const chainLimit = chainAttempts > 255 ? 255 : chainAttempts; + + /* We know the hashtable is oversized by a factor of `bucketSize`. + * We are going to temporarily pretend `bucketSize == 1`, keeping only a + * single entry. We will use the rest of the space to construct a temporary + * chaintable. + */ + U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; + U32* const tmpHashTable = hashTable; + U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog); + U32 const tmpChainSize = (U32)((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog; + U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx; + U32 hashIdx; + + assert(ms->cParams.chainLog <= 24); + assert(ms->cParams.hashLog > ms->cParams.chainLog); + assert(idx != 0); + assert(tmpMinChain <= minChain); + + /* fill conventional hash table and conventional chain table */ + for ( ; idx < target; idx++) { + U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch); + if (idx >= tmpMinChain) { + tmpChainTable[idx - tmpMinChain] = hashTable[h]; + } + tmpHashTable[h] = idx; + } + + /* sort chains into ddss chain table */ + { + U32 chainPos = 0; + for (hashIdx = 0; hashIdx < (1U << hashLog); hashIdx++) { + U32 count; + U32 countBeyondMinChain = 0; + U32 i = tmpHashTable[hashIdx]; + for (count = 0; i >= tmpMinChain && count < cacheSize; count++) { + /* skip through the chain to the first position that won't be + * in the hash cache bucket */ + if (i < minChain) { + countBeyondMinChain++; + } + i = tmpChainTable[i - tmpMinChain]; + } + if (count == cacheSize) { + for (count = 0; count < chainLimit;) { + if (i < minChain) { + if (!i || ++countBeyondMinChain > cacheSize) { + /* only allow pulling `cacheSize` number of entries + * into the cache or chainTable beyond `minChain`, + * to replace the entries pulled out of the + * chainTable into the cache. This lets us reach + * back further without increasing the total number + * of entries in the chainTable, guaranteeing the + * DDSS chain table will fit into the space + * allocated for the regular one. */ + break; + } + } + chainTable[chainPos++] = i; + count++; + if (i < tmpMinChain) { + break; + } + i = tmpChainTable[i - tmpMinChain]; + } + } else { + count = 0; + } + if (count) { + tmpHashTable[hashIdx] = ((chainPos - count) << 8) + count; + } else { + tmpHashTable[hashIdx] = 0; + } + } + assert(chainPos <= chainSize); /* I believe this is guaranteed... */ + } + + /* move chain pointers into the last entry of each hash bucket */ + for (hashIdx = (1 << hashLog); hashIdx; ) { + U32 const bucketIdx = --hashIdx << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 const chainPackedPointer = tmpHashTable[hashIdx]; + U32 i; + for (i = 0; i < cacheSize; i++) { + hashTable[bucketIdx + i] = 0; + } + hashTable[bucketIdx + bucketSize - 1] = chainPackedPointer; + } + + /* fill the buckets of the hash table */ + for (idx = ms->nextToUpdate; idx < target; idx++) { + U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch) + << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 i; + /* Shift hash cache down 1. */ + for (i = cacheSize - 1; i; i--) + hashTable[h + i] = hashTable[h + i - 1]; + hashTable[h] = idx; + } + + ms->nextToUpdate = target; +} + +/* Returns the longest match length found in the dedicated dict search structure. + * If none are longer than the argument ml, then ml will be returned. + */ +FORCE_INLINE_TEMPLATE +size_t ZSTD_dedicatedDictSearch_lazy_search(size_t* offsetPtr, size_t ml, U32 nbAttempts, + const ZSTD_MatchState_t* const dms, + const BYTE* const ip, const BYTE* const iLimit, + const BYTE* const prefixStart, const U32 curr, + const U32 dictLimit, const size_t ddsIdx) { + const U32 ddsLowestIndex = dms->window.dictLimit; + const BYTE* const ddsBase = dms->window.base; + const BYTE* const ddsEnd = dms->window.nextSrc; + const U32 ddsSize = (U32)(ddsEnd - ddsBase); + const U32 ddsIndexDelta = dictLimit - ddsSize; + const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG); + const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1; + U32 ddsAttempt; + U32 matchIndex; + + for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) { + PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]); + } + + { + U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1]; + U32 const chainIndex = chainPackedPointer >> 8; + + PREFETCH_L1(&dms->chainTable[chainIndex]); + } + + for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) { + size_t currentMl=0; + const BYTE* match; + matchIndex = dms->hashTable[ddsIdx + ddsAttempt]; + match = ddsBase + matchIndex; + + if (!matchIndex) { + return ml; + } + + /* guaranteed by table construction */ + (void)ddsLowestIndex; + assert(matchIndex >= ddsLowestIndex); + assert(match+4 <= ddsEnd); + if (MEM_read32(match) == MEM_read32(ip)) { + /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + ddsIndexDelta)); + if (ip+currentMl == iLimit) { + /* best possible, avoids read overflow on next attempt */ + return ml; + } + } + } + + { + U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1]; + U32 chainIndex = chainPackedPointer >> 8; + U32 const chainLength = chainPackedPointer & 0xFF; + U32 const chainAttempts = nbAttempts - ddsAttempt; + U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts; + U32 chainAttempt; + + for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) { + PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]); + } + + for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) { + size_t currentMl=0; + const BYTE* match; + matchIndex = dms->chainTable[chainIndex]; + match = ddsBase + matchIndex; + + /* guaranteed by table construction */ + assert(matchIndex >= ddsLowestIndex); + assert(match+4 <= ddsEnd); + if (MEM_read32(match) == MEM_read32(ip)) { + /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + ddsIndexDelta)); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + } + } + return ml; +} + + +/* ********************************* +* Hash Chain +***********************************/ +#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & (mask)] + +/* Update chains up to ip (excluded) + Assumption : always within prefix (i.e. not within extDict) */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertAndFindFirstIndex_internal( + ZSTD_MatchState_t* ms, + const ZSTD_compressionParameters* const cParams, + const BYTE* ip, U32 const mls, U32 const lazySkipping) +{ + U32* const hashTable = ms->hashTable; + const U32 hashLog = cParams->hashLog; + U32* const chainTable = ms->chainTable; + const U32 chainMask = (1 << cParams->chainLog) - 1; + const BYTE* const base = ms->window.base; + const U32 target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + + while(idx < target) { /* catch up */ + size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls); + NEXT_IN_CHAIN(idx, chainMask) = hashTable[h]; + hashTable[h] = idx; + idx++; + /* Stop inserting every position when in the lazy skipping mode. */ + if (lazySkipping) + break; + } + + ms->nextToUpdate = target; + return hashTable[ZSTD_hashPtr(ip, hashLog, mls)]; +} + +U32 ZSTD_insertAndFindFirstIndex(ZSTD_MatchState_t* ms, const BYTE* ip) { + const ZSTD_compressionParameters* const cParams = &ms->cParams; + return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch, /* lazySkipping*/ 0); +} + +/* inlining is important to hardwire a hot branch (template emulation) */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_HcFindBestMatch( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 mls, const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const chainTable = ms->chainTable; + const U32 chainSize = (1 << cParams->chainLog); + const U32 chainMask = chainSize-1; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const U32 curr = (U32)(ip-base); + const U32 maxDistance = 1U << cParams->windowLog; + const U32 lowestValid = ms->window.lowLimit; + const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + const U32 isDictionary = (ms->loadedDictEnd != 0); + const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance; + const U32 minChain = curr > chainSize ? curr - chainSize : 0; + U32 nbAttempts = 1U << cParams->searchLog; + size_t ml=4-1; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const U32 ddsHashLog = dictMode == ZSTD_dedicatedDictSearch + ? dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG : 0; + const size_t ddsIdx = dictMode == ZSTD_dedicatedDictSearch + ? ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG : 0; + + U32 matchIndex; + + if (dictMode == ZSTD_dedicatedDictSearch) { + const U32* entry = &dms->hashTable[ddsIdx]; + PREFETCH_L1(entry); + } + + /* HC4 match finder */ + matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls, ms->lazySkipping); + + for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) { + size_t currentMl=0; + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + const BYTE* const match = base + matchIndex; + assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */ + /* read 4B starting from (match + ml + 1 - sizeof(U32)) */ + if (MEM_read32(match + ml - 3) == MEM_read32(ip + ml - 3)) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex; + assert(match+4 <= dictEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + + if (matchIndex <= minChain) break; + matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); + } + + assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dedicatedDictSearch) { + ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts, dms, + ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); + } else if (dictMode == ZSTD_dictMatchState) { + const U32* const dmsChainTable = dms->chainTable; + const U32 dmsChainSize = (1 << dms->cParams.chainLog); + const U32 dmsChainMask = dmsChainSize - 1; + const U32 dmsLowestIndex = dms->window.dictLimit; + const BYTE* const dmsBase = dms->window.base; + const BYTE* const dmsEnd = dms->window.nextSrc; + const U32 dmsSize = (U32)(dmsEnd - dmsBase); + const U32 dmsIndexDelta = dictLimit - dmsSize; + const U32 dmsMinChain = dmsSize > dmsChainSize ? dmsSize - dmsChainSize : 0; + + matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)]; + + for ( ; (matchIndex>=dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) { + size_t currentMl=0; + const BYTE* const match = dmsBase + matchIndex; + assert(match+4 <= dmsEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4; + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + assert(curr > matchIndex + dmsIndexDelta); + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + dmsIndexDelta)); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + + if (matchIndex <= dmsMinChain) break; + + matchIndex = dmsChainTable[matchIndex & dmsChainMask]; + } + } + + return ml; +} + +/* ********************************* +* (SIMD) Row-based matchfinder +***********************************/ +/* Constants for row-based hash */ +#define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1) +#define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */ + +#define ZSTD_ROW_HASH_CACHE_MASK (ZSTD_ROW_HASH_CACHE_SIZE - 1) + +typedef U64 ZSTD_VecMask; /* Clarifies when we are interacting with a U64 representing a mask of matches */ + +/* ZSTD_VecMask_next(): + * Starting from the LSB, returns the idx of the next non-zero bit. + * Basically counting the nb of trailing zeroes. + */ +MEM_STATIC U32 ZSTD_VecMask_next(ZSTD_VecMask val) { + return ZSTD_countTrailingZeros64(val); +} + +/* ZSTD_row_nextIndex(): + * Returns the next index to insert at within a tagTable row, and updates the "head" + * value to reflect the update. Essentially cycles backwards from [1, {entries per row}) + */ +FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextIndex(BYTE* const tagRow, U32 const rowMask) { + U32 next = (*tagRow-1) & rowMask; + next += (next == 0) ? rowMask : 0; /* skip first position */ + *tagRow = (BYTE)next; + return next; +} + +/* ZSTD_isAligned(): + * Checks that a pointer is aligned to "align" bytes which must be a power of 2. + */ +MEM_STATIC int ZSTD_isAligned(void const* ptr, size_t align) { + assert((align & (align - 1)) == 0); + return (((size_t)ptr) & (align - 1)) == 0; +} + +/* ZSTD_row_prefetch(): + * Performs prefetching for the hashTable and tagTable at a given row. + */ +FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, BYTE const* tagTable, U32 const relRow, U32 const rowLog) { + PREFETCH_L1(hashTable + relRow); + if (rowLog >= 5) { + PREFETCH_L1(hashTable + relRow + 16); + /* Note: prefetching more of the hash table does not appear to be beneficial for 128-entry rows */ + } + PREFETCH_L1(tagTable + relRow); + if (rowLog == 6) { + PREFETCH_L1(tagTable + relRow + 32); + } + assert(rowLog == 4 || rowLog == 5 || rowLog == 6); + assert(ZSTD_isAligned(hashTable + relRow, 64)); /* prefetched hash row always 64-byte aligned */ + assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on correct multiple of bytes (32,64,128) */ +} + +/* ZSTD_row_fillHashCache(): + * Fill up the hash cache starting at idx, prefetching up to ZSTD_ROW_HASH_CACHE_SIZE entries, + * but not beyond iLimit. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_fillHashCache(ZSTD_MatchState_t* ms, const BYTE* base, + U32 const rowLog, U32 const mls, + U32 idx, const BYTE* const iLimit) +{ + U32 const* const hashTable = ms->hashTable; + BYTE const* const tagTable = ms->tagTable; + U32 const hashLog = ms->rowHashLog; + U32 const maxElemsToPrefetch = (base + idx) > iLimit ? 0 : (U32)(iLimit - (base + idx) + 1); + U32 const lim = idx + MIN(ZSTD_ROW_HASH_CACHE_SIZE, maxElemsToPrefetch); + + for (; idx < lim; ++idx) { + U32 const hash = (U32)ZSTD_hashPtrSalted(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt); + U32 const row = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + ZSTD_row_prefetch(hashTable, tagTable, row, rowLog); + ms->hashCache[idx & ZSTD_ROW_HASH_CACHE_MASK] = hash; + } + + DEBUGLOG(6, "ZSTD_row_fillHashCache(): [%u %u %u %u %u %u %u %u]", ms->hashCache[0], ms->hashCache[1], + ms->hashCache[2], ms->hashCache[3], ms->hashCache[4], + ms->hashCache[5], ms->hashCache[6], ms->hashCache[7]); +} + +/* ZSTD_row_nextCachedHash(): + * Returns the hash of base + idx, and replaces the hash in the hash cache with the byte at + * base + idx + ZSTD_ROW_HASH_CACHE_SIZE. Also prefetches the appropriate rows from hashTable and tagTable. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTable, + BYTE const* tagTable, BYTE const* base, + U32 idx, U32 const hashLog, + U32 const rowLog, U32 const mls, + U64 const hashSalt) +{ + U32 const newHash = (U32)ZSTD_hashPtrSalted(base+idx+ZSTD_ROW_HASH_CACHE_SIZE, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt); + U32 const row = (newHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + ZSTD_row_prefetch(hashTable, tagTable, row, rowLog); + { U32 const hash = cache[idx & ZSTD_ROW_HASH_CACHE_MASK]; + cache[idx & ZSTD_ROW_HASH_CACHE_MASK] = newHash; + return hash; + } +} + +/* ZSTD_row_update_internalImpl(): + * Updates the hash table with positions starting from updateStartIdx until updateEndIdx. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_update_internalImpl(ZSTD_MatchState_t* ms, + U32 updateStartIdx, U32 const updateEndIdx, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) +{ + U32* const hashTable = ms->hashTable; + BYTE* const tagTable = ms->tagTable; + U32 const hashLog = ms->rowHashLog; + const BYTE* const base = ms->window.base; + + DEBUGLOG(6, "ZSTD_row_update_internalImpl(): updateStartIdx=%u, updateEndIdx=%u", updateStartIdx, updateEndIdx); + for (; updateStartIdx < updateEndIdx; ++updateStartIdx) { + U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, updateStartIdx, hashLog, rowLog, mls, ms->hashSalt) + : (U32)ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt); + U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + U32* const row = hashTable + relRow; + BYTE* tagRow = tagTable + relRow; + U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); + + assert(hash == ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt)); + tagRow[pos] = hash & ZSTD_ROW_HASH_TAG_MASK; + row[pos] = updateStartIdx; + } +} + +/* ZSTD_row_update_internal(): + * Inserts the byte at ip into the appropriate position in the hash table, and updates ms->nextToUpdate. + * Skips sections of long matches as is necessary. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_update_internal(ZSTD_MatchState_t* ms, const BYTE* ip, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) +{ + U32 idx = ms->nextToUpdate; + const BYTE* const base = ms->window.base; + const U32 target = (U32)(ip - base); + const U32 kSkipThreshold = 384; + const U32 kMaxMatchStartPositionsToUpdate = 96; + const U32 kMaxMatchEndPositionsToUpdate = 32; + + if (useCache) { + /* Only skip positions when using hash cache, i.e. + * if we are loading a dict, don't skip anything. + * If we decide to skip, then we only update a set number + * of positions at the beginning and end of the match. + */ + if (UNLIKELY(target - idx > kSkipThreshold)) { + U32 const bound = idx + kMaxMatchStartPositionsToUpdate; + ZSTD_row_update_internalImpl(ms, idx, bound, mls, rowLog, rowMask, useCache); + idx = target - kMaxMatchEndPositionsToUpdate; + ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1); + } + } + assert(target >= idx); + ZSTD_row_update_internalImpl(ms, idx, target, mls, rowLog, rowMask, useCache); + ms->nextToUpdate = target; +} + +/* ZSTD_row_update(): + * External wrapper for ZSTD_row_update_internal(). Used for filling the hashtable during dictionary + * processing. + */ +void ZSTD_row_update(ZSTD_MatchState_t* const ms, const BYTE* ip) { + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + const U32 rowMask = (1u << rowLog) - 1; + const U32 mls = MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */); + + DEBUGLOG(5, "ZSTD_row_update(), rowLog=%u", rowLog); + ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 0 /* don't use cache */); +} + +/* Returns the mask width of bits group of which will be set to 1. Given not all + * architectures have easy movemask instruction, this helps to iterate over + * groups of bits easier and faster. + */ +FORCE_INLINE_TEMPLATE U32 +ZSTD_row_matchMaskGroupWidth(const U32 rowEntries) +{ + assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64); + assert(rowEntries <= ZSTD_ROW_HASH_MAX_ENTRIES); + (void)rowEntries; +#if defined(ZSTD_ARCH_ARM_NEON) + /* NEON path only works for little endian */ + if (!MEM_isLittleEndian()) { + return 1; + } + if (rowEntries == 16) { + return 4; + } + if (rowEntries == 32) { + return 2; + } + if (rowEntries == 64) { + return 1; + } +#endif + return 1; +} + +#if defined(ZSTD_ARCH_X86_SSE2) +FORCE_INLINE_TEMPLATE ZSTD_VecMask +ZSTD_row_getSSEMask(int nbChunks, const BYTE* const src, const BYTE tag, const U32 head) +{ + const __m128i comparisonMask = _mm_set1_epi8((char)tag); + int matches[4] = {0}; + int i; + assert(nbChunks == 1 || nbChunks == 2 || nbChunks == 4); + for (i=0; i> chunkSize; + do { + size_t chunk = MEM_readST(&src[i]); + chunk ^= splatChar; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunkSize; + matches |= (chunk * extractMagic) >> shiftAmount; + i -= chunkSize; + } while (i >= 0); + } else { /* big endian: reverse bits during extraction */ + const size_t msb = xFF ^ (xFF >> 1); + const size_t extractMagic = (msb / 0x1FF) | msb; + do { + size_t chunk = MEM_readST(&src[i]); + chunk ^= splatChar; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunkSize; + matches |= ((chunk >> 7) * extractMagic) >> shiftAmount; + i -= chunkSize; + } while (i >= 0); + } + matches = ~matches; + if (rowEntries == 16) { + return ZSTD_rotateRight_U16((U16)matches, headGrouped); + } else if (rowEntries == 32) { + return ZSTD_rotateRight_U32((U32)matches, headGrouped); + } else { + return ZSTD_rotateRight_U64((U64)matches, headGrouped); + } + } +#endif +} + +/* The high-level approach of the SIMD row based match finder is as follows: + * - Figure out where to insert the new entry: + * - Generate a hash for current input position and split it into a one byte of tag and `rowHashLog` bits of index. + * - The hash is salted by a value that changes on every context reset, so when the same table is used + * we will avoid collisions that would otherwise slow us down by introducing phantom matches. + * - The hashTable is effectively split into groups or "rows" of 15 or 31 entries of U32, and the index determines + * which row to insert into. + * - Determine the correct position within the row to insert the entry into. Each row of 15 or 31 can + * be considered as a circular buffer with a "head" index that resides in the tagTable (overall 16 or 32 bytes + * per row). + * - Use SIMD to efficiently compare the tags in the tagTable to the 1-byte tag calculated for the position and + * generate a bitfield that we can cycle through to check the collisions in the hash table. + * - Pick the longest match. + * - Insert the tag into the equivalent row and position in the tagTable. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_RowFindBestMatch( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 mls, const ZSTD_dictMode_e dictMode, + const U32 rowLog) +{ + U32* const hashTable = ms->hashTable; + BYTE* const tagTable = ms->tagTable; + U32* const hashCache = ms->hashCache; + const U32 hashLog = ms->rowHashLog; + const ZSTD_compressionParameters* const cParams = &ms->cParams; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const U32 curr = (U32)(ip-base); + const U32 maxDistance = 1U << cParams->windowLog; + const U32 lowestValid = ms->window.lowLimit; + const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + const U32 isDictionary = (ms->loadedDictEnd != 0); + const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance; + const U32 rowEntries = (1U << rowLog); + const U32 rowMask = rowEntries - 1; + const U32 cappedSearchLog = MIN(cParams->searchLog, rowLog); /* nb of searches is capped at nb entries per row */ + const U32 groupWidth = ZSTD_row_matchMaskGroupWidth(rowEntries); + const U64 hashSalt = ms->hashSalt; + U32 nbAttempts = 1U << cappedSearchLog; + size_t ml=4-1; + U32 hash; + + /* DMS/DDS variables that may be referenced laster */ + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + + /* Initialize the following variables to satisfy static analyzer */ + size_t ddsIdx = 0; + U32 ddsExtraAttempts = 0; /* cctx hash tables are limited in searches, but allow extra searches into DDS */ + U32 dmsTag = 0; + U32* dmsRow = NULL; + BYTE* dmsTagRow = NULL; + + if (dictMode == ZSTD_dedicatedDictSearch) { + const U32 ddsHashLog = dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; + { /* Prefetch DDS hashtable entry */ + ddsIdx = ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG; + PREFETCH_L1(&dms->hashTable[ddsIdx]); + } + ddsExtraAttempts = cParams->searchLog > rowLog ? 1U << (cParams->searchLog - rowLog) : 0; + } + + if (dictMode == ZSTD_dictMatchState) { + /* Prefetch DMS rows */ + U32* const dmsHashTable = dms->hashTable; + BYTE* const dmsTagTable = dms->tagTable; + U32 const dmsHash = (U32)ZSTD_hashPtr(ip, dms->rowHashLog + ZSTD_ROW_HASH_TAG_BITS, mls); + U32 const dmsRelRow = (dmsHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + dmsTag = dmsHash & ZSTD_ROW_HASH_TAG_MASK; + dmsTagRow = (BYTE*)(dmsTagTable + dmsRelRow); + dmsRow = dmsHashTable + dmsRelRow; + ZSTD_row_prefetch(dmsHashTable, dmsTagTable, dmsRelRow, rowLog); + } + + /* Update the hashTable and tagTable up to (but not including) ip */ + if (!ms->lazySkipping) { + ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 1 /* useCache */); + hash = ZSTD_row_nextCachedHash(hashCache, hashTable, tagTable, base, curr, hashLog, rowLog, mls, hashSalt); + } else { + /* Stop inserting every position when in the lazy skipping mode. + * The hash cache is also not kept up to date in this mode. + */ + hash = (U32)ZSTD_hashPtrSalted(ip, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt); + ms->nextToUpdate = curr; + } + ms->hashSaltEntropy += hash; /* collect salt entropy */ + + { /* Get the hash for ip, compute the appropriate row */ + U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + U32 const tag = hash & ZSTD_ROW_HASH_TAG_MASK; + U32* const row = hashTable + relRow; + BYTE* tagRow = (BYTE*)(tagTable + relRow); + U32 const headGrouped = (*tagRow & rowMask) * groupWidth; + U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES]; + size_t numMatches = 0; + size_t currMatch = 0; + ZSTD_VecMask matches = ZSTD_row_getMatchMask(tagRow, (BYTE)tag, headGrouped, rowEntries); + + /* Cycle through the matches and prefetch */ + for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) { + U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask; + U32 const matchIndex = row[matchPos]; + if(matchPos == 0) continue; + assert(numMatches < rowEntries); + if (matchIndex < lowLimit) + break; + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + PREFETCH_L1(base + matchIndex); + } else { + PREFETCH_L1(dictBase + matchIndex); + } + matchBuffer[numMatches++] = matchIndex; + --nbAttempts; + } + + /* Speed opt: insert current byte into hashtable too. This allows us to avoid one iteration of the loop + in ZSTD_row_update_internal() at the next search. */ + { + U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); + tagRow[pos] = (BYTE)tag; + row[pos] = ms->nextToUpdate++; + } + + /* Return the longest match */ + for (; currMatch < numMatches; ++currMatch) { + U32 const matchIndex = matchBuffer[currMatch]; + size_t currentMl=0; + assert(matchIndex < curr); + assert(matchIndex >= lowLimit); + + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + const BYTE* const match = base + matchIndex; + assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */ + /* read 4B starting from (match + ml + 1 - sizeof(U32)) */ + if (MEM_read32(match + ml - 3) == MEM_read32(ip + ml - 3)) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex; + assert(match+4 <= dictEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4; + } + + /* Save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + } + } + + assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dedicatedDictSearch) { + ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts + ddsExtraAttempts, dms, + ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); + } else if (dictMode == ZSTD_dictMatchState) { + /* TODO: Measure and potentially add prefetching to DMS */ + const U32 dmsLowestIndex = dms->window.dictLimit; + const BYTE* const dmsBase = dms->window.base; + const BYTE* const dmsEnd = dms->window.nextSrc; + const U32 dmsSize = (U32)(dmsEnd - dmsBase); + const U32 dmsIndexDelta = dictLimit - dmsSize; + + { U32 const headGrouped = (*dmsTagRow & rowMask) * groupWidth; + U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES]; + size_t numMatches = 0; + size_t currMatch = 0; + ZSTD_VecMask matches = ZSTD_row_getMatchMask(dmsTagRow, (BYTE)dmsTag, headGrouped, rowEntries); + + for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) { + U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask; + U32 const matchIndex = dmsRow[matchPos]; + if(matchPos == 0) continue; + if (matchIndex < dmsLowestIndex) + break; + PREFETCH_L1(dmsBase + matchIndex); + matchBuffer[numMatches++] = matchIndex; + --nbAttempts; + } + + /* Return the longest match */ + for (; currMatch < numMatches; ++currMatch) { + U32 const matchIndex = matchBuffer[currMatch]; + size_t currentMl=0; + assert(matchIndex >= dmsLowestIndex); + assert(matchIndex < curr); + + { const BYTE* const match = dmsBase + matchIndex; + assert(match+4 <= dmsEnd); + if (MEM_read32(match) == MEM_read32(ip)) + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4; + } + + if (currentMl > ml) { + ml = currentMl; + assert(curr > matchIndex + dmsIndexDelta); + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + dmsIndexDelta)); + if (ip+currentMl == iLimit) break; + } + } + } + } + return ml; +} + + +/** + * Generate search functions templated on (dictMode, mls, rowLog). + * These functions are outlined for code size & compilation time. + * ZSTD_searchMax() dispatches to the correct implementation function. + * + * TODO: The start of the search function involves loading and calculating a + * bunch of constants from the ZSTD_MatchState_t. These computations could be + * done in an initialization function, and saved somewhere in the match state. + * Then we could pass a pointer to the saved state instead of the match state, + * and avoid duplicate computations. + * + * TODO: Move the match re-winding into searchMax. This improves compression + * ratio, and unlocks further simplifications with the next TODO. + * + * TODO: Try moving the repcode search into searchMax. After the re-winding + * and repcode search are in searchMax, there is no more logic in the match + * finder loop that requires knowledge about the dictMode. So we should be + * able to avoid force inlining it, and we can join the extDict loop with + * the single segment loop. It should go in searchMax instead of its own + * function to avoid having multiple virtual function calls per search. + */ + +#define ZSTD_BT_SEARCH_FN(dictMode, mls) ZSTD_BtFindBestMatch_##dictMode##_##mls +#define ZSTD_HC_SEARCH_FN(dictMode, mls) ZSTD_HcFindBestMatch_##dictMode##_##mls +#define ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog + +#define ZSTD_SEARCH_FN_ATTRS FORCE_NOINLINE + +#define GEN_ZSTD_BT_SEARCH_FN(dictMode, mls) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_BT_SEARCH_FN(dictMode, mls)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offBasePtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + return ZSTD_BtFindBestMatch(ms, ip, iLimit, offBasePtr, mls, ZSTD_##dictMode); \ + } \ + +#define GEN_ZSTD_HC_SEARCH_FN(dictMode, mls) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_HC_SEARCH_FN(dictMode, mls)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + return ZSTD_HcFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \ + } \ + +#define GEN_ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + assert(MAX(4, MIN(6, ms->cParams.searchLog)) == rowLog); \ + return ZSTD_RowFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode, rowLog); \ + } \ + +#define ZSTD_FOR_EACH_ROWLOG(X, dictMode, mls) \ + X(dictMode, mls, 4) \ + X(dictMode, mls, 5) \ + X(dictMode, mls, 6) + +#define ZSTD_FOR_EACH_MLS_ROWLOG(X, dictMode) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 4) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 5) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 6) + +#define ZSTD_FOR_EACH_MLS(X, dictMode) \ + X(dictMode, 4) \ + X(dictMode, 5) \ + X(dictMode, 6) + +#define ZSTD_FOR_EACH_DICT_MODE(X, ...) \ + X(__VA_ARGS__, noDict) \ + X(__VA_ARGS__, extDict) \ + X(__VA_ARGS__, dictMatchState) \ + X(__VA_ARGS__, dedicatedDictSearch) + +/* Generate row search fns for each combination of (dictMode, mls, rowLog) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS_ROWLOG, GEN_ZSTD_ROW_SEARCH_FN) +/* Generate binary Tree search fns for each combination of (dictMode, mls) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_BT_SEARCH_FN) +/* Generate hash chain search fns for each combination of (dictMode, mls) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_HC_SEARCH_FN) + +typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e; + +#define GEN_ZSTD_CALL_BT_SEARCH_FN(dictMode, mls) \ + case mls: \ + return ZSTD_BT_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr); +#define GEN_ZSTD_CALL_HC_SEARCH_FN(dictMode, mls) \ + case mls: \ + return ZSTD_HC_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr); +#define GEN_ZSTD_CALL_ROW_SEARCH_FN(dictMode, mls, rowLog) \ + case rowLog: \ + return ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)(ms, ip, iend, offsetPtr); + +#define ZSTD_SWITCH_MLS(X, dictMode) \ + switch (mls) { \ + ZSTD_FOR_EACH_MLS(X, dictMode) \ + } + +#define ZSTD_SWITCH_ROWLOG(dictMode, mls) \ + case mls: \ + switch (rowLog) { \ + ZSTD_FOR_EACH_ROWLOG(GEN_ZSTD_CALL_ROW_SEARCH_FN, dictMode, mls) \ + } \ + ZSTD_UNREACHABLE; \ + break; + +#define ZSTD_SWITCH_SEARCH_METHOD(dictMode) \ + switch (searchMethod) { \ + case search_hashChain: \ + ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_HC_SEARCH_FN, dictMode) \ + break; \ + case search_binaryTree: \ + ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_BT_SEARCH_FN, dictMode) \ + break; \ + case search_rowHash: \ + ZSTD_SWITCH_MLS(ZSTD_SWITCH_ROWLOG, dictMode) \ + break; \ + } \ + ZSTD_UNREACHABLE; + +/** + * Searches for the longest match at @p ip. + * Dispatches to the correct implementation function based on the + * (searchMethod, dictMode, mls, rowLog). We use switch statements + * here instead of using an indirect function call through a function + * pointer because after Spectre and Meltdown mitigations, indirect + * function calls can be very costly, especially in the kernel. + * + * NOTE: dictMode and searchMethod should be templated, so those switch + * statements should be optimized out. Only the mls & rowLog switches + * should be left. + * + * @param ms The match state. + * @param ip The position to search at. + * @param iend The end of the input data. + * @param[out] offsetPtr Stores the match offset into this pointer. + * @param mls The minimum search length, in the range [4, 6]. + * @param rowLog The row log (if applicable), in the range [4, 6]. + * @param searchMethod The search method to use (templated). + * @param dictMode The dictMode (templated). + * + * @returns The length of the longest match found, or < mls if no match is found. + * If a match is found its offset is stored in @p offsetPtr. + */ +FORCE_INLINE_TEMPLATE size_t ZSTD_searchMax( + ZSTD_MatchState_t* ms, + const BYTE* ip, + const BYTE* iend, + size_t* offsetPtr, + U32 const mls, + U32 const rowLog, + searchMethod_e const searchMethod, + ZSTD_dictMode_e const dictMode) +{ + if (dictMode == ZSTD_noDict) { + ZSTD_SWITCH_SEARCH_METHOD(noDict) + } else if (dictMode == ZSTD_extDict) { + ZSTD_SWITCH_SEARCH_METHOD(extDict) + } else if (dictMode == ZSTD_dictMatchState) { + ZSTD_SWITCH_SEARCH_METHOD(dictMatchState) + } else if (dictMode == ZSTD_dedicatedDictSearch) { + ZSTD_SWITCH_SEARCH_METHOD(dedicatedDictSearch) + } + ZSTD_UNREACHABLE; + return 0; +} + +/* ******************************* +* Common parser - lazy strategy +*********************************/ + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_lazy_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const searchMethod_e searchMethod, const U32 depth, + ZSTD_dictMode_e const dictMode) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = (searchMethod == search_rowHash) ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; + const BYTE* const base = ms->window.base; + const U32 prefixLowestIndex = ms->window.dictLimit; + const BYTE* const prefixLowest = base + prefixLowestIndex; + const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6); + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + + U32 offset_1 = rep[0], offset_2 = rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + const int isDMS = dictMode == ZSTD_dictMatchState; + const int isDDS = dictMode == ZSTD_dedicatedDictSearch; + const int isDxS = isDMS || isDDS; + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const U32 dictLowestIndex = isDxS ? dms->window.dictLimit : 0; + const BYTE* const dictBase = isDxS ? dms->window.base : NULL; + const BYTE* const dictLowest = isDxS ? dictBase + dictLowestIndex : NULL; + const BYTE* const dictEnd = isDxS ? dms->window.nextSrc : NULL; + const U32 dictIndexDelta = isDxS ? + prefixLowestIndex - (U32)(dictEnd - dictBase) : + 0; + const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest)); + + DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u) (searchFunc=%u)", (U32)dictMode, (U32)searchMethod); + ip += (dictAndPrefixLength == 0); + if (dictMode == ZSTD_noDict) { + U32 const curr = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, ms->cParams.windowLog); + U32 const maxRep = curr - windowLow; + if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + if (isDxS) { + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + } + + /* Reset the lazy skipping state */ + ms->lazySkipping = 0; + + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + + /* Match Loop */ +#if defined(__GNUC__) && defined(__x86_64__) + /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the + * code alignment is perturbed. To fix the instability align the loop on 32-bytes. + */ + __asm__(".p2align 5"); +#endif + while (ip < ilimit) { + size_t matchLength=0; + size_t offBase = REPCODE1_TO_OFFBASE; + const BYTE* start=ip+1; + DEBUGLOG(7, "search baseline (depth 0)"); + + /* check repCode */ + if (isDxS) { + const U32 repIndex = (U32)(ip - base) + 1 - offset_1; + const BYTE* repMatch = ((dictMode == ZSTD_dictMatchState || dictMode == ZSTD_dedicatedDictSearch) + && repIndex < prefixLowestIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + if (depth==0) goto _storeSequence; + } + } + if ( dictMode == ZSTD_noDict + && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) { + matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; + if (depth==0) goto _storeSequence; + } + + /* first search (depth 0) */ + { size_t offbaseFound = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offbaseFound, mls, rowLog, searchMethod, dictMode); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offBase = offbaseFound; + } + + if (matchLength < 4) { + size_t const step = ((size_t)(ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */; + ip += step; + /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time. + * In this mode we stop inserting every position into our tables, and only insert + * positions that we search, which is one in step positions. + * The exact cutoff is flexible, I've just chosen a number that is reasonably high, + * so we minimize the compression ratio loss in "normal" scenarios. This mode gets + * triggered once we've gone 2KB without finding any matches. + */ + ms->lazySkipping = step > kLazySkippingStep; + continue; + } + + /* let's try to find a better solution */ + if (depth>=1) + while (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) { + size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4; + int const gain2 = (int)(mlRep * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + if (isDxS) { + const U32 repIndex = (U32)(ip - base) - offset_1; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + int const gain2 = (int)(mlRep * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + } + { size_t ofbCandidate=999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, dictMode); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 4); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; /* search a better one */ + } } + + /* let's find an even better one */ + if ((depth==2) && (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) { + size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4; + int const gain2 = (int)(mlRep * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + if (isDxS) { + const U32 repIndex = (U32)(ip - base) - offset_1; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + int const gain2 = (int)(mlRep * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + } + { size_t ofbCandidate=999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, dictMode); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 7); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; + } } } + break; /* nothing found : store previous solution */ + } + + /* NOTE: + * Pay attention that `start[-value]` can lead to strange undefined behavior + * notably if `value` is unsigned, resulting in a large positive `-value`. + */ + /* catch up */ + if (OFFBASE_IS_OFFSET(offBase)) { + if (dictMode == ZSTD_noDict) { + while ( ((start > anchor) & (start - OFFBASE_TO_OFFSET(offBase) > prefixLowest)) + && (start[-1] == (start-OFFBASE_TO_OFFSET(offBase))[-1]) ) /* only search for offset within prefix */ + { start--; matchLength++; } + } + if (isDxS) { + U32 const matchIndex = (U32)((size_t)(start-base) - OFFBASE_TO_OFFSET(offBase)); + const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex; + const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest; + while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ + } + offset_2 = offset_1; offset_1 = (U32)OFFBASE_TO_OFFSET(offBase); + } + /* store sequence */ +_storeSequence: + { size_t const litLength = (size_t)(start - anchor); + ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength); + anchor = ip = start + matchLength; + } + if (ms->lazySkipping) { + /* We've found a match, disable lazy skipping mode, and refill the hash cache. */ + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + ms->lazySkipping = 0; + } + + /* check immediate repcode */ + if (isDxS) { + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex = current2 - offset_2; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase - dictIndexDelta + repIndex : + base + repIndex; + if ( (ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; + } + break; + } + } + + if (dictMode == ZSTD_noDict) { + while ( ((ip <= ilimit) & (offset_2>0)) + && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { + /* store sequence */ + matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap repcodes */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } } } + + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_greedy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_greedy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_greedy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy2_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy2_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_btlazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_dictMatchState); +} +#endif + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_lazy_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const searchMethod_e searchMethod, const U32 depth) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = searchMethod == search_rowHash ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; + const BYTE* const base = ms->window.base; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const dictStart = dictBase + ms->window.lowLimit; + const U32 windowLog = ms->cParams.windowLog; + const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6); + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + + U32 offset_1 = rep[0], offset_2 = rep[1]; + + DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod); + + /* Reset the lazy skipping state */ + ms->lazySkipping = 0; + + /* init */ + ip += (ip == prefixStart); + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + + /* Match Loop */ +#if defined(__GNUC__) && defined(__x86_64__) + /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the + * code alignment is perturbed. To fix the instability align the loop on 32-bytes. + */ + __asm__(".p2align 5"); +#endif + while (ip < ilimit) { + size_t matchLength=0; + size_t offBase = REPCODE1_TO_OFFBASE; + const BYTE* start=ip+1; + U32 curr = (U32)(ip-base); + + /* check repCode */ + { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr+1, windowLog); + const U32 repIndex = (U32)(curr+1 - offset_1); + const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + if ( (ZSTD_index_overlap_check(dictLimit, repIndex)) + & (offset_1 <= curr+1 - windowLow) ) /* note: we are searching at curr+1 */ + if (MEM_read32(ip+1) == MEM_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4; + if (depth==0) goto _storeSequence; + } } + + /* first search (depth 0) */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offBase = ofbCandidate; + } + + if (matchLength < 4) { + size_t const step = ((size_t)(ip-anchor) >> kSearchStrength); + ip += step + 1; /* jump faster over incompressible sections */ + /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time. + * In this mode we stop inserting every position into our tables, and only insert + * positions that we search, which is one in step positions. + * The exact cutoff is flexible, I've just chosen a number that is reasonably high, + * so we minimize the compression ratio loss in "normal" scenarios. This mode gets + * triggered once we've gone 2KB without finding any matches. + */ + ms->lazySkipping = step > kLazySkippingStep; + continue; + } + + /* let's try to find a better solution */ + if (depth>=1) + while (ip repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + int const gain2 = (int)(repLength * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((repLength >= 4) && (gain2 > gain1)) + matchLength = repLength, offBase = REPCODE1_TO_OFFBASE, start = ip; + } } + + /* search match, depth 1 */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 4); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; /* search a better one */ + } } + + /* let's find an even better one */ + if ((depth==2) && (ip repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + int const gain2 = (int)(repLength * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((repLength >= 4) && (gain2 > gain1)) + matchLength = repLength, offBase = REPCODE1_TO_OFFBASE, start = ip; + } } + + /* search match, depth 2 */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 7); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; + } } } + break; /* nothing found : store previous solution */ + } + + /* catch up */ + if (OFFBASE_IS_OFFSET(offBase)) { + U32 const matchIndex = (U32)((size_t)(start-base) - OFFBASE_TO_OFFSET(offBase)); + const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; + const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; + while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ + offset_2 = offset_1; offset_1 = (U32)OFFBASE_TO_OFFSET(offBase); + } + + /* store sequence */ +_storeSequence: + { size_t const litLength = (size_t)(start - anchor); + ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength); + anchor = ip = start + matchLength; + } + if (ms->lazySkipping) { + /* We've found a match, disable lazy skipping mode, and refill the hash cache. */ + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + ms->lazySkipping = 0; + } + + /* check immediate repcode */ + while (ip <= ilimit) { + const U32 repCurrent = (U32)(ip-base); + const U32 windowLow = ZSTD_getLowestMatchIndex(ms, repCurrent, windowLog); + const U32 repIndex = repCurrent - offset_2; + const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + if ( (ZSTD_index_overlap_check(dictLimit, repIndex)) + & (offset_2 <= repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap offset history */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + break; + } } + + /* Save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0); +} + +size_t ZSTD_compressBlock_greedy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1); +} + +size_t ZSTD_compressBlock_lazy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2); +} + +size_t ZSTD_compressBlock_lazy2_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2); +} +#endif diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_lazy.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_lazy.h new file mode 100644 index 000000000..bd8dc49e6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_lazy.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LAZY_H +#define ZSTD_LAZY_H + +#include "zstd_compress_internal.h" + +/** + * Dedicated Dictionary Search Structure bucket log. In the + * ZSTD_dedicatedDictSearch mode, the hashTable has + * 2 ** ZSTD_LAZY_DDSS_BUCKET_LOG entries in each bucket, rather than just + * one. + */ +#define ZSTD_LAZY_DDSS_BUCKET_LOG 2 + +#define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */ + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) +U32 ZSTD_insertAndFindFirstIndex(ZSTD_MatchState_t* ms, const BYTE* ip); +void ZSTD_row_update(ZSTD_MatchState_t* const ms, const BYTE* ip); + +void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_MatchState_t* ms, const BYTE* const ip); + +void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue); /*! used in ZSTD_reduceIndex(). preemptively increase value of ZSTD_DUBT_UNSORTED_MARK */ +#endif + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_GREEDY ZSTD_compressBlock_greedy +#define ZSTD_COMPRESSBLOCK_GREEDY_ROW ZSTD_compressBlock_greedy_row +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE ZSTD_compressBlock_greedy_dictMatchState +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW ZSTD_compressBlock_greedy_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH ZSTD_compressBlock_greedy_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_greedy_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT ZSTD_compressBlock_greedy_extDict +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW ZSTD_compressBlock_greedy_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_GREEDY NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_LAZY ZSTD_compressBlock_lazy +#define ZSTD_COMPRESSBLOCK_LAZY_ROW ZSTD_compressBlock_lazy_row +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE ZSTD_compressBlock_lazy_dictMatchState +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW ZSTD_compressBlock_lazy_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH ZSTD_compressBlock_lazy_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_lazy_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT ZSTD_compressBlock_lazy_extDict +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW ZSTD_compressBlock_lazy_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_LAZY NULL +#define ZSTD_COMPRESSBLOCK_LAZY_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_LAZY2 ZSTD_compressBlock_lazy2 +#define ZSTD_COMPRESSBLOCK_LAZY2_ROW ZSTD_compressBlock_lazy2_row +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE ZSTD_compressBlock_lazy2_dictMatchState +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW ZSTD_compressBlock_lazy2_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH ZSTD_compressBlock_lazy2_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_lazy2_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT ZSTD_compressBlock_lazy2_extDict +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW ZSTD_compressBlock_lazy2_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_LAZY2 NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btlazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btlazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTLAZY2 ZSTD_compressBlock_btlazy2 +#define ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE ZSTD_compressBlock_btlazy2_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT ZSTD_compressBlock_btlazy2_extDict +#else +#define ZSTD_COMPRESSBLOCK_BTLAZY2 NULL +#define ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT NULL +#endif + +#endif /* ZSTD_LAZY_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm.c new file mode 100644 index 000000000..070551cad --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm.c @@ -0,0 +1,745 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_ldm.h" + +#include "../common/debug.h" +#include "../common/xxhash.h" +#include "zstd_fast.h" /* ZSTD_fillHashTable() */ +#include "zstd_double_fast.h" /* ZSTD_fillDoubleHashTable() */ +#include "zstd_ldm_geartab.h" + +#define LDM_BUCKET_SIZE_LOG 4 +#define LDM_MIN_MATCH_LENGTH 64 +#define LDM_HASH_RLOG 7 + +typedef struct { + U64 rolling; + U64 stopMask; +} ldmRollingHashState_t; + +/** ZSTD_ldm_gear_init(): + * + * Initializes the rolling hash state such that it will honor the + * settings in params. */ +static void ZSTD_ldm_gear_init(ldmRollingHashState_t* state, ldmParams_t const* params) +{ + unsigned maxBitsInMask = MIN(params->minMatchLength, 64); + unsigned hashRateLog = params->hashRateLog; + + state->rolling = ~(U32)0; + + /* The choice of the splitting criterion is subject to two conditions: + * 1. it has to trigger on average every 2^(hashRateLog) bytes; + * 2. ideally, it has to depend on a window of minMatchLength bytes. + * + * In the gear hash algorithm, bit n depends on the last n bytes; + * so in order to obtain a good quality splitting criterion it is + * preferable to use bits with high weight. + * + * To match condition 1 we use a mask with hashRateLog bits set + * and, because of the previous remark, we make sure these bits + * have the highest possible weight while still respecting + * condition 2. + */ + if (hashRateLog > 0 && hashRateLog <= maxBitsInMask) { + state->stopMask = (((U64)1 << hashRateLog) - 1) << (maxBitsInMask - hashRateLog); + } else { + /* In this degenerate case we simply honor the hash rate. */ + state->stopMask = ((U64)1 << hashRateLog) - 1; + } +} + +/** ZSTD_ldm_gear_reset() + * Feeds [data, data + minMatchLength) into the hash without registering any + * splits. This effectively resets the hash state. This is used when skipping + * over data, either at the beginning of a block, or skipping sections. + */ +static void ZSTD_ldm_gear_reset(ldmRollingHashState_t* state, + BYTE const* data, size_t minMatchLength) +{ + U64 hash = state->rolling; + size_t n = 0; + +#define GEAR_ITER_ONCE() do { \ + hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \ + n += 1; \ + } while (0) + while (n + 3 < minMatchLength) { + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + } + while (n < minMatchLength) { + GEAR_ITER_ONCE(); + } +#undef GEAR_ITER_ONCE +} + +/** ZSTD_ldm_gear_feed(): + * + * Registers in the splits array all the split points found in the first + * size bytes following the data pointer. This function terminates when + * either all the data has been processed or LDM_BATCH_SIZE splits are + * present in the splits array. + * + * Precondition: The splits array must not be full. + * Returns: The number of bytes processed. */ +static size_t ZSTD_ldm_gear_feed(ldmRollingHashState_t* state, + BYTE const* data, size_t size, + size_t* splits, unsigned* numSplits) +{ + size_t n; + U64 hash, mask; + + hash = state->rolling; + mask = state->stopMask; + n = 0; + +#define GEAR_ITER_ONCE() do { \ + hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \ + n += 1; \ + if (UNLIKELY((hash & mask) == 0)) { \ + splits[*numSplits] = n; \ + *numSplits += 1; \ + if (*numSplits == LDM_BATCH_SIZE) \ + goto done; \ + } \ + } while (0) + + while (n + 3 < size) { + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + } + while (n < size) { + GEAR_ITER_ONCE(); + } + +#undef GEAR_ITER_ONCE + +done: + state->rolling = hash; + return n; +} + +void ZSTD_ldm_adjustParameters(ldmParams_t* params, + const ZSTD_compressionParameters* cParams) +{ + params->windowLog = cParams->windowLog; + ZSTD_STATIC_ASSERT(LDM_BUCKET_SIZE_LOG <= ZSTD_LDM_BUCKETSIZELOG_MAX); + DEBUGLOG(4, "ZSTD_ldm_adjustParameters"); + if (params->hashRateLog == 0) { + if (params->hashLog > 0) { + /* if params->hashLog is set, derive hashRateLog from it */ + assert(params->hashLog <= ZSTD_HASHLOG_MAX); + if (params->windowLog > params->hashLog) { + params->hashRateLog = params->windowLog - params->hashLog; + } + } else { + assert(1 <= (int)cParams->strategy && (int)cParams->strategy <= 9); + /* mapping from [fast, rate7] to [btultra2, rate4] */ + params->hashRateLog = 7 - (cParams->strategy/3); + } + } + if (params->hashLog == 0) { + params->hashLog = BOUNDED(ZSTD_HASHLOG_MIN, params->windowLog - params->hashRateLog, ZSTD_HASHLOG_MAX); + } + if (params->minMatchLength == 0) { + params->minMatchLength = LDM_MIN_MATCH_LENGTH; + if (cParams->strategy >= ZSTD_btultra) + params->minMatchLength /= 2; + } + if (params->bucketSizeLog==0) { + assert(1 <= (int)cParams->strategy && (int)cParams->strategy <= 9); + params->bucketSizeLog = BOUNDED(LDM_BUCKET_SIZE_LOG, (U32)cParams->strategy, ZSTD_LDM_BUCKETSIZELOG_MAX); + } + params->bucketSizeLog = MIN(params->bucketSizeLog, params->hashLog); +} + +size_t ZSTD_ldm_getTableSize(ldmParams_t params) +{ + size_t const ldmHSize = ((size_t)1) << params.hashLog; + size_t const ldmBucketSizeLog = MIN(params.bucketSizeLog, params.hashLog); + size_t const ldmBucketSize = ((size_t)1) << (params.hashLog - ldmBucketSizeLog); + size_t const totalSize = ZSTD_cwksp_alloc_size(ldmBucketSize) + + ZSTD_cwksp_alloc_size(ldmHSize * sizeof(ldmEntry_t)); + return params.enableLdm == ZSTD_ps_enable ? totalSize : 0; +} + +size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize) +{ + return params.enableLdm == ZSTD_ps_enable ? (maxChunkSize / params.minMatchLength) : 0; +} + +/** ZSTD_ldm_getBucket() : + * Returns a pointer to the start of the bucket associated with hash. */ +static ldmEntry_t* ZSTD_ldm_getBucket( + const ldmState_t* ldmState, size_t hash, U32 const bucketSizeLog) +{ + return ldmState->hashTable + (hash << bucketSizeLog); +} + +/** ZSTD_ldm_insertEntry() : + * Insert the entry with corresponding hash into the hash table */ +static void ZSTD_ldm_insertEntry(ldmState_t* ldmState, + size_t const hash, const ldmEntry_t entry, + U32 const bucketSizeLog) +{ + BYTE* const pOffset = ldmState->bucketOffsets + hash; + unsigned const offset = *pOffset; + + *(ZSTD_ldm_getBucket(ldmState, hash, bucketSizeLog) + offset) = entry; + *pOffset = (BYTE)((offset + 1) & ((1u << bucketSizeLog) - 1)); + +} + +/** ZSTD_ldm_countBackwardsMatch() : + * Returns the number of bytes that match backwards before pIn and pMatch. + * + * We count only bytes where pMatch >= pBase and pIn >= pAnchor. */ +static size_t ZSTD_ldm_countBackwardsMatch( + const BYTE* pIn, const BYTE* pAnchor, + const BYTE* pMatch, const BYTE* pMatchBase) +{ + size_t matchLength = 0; + while (pIn > pAnchor && pMatch > pMatchBase && pIn[-1] == pMatch[-1]) { + pIn--; + pMatch--; + matchLength++; + } + return matchLength; +} + +/** ZSTD_ldm_countBackwardsMatch_2segments() : + * Returns the number of bytes that match backwards from pMatch, + * even with the backwards match spanning 2 different segments. + * + * On reaching `pMatchBase`, start counting from mEnd */ +static size_t ZSTD_ldm_countBackwardsMatch_2segments( + const BYTE* pIn, const BYTE* pAnchor, + const BYTE* pMatch, const BYTE* pMatchBase, + const BYTE* pExtDictStart, const BYTE* pExtDictEnd) +{ + size_t matchLength = ZSTD_ldm_countBackwardsMatch(pIn, pAnchor, pMatch, pMatchBase); + if (pMatch - matchLength != pMatchBase || pMatchBase == pExtDictStart) { + /* If backwards match is entirely in the extDict or prefix, immediately return */ + return matchLength; + } + DEBUGLOG(7, "ZSTD_ldm_countBackwardsMatch_2segments: found 2-parts backwards match (length in prefix==%zu)", matchLength); + matchLength += ZSTD_ldm_countBackwardsMatch(pIn - matchLength, pAnchor, pExtDictEnd, pExtDictStart); + DEBUGLOG(7, "final backwards match length = %zu", matchLength); + return matchLength; +} + +/** ZSTD_ldm_fillFastTables() : + * + * Fills the relevant tables for the ZSTD_fast and ZSTD_dfast strategies. + * This is similar to ZSTD_loadDictionaryContent. + * + * The tables for the other strategies are filled within their + * block compressors. */ +static size_t ZSTD_ldm_fillFastTables(ZSTD_MatchState_t* ms, + void const* end) +{ + const BYTE* const iend = (const BYTE*)end; + + switch(ms->cParams.strategy) + { + case ZSTD_fast: + ZSTD_fillHashTable(ms, iend, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx); + break; + + case ZSTD_dfast: +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + ZSTD_fillDoubleHashTable(ms, iend, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + default: + assert(0); /* not possible : not a valid strategy id */ + } + + return 0; +} + +void ZSTD_ldm_fillHashTable( + ldmState_t* ldmState, const BYTE* ip, + const BYTE* iend, ldmParams_t const* params) +{ + U32 const minMatchLength = params->minMatchLength; + U32 const bucketSizeLog = params->bucketSizeLog; + U32 const hBits = params->hashLog - bucketSizeLog; + BYTE const* const base = ldmState->window.base; + BYTE const* const istart = ip; + ldmRollingHashState_t hashState; + size_t* const splits = ldmState->splitIndices; + unsigned numSplits; + + DEBUGLOG(5, "ZSTD_ldm_fillHashTable"); + + ZSTD_ldm_gear_init(&hashState, params); + while (ip < iend) { + size_t hashed; + unsigned n; + + numSplits = 0; + hashed = ZSTD_ldm_gear_feed(&hashState, ip, (size_t)(iend - ip), splits, &numSplits); + + for (n = 0; n < numSplits; n++) { + if (ip + splits[n] >= istart + minMatchLength) { + BYTE const* const split = ip + splits[n] - minMatchLength; + U64 const xxhash = XXH64(split, minMatchLength, 0); + U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1)); + ldmEntry_t entry; + + entry.offset = (U32)(split - base); + entry.checksum = (U32)(xxhash >> 32); + ZSTD_ldm_insertEntry(ldmState, hash, entry, params->bucketSizeLog); + } + } + + ip += hashed; + } +} + + +/** ZSTD_ldm_limitTableUpdate() : + * + * Sets cctx->nextToUpdate to a position corresponding closer to anchor + * if it is far way + * (after a long match, only update tables a limited amount). */ +static void ZSTD_ldm_limitTableUpdate(ZSTD_MatchState_t* ms, const BYTE* anchor) +{ + U32 const curr = (U32)(anchor - ms->window.base); + if (curr > ms->nextToUpdate + 1024) { + ms->nextToUpdate = + curr - MIN(512, curr - ms->nextToUpdate - 1024); + } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_ldm_generateSequences_internal( + ldmState_t* ldmState, RawSeqStore_t* rawSeqStore, + ldmParams_t const* params, void const* src, size_t srcSize) +{ + /* LDM parameters */ + int const extDict = ZSTD_window_hasExtDict(ldmState->window); + U32 const minMatchLength = params->minMatchLength; + U32 const entsPerBucket = 1U << params->bucketSizeLog; + U32 const hBits = params->hashLog - params->bucketSizeLog; + /* Prefix and extDict parameters */ + U32 const dictLimit = ldmState->window.dictLimit; + U32 const lowestIndex = extDict ? ldmState->window.lowLimit : dictLimit; + BYTE const* const base = ldmState->window.base; + BYTE const* const dictBase = extDict ? ldmState->window.dictBase : NULL; + BYTE const* const dictStart = extDict ? dictBase + lowestIndex : NULL; + BYTE const* const dictEnd = extDict ? dictBase + dictLimit : NULL; + BYTE const* const lowPrefixPtr = base + dictLimit; + /* Input bounds */ + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + BYTE const* const ilimit = iend - HASH_READ_SIZE; + /* Input positions */ + BYTE const* anchor = istart; + BYTE const* ip = istart; + /* Rolling hash state */ + ldmRollingHashState_t hashState; + /* Arrays for staged-processing */ + size_t* const splits = ldmState->splitIndices; + ldmMatchCandidate_t* const candidates = ldmState->matchCandidates; + unsigned numSplits; + + if (srcSize < minMatchLength) + return iend - anchor; + + /* Initialize the rolling hash state with the first minMatchLength bytes */ + ZSTD_ldm_gear_init(&hashState, params); + ZSTD_ldm_gear_reset(&hashState, ip, minMatchLength); + ip += minMatchLength; + + while (ip < ilimit) { + size_t hashed; + unsigned n; + + numSplits = 0; + hashed = ZSTD_ldm_gear_feed(&hashState, ip, ilimit - ip, + splits, &numSplits); + + for (n = 0; n < numSplits; n++) { + BYTE const* const split = ip + splits[n] - minMatchLength; + U64 const xxhash = XXH64(split, minMatchLength, 0); + U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1)); + + candidates[n].split = split; + candidates[n].hash = hash; + candidates[n].checksum = (U32)(xxhash >> 32); + candidates[n].bucket = ZSTD_ldm_getBucket(ldmState, hash, params->bucketSizeLog); + PREFETCH_L1(candidates[n].bucket); + } + + for (n = 0; n < numSplits; n++) { + size_t forwardMatchLength = 0, backwardMatchLength = 0, + bestMatchLength = 0, mLength; + U32 offset; + BYTE const* const split = candidates[n].split; + U32 const checksum = candidates[n].checksum; + U32 const hash = candidates[n].hash; + ldmEntry_t* const bucket = candidates[n].bucket; + ldmEntry_t const* cur; + ldmEntry_t const* bestEntry = NULL; + ldmEntry_t newEntry; + + newEntry.offset = (U32)(split - base); + newEntry.checksum = checksum; + + /* If a split point would generate a sequence overlapping with + * the previous one, we merely register it in the hash table and + * move on */ + if (split < anchor) { + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + continue; + } + + for (cur = bucket; cur < bucket + entsPerBucket; cur++) { + size_t curForwardMatchLength, curBackwardMatchLength, + curTotalMatchLength; + if (cur->checksum != checksum || cur->offset <= lowestIndex) { + continue; + } + if (extDict) { + BYTE const* const curMatchBase = + cur->offset < dictLimit ? dictBase : base; + BYTE const* const pMatch = curMatchBase + cur->offset; + BYTE const* const matchEnd = + cur->offset < dictLimit ? dictEnd : iend; + BYTE const* const lowMatchPtr = + cur->offset < dictLimit ? dictStart : lowPrefixPtr; + curForwardMatchLength = + ZSTD_count_2segments(split, pMatch, iend, matchEnd, lowPrefixPtr); + if (curForwardMatchLength < minMatchLength) { + continue; + } + curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch_2segments( + split, anchor, pMatch, lowMatchPtr, dictStart, dictEnd); + } else { /* !extDict */ + BYTE const* const pMatch = base + cur->offset; + curForwardMatchLength = ZSTD_count(split, pMatch, iend); + if (curForwardMatchLength < minMatchLength) { + continue; + } + curBackwardMatchLength = + ZSTD_ldm_countBackwardsMatch(split, anchor, pMatch, lowPrefixPtr); + } + curTotalMatchLength = curForwardMatchLength + curBackwardMatchLength; + + if (curTotalMatchLength > bestMatchLength) { + bestMatchLength = curTotalMatchLength; + forwardMatchLength = curForwardMatchLength; + backwardMatchLength = curBackwardMatchLength; + bestEntry = cur; + } + } + + /* No match found -- insert an entry into the hash table + * and process the next candidate match */ + if (bestEntry == NULL) { + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + continue; + } + + /* Match found */ + offset = (U32)(split - base) - bestEntry->offset; + mLength = forwardMatchLength + backwardMatchLength; + { + rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size; + + /* Out of sequence storage */ + if (rawSeqStore->size == rawSeqStore->capacity) + return ERROR(dstSize_tooSmall); + seq->litLength = (U32)(split - backwardMatchLength - anchor); + seq->matchLength = (U32)mLength; + seq->offset = offset; + rawSeqStore->size++; + } + + /* Insert the current entry into the hash table --- it must be + * done after the previous block to avoid clobbering bestEntry */ + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + + anchor = split + forwardMatchLength; + + /* If we find a match that ends after the data that we've hashed + * then we have a repeating, overlapping, pattern. E.g. all zeros. + * If one repetition of the pattern matches our `stopMask` then all + * repetitions will. We don't need to insert them all into out table, + * only the first one. So skip over overlapping matches. + * This is a major speed boost (20x) for compressing a single byte + * repeated, when that byte ends up in the table. + */ + if (anchor > ip + hashed) { + ZSTD_ldm_gear_reset(&hashState, anchor - minMatchLength, minMatchLength); + /* Continue the outer loop at anchor (ip + hashed == anchor). */ + ip = anchor - hashed; + break; + } + } + + ip += hashed; + } + + return iend - anchor; +} + +/*! ZSTD_ldm_reduceTable() : + * reduce table indexes by `reducerValue` */ +static void ZSTD_ldm_reduceTable(ldmEntry_t* const table, U32 const size, + U32 const reducerValue) +{ + U32 u; + for (u = 0; u < size; u++) { + if (table[u].offset < reducerValue) table[u].offset = 0; + else table[u].offset -= reducerValue; + } +} + +size_t ZSTD_ldm_generateSequences( + ldmState_t* ldmState, RawSeqStore_t* sequences, + ldmParams_t const* params, void const* src, size_t srcSize) +{ + U32 const maxDist = 1U << params->windowLog; + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + size_t const kMaxChunkSize = 1 << 20; + size_t const nbChunks = (srcSize / kMaxChunkSize) + ((srcSize % kMaxChunkSize) != 0); + size_t chunk; + size_t leftoverSize = 0; + + assert(ZSTD_CHUNKSIZE_MAX >= kMaxChunkSize); + /* Check that ZSTD_window_update() has been called for this chunk prior + * to passing it to this function. + */ + assert(ldmState->window.nextSrc >= (BYTE const*)src + srcSize); + /* The input could be very large (in zstdmt), so it must be broken up into + * chunks to enforce the maximum distance and handle overflow correction. + */ + assert(sequences->pos <= sequences->size); + assert(sequences->size <= sequences->capacity); + for (chunk = 0; chunk < nbChunks && sequences->size < sequences->capacity; ++chunk) { + BYTE const* const chunkStart = istart + chunk * kMaxChunkSize; + size_t const remaining = (size_t)(iend - chunkStart); + BYTE const *const chunkEnd = + (remaining < kMaxChunkSize) ? iend : chunkStart + kMaxChunkSize; + size_t const chunkSize = chunkEnd - chunkStart; + size_t newLeftoverSize; + size_t const prevSize = sequences->size; + + assert(chunkStart < iend); + /* 1. Perform overflow correction if necessary. */ + if (ZSTD_window_needOverflowCorrection(ldmState->window, 0, maxDist, ldmState->loadedDictEnd, chunkStart, chunkEnd)) { + U32 const ldmHSize = 1U << params->hashLog; + U32 const correction = ZSTD_window_correctOverflow( + &ldmState->window, /* cycleLog */ 0, maxDist, chunkStart); + ZSTD_ldm_reduceTable(ldmState->hashTable, ldmHSize, correction); + /* invalidate dictionaries on overflow correction */ + ldmState->loadedDictEnd = 0; + } + /* 2. We enforce the maximum offset allowed. + * + * kMaxChunkSize should be small enough that we don't lose too much of + * the window through early invalidation. + * TODO: * Test the chunk size. + * * Try invalidation after the sequence generation and test the + * offset against maxDist directly. + * + * NOTE: Because of dictionaries + sequence splitting we MUST make sure + * that any offset used is valid at the END of the sequence, since it may + * be split into two sequences. This condition holds when using + * ZSTD_window_enforceMaxDist(), but if we move to checking offsets + * against maxDist directly, we'll have to carefully handle that case. + */ + ZSTD_window_enforceMaxDist(&ldmState->window, chunkEnd, maxDist, &ldmState->loadedDictEnd, NULL); + /* 3. Generate the sequences for the chunk, and get newLeftoverSize. */ + newLeftoverSize = ZSTD_ldm_generateSequences_internal( + ldmState, sequences, params, chunkStart, chunkSize); + if (ZSTD_isError(newLeftoverSize)) + return newLeftoverSize; + /* 4. We add the leftover literals from previous iterations to the first + * newly generated sequence, or add the `newLeftoverSize` if none are + * generated. + */ + /* Prepend the leftover literals from the last call */ + if (prevSize < sequences->size) { + sequences->seq[prevSize].litLength += (U32)leftoverSize; + leftoverSize = newLeftoverSize; + } else { + assert(newLeftoverSize == chunkSize); + leftoverSize += chunkSize; + } + } + return 0; +} + +void +ZSTD_ldm_skipSequences(RawSeqStore_t* rawSeqStore, size_t srcSize, U32 const minMatch) +{ + while (srcSize > 0 && rawSeqStore->pos < rawSeqStore->size) { + rawSeq* seq = rawSeqStore->seq + rawSeqStore->pos; + if (srcSize <= seq->litLength) { + /* Skip past srcSize literals */ + seq->litLength -= (U32)srcSize; + return; + } + srcSize -= seq->litLength; + seq->litLength = 0; + if (srcSize < seq->matchLength) { + /* Skip past the first srcSize of the match */ + seq->matchLength -= (U32)srcSize; + if (seq->matchLength < minMatch) { + /* The match is too short, omit it */ + if (rawSeqStore->pos + 1 < rawSeqStore->size) { + seq[1].litLength += seq[0].matchLength; + } + rawSeqStore->pos++; + } + return; + } + srcSize -= seq->matchLength; + seq->matchLength = 0; + rawSeqStore->pos++; + } +} + +/** + * If the sequence length is longer than remaining then the sequence is split + * between this block and the next. + * + * Returns the current sequence to handle, or if the rest of the block should + * be literals, it returns a sequence with offset == 0. + */ +static rawSeq maybeSplitSequence(RawSeqStore_t* rawSeqStore, + U32 const remaining, U32 const minMatch) +{ + rawSeq sequence = rawSeqStore->seq[rawSeqStore->pos]; + assert(sequence.offset > 0); + /* Likely: No partial sequence */ + if (remaining >= sequence.litLength + sequence.matchLength) { + rawSeqStore->pos++; + return sequence; + } + /* Cut the sequence short (offset == 0 ==> rest is literals). */ + if (remaining <= sequence.litLength) { + sequence.offset = 0; + } else if (remaining < sequence.litLength + sequence.matchLength) { + sequence.matchLength = remaining - sequence.litLength; + if (sequence.matchLength < minMatch) { + sequence.offset = 0; + } + } + /* Skip past `remaining` bytes for the future sequences. */ + ZSTD_ldm_skipSequences(rawSeqStore, remaining, minMatch); + return sequence; +} + +void ZSTD_ldm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes) { + U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes); + while (currPos && rawSeqStore->pos < rawSeqStore->size) { + rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos]; + if (currPos >= currSeq.litLength + currSeq.matchLength) { + currPos -= currSeq.litLength + currSeq.matchLength; + rawSeqStore->pos++; + } else { + rawSeqStore->posInSequence = currPos; + break; + } + } + if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) { + rawSeqStore->posInSequence = 0; + } +} + +size_t ZSTD_ldm_blockCompress(RawSeqStore_t* rawSeqStore, + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + ZSTD_ParamSwitch_e useRowMatchFinder, + void const* src, size_t srcSize) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + unsigned const minMatch = cParams->minMatch; + ZSTD_BlockCompressor_f const blockCompressor = + ZSTD_selectBlockCompressor(cParams->strategy, useRowMatchFinder, ZSTD_matchState_dictMode(ms)); + /* Input bounds */ + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + /* Input positions */ + BYTE const* ip = istart; + + DEBUGLOG(5, "ZSTD_ldm_blockCompress: srcSize=%zu", srcSize); + /* If using opt parser, use LDMs only as candidates rather than always accepting them */ + if (cParams->strategy >= ZSTD_btopt) { + size_t lastLLSize; + ms->ldmSeqStore = rawSeqStore; + lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize); + ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize); + return lastLLSize; + } + + assert(rawSeqStore->pos <= rawSeqStore->size); + assert(rawSeqStore->size <= rawSeqStore->capacity); + /* Loop through each sequence and apply the block compressor to the literals */ + while (rawSeqStore->pos < rawSeqStore->size && ip < iend) { + /* maybeSplitSequence updates rawSeqStore->pos */ + rawSeq const sequence = maybeSplitSequence(rawSeqStore, + (U32)(iend - ip), minMatch); + /* End signal */ + if (sequence.offset == 0) + break; + + assert(ip + sequence.litLength + sequence.matchLength <= iend); + + /* Fill tables for block compressor */ + ZSTD_ldm_limitTableUpdate(ms, ip); + ZSTD_ldm_fillFastTables(ms, ip); + /* Run the block compressor */ + DEBUGLOG(5, "pos %u : calling block compressor on segment of size %u", (unsigned)(ip-istart), sequence.litLength); + { + int i; + size_t const newLitLength = + blockCompressor(ms, seqStore, rep, ip, sequence.litLength); + ip += sequence.litLength; + /* Update the repcodes */ + for (i = ZSTD_REP_NUM - 1; i > 0; i--) + rep[i] = rep[i-1]; + rep[0] = sequence.offset; + /* Store the sequence */ + ZSTD_storeSeq(seqStore, newLitLength, ip - newLitLength, iend, + OFFSET_TO_OFFBASE(sequence.offset), + sequence.matchLength); + ip += sequence.matchLength; + } + } + /* Fill the tables for the block compressor */ + ZSTD_ldm_limitTableUpdate(ms, ip); + ZSTD_ldm_fillFastTables(ms, ip); + /* Compress the last literals */ + return blockCompressor(ms, seqStore, rep, ip, iend - ip); +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm.h new file mode 100644 index 000000000..42736231a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LDM_H +#define ZSTD_LDM_H + +#include "zstd_compress_internal.h" /* ldmParams_t, U32 */ +#include "../zstd.h" /* ZSTD_CCtx, size_t */ + +/*-************************************* +* Long distance matching +***************************************/ + +#define ZSTD_LDM_DEFAULT_WINDOW_LOG ZSTD_WINDOWLOG_LIMIT_DEFAULT + +void ZSTD_ldm_fillHashTable( + ldmState_t* state, const BYTE* ip, + const BYTE* iend, ldmParams_t const* params); + +/** + * ZSTD_ldm_generateSequences(): + * + * Generates the sequences using the long distance match finder. + * Generates long range matching sequences in `sequences`, which parse a prefix + * of the source. `sequences` must be large enough to store every sequence, + * which can be checked with `ZSTD_ldm_getMaxNbSeq()`. + * @returns 0 or an error code. + * + * NOTE: The user must have called ZSTD_window_update() for all of the input + * they have, even if they pass it to ZSTD_ldm_generateSequences() in chunks. + * NOTE: This function returns an error if it runs out of space to store + * sequences. + */ +size_t ZSTD_ldm_generateSequences( + ldmState_t* ldms, RawSeqStore_t* sequences, + ldmParams_t const* params, void const* src, size_t srcSize); + +/** + * ZSTD_ldm_blockCompress(): + * + * Compresses a block using the predefined sequences, along with a secondary + * block compressor. The literals section of every sequence is passed to the + * secondary block compressor, and those sequences are interspersed with the + * predefined sequences. Returns the length of the last literals. + * Updates `rawSeqStore.pos` to indicate how many sequences have been consumed. + * `rawSeqStore.seq` may also be updated to split the last sequence between two + * blocks. + * @return The length of the last literals. + * + * NOTE: The source must be at most the maximum block size, but the predefined + * sequences can be any size, and may be longer than the block. In the case that + * they are longer than the block, the last sequences may need to be split into + * two. We handle that case correctly, and update `rawSeqStore` appropriately. + * NOTE: This function does not return any errors. + */ +size_t ZSTD_ldm_blockCompress(RawSeqStore_t* rawSeqStore, + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + ZSTD_ParamSwitch_e useRowMatchFinder, + void const* src, size_t srcSize); + +/** + * ZSTD_ldm_skipSequences(): + * + * Skip past `srcSize` bytes worth of sequences in `rawSeqStore`. + * Avoids emitting matches less than `minMatch` bytes. + * Must be called for data that is not passed to ZSTD_ldm_blockCompress(). + */ +void ZSTD_ldm_skipSequences(RawSeqStore_t* rawSeqStore, size_t srcSize, + U32 const minMatch); + +/* ZSTD_ldm_skipRawSeqStoreBytes(): + * Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'. + * Not to be used in conjunction with ZSTD_ldm_skipSequences(). + * Must be called for data with is not passed to ZSTD_ldm_blockCompress(). + */ +void ZSTD_ldm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes); + +/** ZSTD_ldm_getTableSize() : + * Estimate the space needed for long distance matching tables or 0 if LDM is + * disabled. + */ +size_t ZSTD_ldm_getTableSize(ldmParams_t params); + +/** ZSTD_ldm_getSeqSpace() : + * Return an upper bound on the number of sequences that can be produced by + * the long distance matcher, or 0 if LDM is disabled. + */ +size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize); + +/** ZSTD_ldm_adjustParameters() : + * If the params->hashRateLog is not set, set it to its default value based on + * windowLog and params->hashLog. + * + * Ensures that params->bucketSizeLog is <= params->hashLog (setting it to + * params->hashLog if it is not). + * + * Ensures that the minMatchLength >= targetLength during optimal parsing. + */ +void ZSTD_ldm_adjustParameters(ldmParams_t* params, + ZSTD_compressionParameters const* cParams); + +#endif /* ZSTD_FAST_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm_geartab.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm_geartab.h new file mode 100644 index 000000000..ef34bc5c9 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_ldm_geartab.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LDM_GEARTAB_H +#define ZSTD_LDM_GEARTAB_H + +#include "../common/compiler.h" /* UNUSED_ATTR */ +#include "../common/mem.h" /* U64 */ + +static UNUSED_ATTR const U64 ZSTD_ldm_gearTab[256] = { + 0xf5b8f72c5f77775c, 0x84935f266b7ac412, 0xb647ada9ca730ccc, + 0xb065bb4b114fb1de, 0x34584e7e8c3a9fd0, 0x4e97e17c6ae26b05, + 0x3a03d743bc99a604, 0xcecd042422c4044f, 0x76de76c58524259e, + 0x9c8528f65badeaca, 0x86563706e2097529, 0x2902475fa375d889, + 0xafb32a9739a5ebe6, 0xce2714da3883e639, 0x21eaf821722e69e, + 0x37b628620b628, 0x49a8d455d88caf5, 0x8556d711e6958140, + 0x4f7ae74fc605c1f, 0x829f0c3468bd3a20, 0x4ffdc885c625179e, + 0x8473de048a3daf1b, 0x51008822b05646b2, 0x69d75d12b2d1cc5f, + 0x8c9d4a19159154bc, 0xc3cc10f4abbd4003, 0xd06ddc1cecb97391, + 0xbe48e6e7ed80302e, 0x3481db31cee03547, 0xacc3f67cdaa1d210, + 0x65cb771d8c7f96cc, 0x8eb27177055723dd, 0xc789950d44cd94be, + 0x934feadc3700b12b, 0x5e485f11edbdf182, 0x1e2e2a46fd64767a, + 0x2969ca71d82efa7c, 0x9d46e9935ebbba2e, 0xe056b67e05e6822b, + 0x94d73f55739d03a0, 0xcd7010bdb69b5a03, 0x455ef9fcd79b82f4, + 0x869cb54a8749c161, 0x38d1a4fa6185d225, 0xb475166f94bbe9bb, + 0xa4143548720959f1, 0x7aed4780ba6b26ba, 0xd0ce264439e02312, + 0x84366d746078d508, 0xa8ce973c72ed17be, 0x21c323a29a430b01, + 0x9962d617e3af80ee, 0xab0ce91d9c8cf75b, 0x530e8ee6d19a4dbc, + 0x2ef68c0cf53f5d72, 0xc03a681640a85506, 0x496e4e9f9c310967, + 0x78580472b59b14a0, 0x273824c23b388577, 0x66bf923ad45cb553, + 0x47ae1a5a2492ba86, 0x35e304569e229659, 0x4765182a46870b6f, + 0x6cbab625e9099412, 0xddac9a2e598522c1, 0x7172086e666624f2, + 0xdf5003ca503b7837, 0x88c0c1db78563d09, 0x58d51865acfc289d, + 0x177671aec65224f1, 0xfb79d8a241e967d7, 0x2be1e101cad9a49a, + 0x6625682f6e29186b, 0x399553457ac06e50, 0x35dffb4c23abb74, + 0x429db2591f54aade, 0xc52802a8037d1009, 0x6acb27381f0b25f3, + 0xf45e2551ee4f823b, 0x8b0ea2d99580c2f7, 0x3bed519cbcb4e1e1, + 0xff452823dbb010a, 0x9d42ed614f3dd267, 0x5b9313c06257c57b, + 0xa114b8008b5e1442, 0xc1fe311c11c13d4b, 0x66e8763ea34c5568, + 0x8b982af1c262f05d, 0xee8876faaa75fbb7, 0x8a62a4d0d172bb2a, + 0xc13d94a3b7449a97, 0x6dbbba9dc15d037c, 0xc786101f1d92e0f1, + 0xd78681a907a0b79b, 0xf61aaf2962c9abb9, 0x2cfd16fcd3cb7ad9, + 0x868c5b6744624d21, 0x25e650899c74ddd7, 0xba042af4a7c37463, + 0x4eb1a539465a3eca, 0xbe09dbf03b05d5ca, 0x774e5a362b5472ba, + 0x47a1221229d183cd, 0x504b0ca18ef5a2df, 0xdffbdfbde2456eb9, + 0x46cd2b2fbee34634, 0xf2aef8fe819d98c3, 0x357f5276d4599d61, + 0x24a5483879c453e3, 0x88026889192b4b9, 0x28da96671782dbec, + 0x4ef37c40588e9aaa, 0x8837b90651bc9fb3, 0xc164f741d3f0e5d6, + 0xbc135a0a704b70ba, 0x69cd868f7622ada, 0xbc37ba89e0b9c0ab, + 0x47c14a01323552f6, 0x4f00794bacee98bb, 0x7107de7d637a69d5, + 0x88af793bb6f2255e, 0xf3c6466b8799b598, 0xc288c616aa7f3b59, + 0x81ca63cf42fca3fd, 0x88d85ace36a2674b, 0xd056bd3792389e7, + 0xe55c396c4e9dd32d, 0xbefb504571e6c0a6, 0x96ab32115e91e8cc, + 0xbf8acb18de8f38d1, 0x66dae58801672606, 0x833b6017872317fb, + 0xb87c16f2d1c92864, 0xdb766a74e58b669c, 0x89659f85c61417be, + 0xc8daad856011ea0c, 0x76a4b565b6fe7eae, 0xa469d085f6237312, + 0xaaf0365683a3e96c, 0x4dbb746f8424f7b8, 0x638755af4e4acc1, + 0x3d7807f5bde64486, 0x17be6d8f5bbb7639, 0x903f0cd44dc35dc, + 0x67b672eafdf1196c, 0xa676ff93ed4c82f1, 0x521d1004c5053d9d, + 0x37ba9ad09ccc9202, 0x84e54d297aacfb51, 0xa0b4b776a143445, + 0x820d471e20b348e, 0x1874383cb83d46dc, 0x97edeec7a1efe11c, + 0xb330e50b1bdc42aa, 0x1dd91955ce70e032, 0xa514cdb88f2939d5, + 0x2791233fd90db9d3, 0x7b670a4cc50f7a9b, 0x77c07d2a05c6dfa5, + 0xe3778b6646d0a6fa, 0xb39c8eda47b56749, 0x933ed448addbef28, + 0xaf846af6ab7d0bf4, 0xe5af208eb666e49, 0x5e6622f73534cd6a, + 0x297daeca42ef5b6e, 0x862daef3d35539a6, 0xe68722498f8e1ea9, + 0x981c53093dc0d572, 0xfa09b0bfbf86fbf5, 0x30b1e96166219f15, + 0x70e7d466bdc4fb83, 0x5a66736e35f2a8e9, 0xcddb59d2b7c1baef, + 0xd6c7d247d26d8996, 0xea4e39eac8de1ba3, 0x539c8bb19fa3aff2, + 0x9f90e4c5fd508d8, 0xa34e5956fbaf3385, 0x2e2f8e151d3ef375, + 0x173691e9b83faec1, 0xb85a8d56bf016379, 0x8382381267408ae3, + 0xb90f901bbdc0096d, 0x7c6ad32933bcec65, 0x76bb5e2f2c8ad595, + 0x390f851a6cf46d28, 0xc3e6064da1c2da72, 0xc52a0c101cfa5389, + 0xd78eaf84a3fbc530, 0x3781b9e2288b997e, 0x73c2f6dea83d05c4, + 0x4228e364c5b5ed7, 0x9d7a3edf0da43911, 0x8edcfeda24686756, + 0x5e7667a7b7a9b3a1, 0x4c4f389fa143791d, 0xb08bc1023da7cddc, + 0x7ab4be3ae529b1cc, 0x754e6132dbe74ff9, 0x71635442a839df45, + 0x2f6fb1643fbe52de, 0x961e0a42cf7a8177, 0xf3b45d83d89ef2ea, + 0xee3de4cf4a6e3e9b, 0xcd6848542c3295e7, 0xe4cee1664c78662f, + 0x9947548b474c68c4, 0x25d73777a5ed8b0b, 0xc915b1d636b7fc, + 0x21c2ba75d9b0d2da, 0x5f6b5dcf608a64a1, 0xdcf333255ff9570c, + 0x633b922418ced4ee, 0xc136dde0b004b34a, 0x58cc83b05d4b2f5a, + 0x5eb424dda28e42d2, 0x62df47369739cd98, 0xb4e0b42485e4ce17, + 0x16e1f0c1f9a8d1e7, 0x8ec3916707560ebf, 0x62ba6e2df2cc9db3, + 0xcbf9f4ff77d83a16, 0x78d9d7d07d2bbcc4, 0xef554ce1e02c41f4, + 0x8d7581127eccf94d, 0xa9b53336cb3c8a05, 0x38c42c0bf45c4f91, + 0x640893cdf4488863, 0x80ec34bc575ea568, 0x39f324f5b48eaa40, + 0xe9d9ed1f8eff527f, 0x9224fc058cc5a214, 0xbaba00b04cfe7741, + 0x309a9f120fcf52af, 0xa558f3ec65626212, 0x424bec8b7adabe2f, + 0x41622513a6aea433, 0xb88da2d5324ca798, 0xd287733b245528a4, + 0x9a44697e6d68aec3, 0x7b1093be2f49bb28, 0x50bbec632e3d8aad, + 0x6cd90723e1ea8283, 0x897b9e7431b02bf3, 0x219efdcb338a7047, + 0x3b0311f0a27c0656, 0xdb17bf91c0db96e7, 0x8cd4fd6b4e85a5b2, + 0xfab071054ba6409d, 0x40d6fe831fa9dfd9, 0xaf358debad7d791e, + 0xeb8d0e25a65e3e58, 0xbbcbd3df14e08580, 0xcf751f27ecdab2b, + 0x2b4da14f2613d8f4 +}; + +#endif /* ZSTD_LDM_GEARTAB_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_opt.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_opt.c new file mode 100644 index 000000000..3d7171b75 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_opt.c @@ -0,0 +1,1580 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "hist.h" +#include "zstd_opt.h" + +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) + +#define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */ +#define ZSTD_MAX_PRICE (1<<30) + +#define ZSTD_PREDEF_THRESHOLD 8 /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */ + + +/*-************************************* +* Price functions for optimal parser +***************************************/ + +#if 0 /* approximation at bit level (for tests) */ +# define BITCOST_ACCURACY 0 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat, opt) ((void)(opt), ZSTD_bitWeight(stat)) +#elif 0 /* fractional bit accuracy (for tests) */ +# define BITCOST_ACCURACY 8 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat,opt) ((void)(opt), ZSTD_fracWeight(stat)) +#else /* opt==approx, ultra==accurate */ +# define BITCOST_ACCURACY 8 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat,opt) ((opt) ? ZSTD_fracWeight(stat) : ZSTD_bitWeight(stat)) +#endif + +/* ZSTD_bitWeight() : + * provide estimated "cost" of a stat in full bits only */ +MEM_STATIC U32 ZSTD_bitWeight(U32 stat) +{ + return (ZSTD_highbit32(stat+1) * BITCOST_MULTIPLIER); +} + +/* ZSTD_fracWeight() : + * provide fractional-bit "cost" of a stat, + * using linear interpolation approximation */ +MEM_STATIC U32 ZSTD_fracWeight(U32 rawStat) +{ + U32 const stat = rawStat + 1; + U32 const hb = ZSTD_highbit32(stat); + U32 const BWeight = hb * BITCOST_MULTIPLIER; + /* Fweight was meant for "Fractional weight" + * but it's effectively a value between 1 and 2 + * using fixed point arithmetic */ + U32 const FWeight = (stat << BITCOST_ACCURACY) >> hb; + U32 const weight = BWeight + FWeight; + assert(hb + BITCOST_ACCURACY < 31); + return weight; +} + +#if (DEBUGLEVEL>=2) +/* debugging function, + * @return price in bytes as fractional value + * for debug messages only */ +MEM_STATIC double ZSTD_fCost(int price) +{ + return (double)price / (BITCOST_MULTIPLIER*8); +} +#endif + +static int ZSTD_compressedLiterals(optState_t const* const optPtr) +{ + return optPtr->literalCompressionMode != ZSTD_ps_disable; +} + +static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel) +{ + if (ZSTD_compressedLiterals(optPtr)) + optPtr->litSumBasePrice = WEIGHT(optPtr->litSum, optLevel); + optPtr->litLengthSumBasePrice = WEIGHT(optPtr->litLengthSum, optLevel); + optPtr->matchLengthSumBasePrice = WEIGHT(optPtr->matchLengthSum, optLevel); + optPtr->offCodeSumBasePrice = WEIGHT(optPtr->offCodeSum, optLevel); +} + + +static U32 sum_u32(const unsigned table[], size_t nbElts) +{ + size_t n; + U32 total = 0; + for (n=0; n0); + unsigned const newStat = base + (table[s] >> shift); + sum += newStat; + table[s] = newStat; + } + return sum; +} + +/* ZSTD_scaleStats() : + * reduce all elt frequencies in table if sum too large + * return the resulting sum of elements */ +static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget) +{ + U32 const prevsum = sum_u32(table, lastEltIndex+1); + U32 const factor = prevsum >> logTarget; + DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget); + assert(logTarget < 30); + if (factor <= 1) return prevsum; + return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor), base_1guaranteed); +} + +/* ZSTD_rescaleFreqs() : + * if first block (detected by optPtr->litLengthSum == 0) : init statistics + * take hints from dictionary if there is one + * and init from zero if there is none, + * using src for literals stats, and baseline stats for sequence symbols + * otherwise downscale existing stats, to be used as seed for next block. + */ +static void +ZSTD_rescaleFreqs(optState_t* const optPtr, + const BYTE* const src, size_t const srcSize, + int const optLevel) +{ + int const compressedLiterals = ZSTD_compressedLiterals(optPtr); + DEBUGLOG(5, "ZSTD_rescaleFreqs (srcSize=%u)", (unsigned)srcSize); + optPtr->priceType = zop_dynamic; + + if (optPtr->litLengthSum == 0) { /* no literals stats collected -> first block assumed -> init */ + + /* heuristic: use pre-defined stats for too small inputs */ + if (srcSize <= ZSTD_PREDEF_THRESHOLD) { + DEBUGLOG(5, "srcSize <= %i : use predefined stats", ZSTD_PREDEF_THRESHOLD); + optPtr->priceType = zop_predef; + } + + assert(optPtr->symbolCosts != NULL); + if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) { + + /* huffman stats covering the full value set : table presumed generated by dictionary */ + optPtr->priceType = zop_dynamic; + + if (compressedLiterals) { + /* generate literals statistics from huffman table */ + unsigned lit; + assert(optPtr->litFreq != NULL); + optPtr->litSum = 0; + for (lit=0; lit<=MaxLit; lit++) { + U32 const scaleLog = 11; /* scale to 2K */ + U32 const bitCost = HUF_getNbBitsFromCTable(optPtr->symbolCosts->huf.CTable, lit); + assert(bitCost <= scaleLog); + optPtr->litFreq[lit] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->litSum += optPtr->litFreq[lit]; + } } + + { unsigned ll; + FSE_CState_t llstate; + FSE_initCState(&llstate, optPtr->symbolCosts->fse.litlengthCTable); + optPtr->litLengthSum = 0; + for (ll=0; ll<=MaxLL; ll++) { + U32 const scaleLog = 10; /* scale to 1K */ + U32 const bitCost = FSE_getMaxNbBits(llstate.symbolTT, ll); + assert(bitCost < scaleLog); + optPtr->litLengthFreq[ll] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->litLengthSum += optPtr->litLengthFreq[ll]; + } } + + { unsigned ml; + FSE_CState_t mlstate; + FSE_initCState(&mlstate, optPtr->symbolCosts->fse.matchlengthCTable); + optPtr->matchLengthSum = 0; + for (ml=0; ml<=MaxML; ml++) { + U32 const scaleLog = 10; + U32 const bitCost = FSE_getMaxNbBits(mlstate.symbolTT, ml); + assert(bitCost < scaleLog); + optPtr->matchLengthFreq[ml] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->matchLengthSum += optPtr->matchLengthFreq[ml]; + } } + + { unsigned of; + FSE_CState_t ofstate; + FSE_initCState(&ofstate, optPtr->symbolCosts->fse.offcodeCTable); + optPtr->offCodeSum = 0; + for (of=0; of<=MaxOff; of++) { + U32 const scaleLog = 10; + U32 const bitCost = FSE_getMaxNbBits(ofstate.symbolTT, of); + assert(bitCost < scaleLog); + optPtr->offCodeFreq[of] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->offCodeSum += optPtr->offCodeFreq[of]; + } } + + } else { /* first block, no dictionary */ + + assert(optPtr->litFreq != NULL); + if (compressedLiterals) { + /* base initial cost of literals on direct frequency within src */ + unsigned lit = MaxLit; + HIST_count_simple(optPtr->litFreq, &lit, src, srcSize); /* use raw first block to init statistics */ + optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8, base_0possible); + } + + { unsigned const baseLLfreqs[MaxLL+1] = { + 4, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 + }; + ZSTD_memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs)); + optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1); + } + + { unsigned ml; + for (ml=0; ml<=MaxML; ml++) + optPtr->matchLengthFreq[ml] = 1; + } + optPtr->matchLengthSum = MaxML+1; + + { unsigned const baseOFCfreqs[MaxOff+1] = { + 6, 2, 1, 1, 2, 3, 4, 4, + 4, 3, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 + }; + ZSTD_memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs)); + optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); + } + + } + + } else { /* new block : scale down accumulated statistics */ + + if (compressedLiterals) + optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12); + optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 11); + optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 11); + optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 11); + } + + ZSTD_setBasePrices(optPtr, optLevel); +} + +/* ZSTD_rawLiteralsCost() : + * price of literals (only) in specified segment (which length can be 0). + * does not include price of literalLength symbol */ +static U32 ZSTD_rawLiteralsCost(const BYTE* const literals, U32 const litLength, + const optState_t* const optPtr, + int optLevel) +{ + DEBUGLOG(8, "ZSTD_rawLiteralsCost (%u literals)", litLength); + if (litLength == 0) return 0; + + if (!ZSTD_compressedLiterals(optPtr)) + return (litLength << 3) * BITCOST_MULTIPLIER; /* Uncompressed - 8 bytes per literal. */ + + if (optPtr->priceType == zop_predef) + return (litLength*6) * BITCOST_MULTIPLIER; /* 6 bit per literal - no statistic used */ + + /* dynamic statistics */ + { U32 price = optPtr->litSumBasePrice * litLength; + U32 const litPriceMax = optPtr->litSumBasePrice - BITCOST_MULTIPLIER; + U32 u; + assert(optPtr->litSumBasePrice >= BITCOST_MULTIPLIER); + for (u=0; u < litLength; u++) { + U32 litPrice = WEIGHT(optPtr->litFreq[literals[u]], optLevel); + if (UNLIKELY(litPrice > litPriceMax)) litPrice = litPriceMax; + price -= litPrice; + } + return price; + } +} + +/* ZSTD_litLengthPrice() : + * cost of literalLength symbol */ +static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optPtr, int optLevel) +{ + assert(litLength <= ZSTD_BLOCKSIZE_MAX); + if (optPtr->priceType == zop_predef) + return WEIGHT(litLength, optLevel); + + /* ZSTD_LLcode() can't compute litLength price for sizes >= ZSTD_BLOCKSIZE_MAX + * because it isn't representable in the zstd format. + * So instead just pretend it would cost 1 bit more than ZSTD_BLOCKSIZE_MAX - 1. + * In such a case, the block would be all literals. + */ + if (litLength == ZSTD_BLOCKSIZE_MAX) + return BITCOST_MULTIPLIER + ZSTD_litLengthPrice(ZSTD_BLOCKSIZE_MAX - 1, optPtr, optLevel); + + /* dynamic statistics */ + { U32 const llCode = ZSTD_LLcode(litLength); + return (LL_bits[llCode] * BITCOST_MULTIPLIER) + + optPtr->litLengthSumBasePrice + - WEIGHT(optPtr->litLengthFreq[llCode], optLevel); + } +} + +/* ZSTD_getMatchPrice() : + * Provides the cost of the match part (offset + matchLength) of a sequence. + * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence. + * @offBase : sumtype, representing an offset or a repcode, and using numeric representation of ZSTD_storeSeq() + * @optLevel: when <2, favors small offset for decompression speed (improved cache efficiency) + */ +FORCE_INLINE_TEMPLATE U32 +ZSTD_getMatchPrice(U32 const offBase, + U32 const matchLength, + const optState_t* const optPtr, + int const optLevel) +{ + U32 price; + U32 const offCode = ZSTD_highbit32(offBase); + U32 const mlBase = matchLength - MINMATCH; + assert(matchLength >= MINMATCH); + + if (optPtr->priceType == zop_predef) /* fixed scheme, does not use statistics */ + return WEIGHT(mlBase, optLevel) + + ((16 + offCode) * BITCOST_MULTIPLIER); /* emulated offset cost */ + + /* dynamic statistics */ + price = (offCode * BITCOST_MULTIPLIER) + (optPtr->offCodeSumBasePrice - WEIGHT(optPtr->offCodeFreq[offCode], optLevel)); + if ((optLevel<2) /*static*/ && offCode >= 20) + price += (offCode-19)*2 * BITCOST_MULTIPLIER; /* handicap for long distance offsets, favor decompression speed */ + + /* match Length */ + { U32 const mlCode = ZSTD_MLcode(mlBase); + price += (ML_bits[mlCode] * BITCOST_MULTIPLIER) + (optPtr->matchLengthSumBasePrice - WEIGHT(optPtr->matchLengthFreq[mlCode], optLevel)); + } + + price += BITCOST_MULTIPLIER / 5; /* heuristic : make matches a bit more costly to favor less sequences -> faster decompression speed */ + + DEBUGLOG(8, "ZSTD_getMatchPrice(ml:%u) = %u", matchLength, price); + return price; +} + +/* ZSTD_updateStats() : + * assumption : literals + litLength <= iend */ +static void ZSTD_updateStats(optState_t* const optPtr, + U32 litLength, const BYTE* literals, + U32 offBase, U32 matchLength) +{ + /* literals */ + if (ZSTD_compressedLiterals(optPtr)) { + U32 u; + for (u=0; u < litLength; u++) + optPtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD; + optPtr->litSum += litLength*ZSTD_LITFREQ_ADD; + } + + /* literal Length */ + { U32 const llCode = ZSTD_LLcode(litLength); + optPtr->litLengthFreq[llCode]++; + optPtr->litLengthSum++; + } + + /* offset code : follows storeSeq() numeric representation */ + { U32 const offCode = ZSTD_highbit32(offBase); + assert(offCode <= MaxOff); + optPtr->offCodeFreq[offCode]++; + optPtr->offCodeSum++; + } + + /* match Length */ + { U32 const mlBase = matchLength - MINMATCH; + U32 const mlCode = ZSTD_MLcode(mlBase); + optPtr->matchLengthFreq[mlCode]++; + optPtr->matchLengthSum++; + } +} + + +/* ZSTD_readMINMATCH() : + * function safe only for comparisons + * assumption : memPtr must be at least 4 bytes before end of buffer */ +MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length) +{ + switch (length) + { + default : + case 4 : return MEM_read32(memPtr); + case 3 : if (MEM_isLittleEndian()) + return MEM_read32(memPtr)<<8; + else + return MEM_read32(memPtr)>>8; + } +} + + +/* Update hashTable3 up to ip (excluded) + Assumption : always within prefix (i.e. not within extDict) */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* const ip) +{ + U32* const hashTable3 = ms->hashTable3; + U32 const hashLog3 = ms->hashLog3; + const BYTE* const base = ms->window.base; + U32 idx = *nextToUpdate3; + U32 const target = (U32)(ip - base); + size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3); + assert(hashLog3 > 0); + + while(idx < target) { + hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx; + idx++; + } + + *nextToUpdate3 = target; + return hashTable3[hash3]; +} + + +/*-************************************* +* Binary Tree search +***************************************/ +/** ZSTD_insertBt1() : add one or multiple positions to tree. + * @param ip assumed <= iend-8 . + * @param target The target of ZSTD_updateTree_internal() - we are filling to this position + * @return : nb of positions added */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertBt1( + const ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + U32 const target, + U32 const mls, const int extDict) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 matchIndex = hashTable[h]; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* match; + const U32 curr = (U32)(ip-base); + const U32 btLow = btMask >= curr ? 0 : curr - btMask; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = smallerPtr + 1; + U32 dummy32; /* to be nullified at the end */ + /* windowLow is based on target because + * we only need positions that will be in the window at the end of the tree update. + */ + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, target, cParams->windowLog); + U32 matchEndIdx = curr+8+1; + size_t bestLength = 8; + U32 nbCompares = 1U << cParams->searchLog; +#ifdef ZSTD_C_PREDICT + U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0); + U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1); + predictedSmall += (predictedSmall>0); + predictedLarge += (predictedLarge>0); +#endif /* ZSTD_C_PREDICT */ + + DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr); + + assert(curr <= target); + assert(ip <= iend-8); /* required for h calculation */ + hashTable[h] = curr; /* Update Hash Table */ + + assert(windowLow > 0); + for (; nbCompares && (matchIndex >= windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(matchIndex < curr); + +#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */ + const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */ + if (matchIndex == predictedSmall) { + /* no need to check length, result known */ + *smallerPtr = matchIndex; + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + predictedSmall = predictPtr[1] + (predictPtr[1]>0); + continue; + } + if (matchIndex == predictedLarge) { + *largerPtr = matchIndex; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + predictedLarge = predictPtr[0] + (predictPtr[0]>0); + continue; + } +#endif + + if (!extDict || (matchIndex+matchLength >= dictLimit)) { + assert(matchIndex+matchLength >= dictLimit); /* might be wrong if actually extDict */ + match = base + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + bestLength = matchLength; + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + } + + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */ + } + + if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */ + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + { U32 positions = 0; + if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */ + assert(matchEndIdx > curr + 8); + return MAX(positions, matchEndIdx - (curr + 8)); + } +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_updateTree_internal( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + const U32 mls, const ZSTD_dictMode_e dictMode) +{ + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + DEBUGLOG(7, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)", + idx, target, dictMode); + + while(idx < target) { + U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, target, mls, dictMode == ZSTD_extDict); + assert(idx < (U32)(idx + forward)); + idx += forward; + } + assert((size_t)(ip - base) <= (size_t)(U32)(-1)); + assert((size_t)(iend - base) <= (size_t)(U32)(-1)); + ms->nextToUpdate = target; +} + +void ZSTD_updateTree(ZSTD_MatchState_t* ms, const BYTE* ip, const BYTE* iend) { + ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict); +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 +ZSTD_insertBtAndGetAllMatches ( + ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */ + ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* const ip, const BYTE* const iLimit, + const ZSTD_dictMode_e dictMode, + const U32 rep[ZSTD_REP_NUM], + const U32 ll0, /* tells if associated literal length is 0 or not. This value must be 0 or 1 */ + const U32 lengthToBeat, + const U32 mls /* template */) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); + const BYTE* const base = ms->window.base; + U32 const curr = (U32)(ip-base); + U32 const hashLog = cParams->hashLog; + U32 const minMatch = (mls==3) ? 3 : 4; + U32* const hashTable = ms->hashTable; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 matchIndex = hashTable[h]; + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask= (1U << btLog) - 1; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const dictBase = ms->window.dictBase; + U32 const dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + U32 const btLow = (btMask >= curr) ? 0 : curr - btMask; + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog); + U32 const matchLow = windowLow ? windowLow : 1; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = bt + 2*(curr&btMask) + 1; + U32 matchEndIdx = curr+8+1; /* farthest referenced position of any match => detects repetitive patterns */ + U32 dummy32; /* to be nullified at the end */ + U32 mnum = 0; + U32 nbCompares = 1U << cParams->searchLog; + + const ZSTD_MatchState_t* dms = dictMode == ZSTD_dictMatchState ? ms->dictMatchState : NULL; + const ZSTD_compressionParameters* const dmsCParams = + dictMode == ZSTD_dictMatchState ? &dms->cParams : NULL; + const BYTE* const dmsBase = dictMode == ZSTD_dictMatchState ? dms->window.base : NULL; + const BYTE* const dmsEnd = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL; + U32 const dmsHighLimit = dictMode == ZSTD_dictMatchState ? (U32)(dmsEnd - dmsBase) : 0; + U32 const dmsLowLimit = dictMode == ZSTD_dictMatchState ? dms->window.lowLimit : 0; + U32 const dmsIndexDelta = dictMode == ZSTD_dictMatchState ? windowLow - dmsHighLimit : 0; + U32 const dmsHashLog = dictMode == ZSTD_dictMatchState ? dmsCParams->hashLog : hashLog; + U32 const dmsBtLog = dictMode == ZSTD_dictMatchState ? dmsCParams->chainLog - 1 : btLog; + U32 const dmsBtMask = dictMode == ZSTD_dictMatchState ? (1U << dmsBtLog) - 1 : 0; + U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit; + + size_t bestLength = lengthToBeat-1; + DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr); + + /* check repCode */ + assert(ll0 <= 1); /* necessarily 1 or 0 */ + { U32 const lastR = ZSTD_REP_NUM + ll0; + U32 repCode; + for (repCode = ll0; repCode < lastR; repCode++) { + U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode]; + U32 const repIndex = curr - repOffset; + U32 repLen = 0; + assert(curr >= dictLimit); + if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) { /* equivalent to `curr > repIndex >= dictLimit` */ + /* We must validate the repcode offset because when we're using a dictionary the + * valid offset range shrinks when the dictionary goes out of bounds. + */ + if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) { + repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch; + } + } else { /* repIndex < dictLimit || repIndex >= curr */ + const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ? + dmsBase + repIndex - dmsIndexDelta : + dictBase + repIndex; + assert(curr >= windowLow); + if ( dictMode == ZSTD_extDict + && ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow) /* equivalent to `curr > repIndex >= windowLow` */ + & (ZSTD_index_overlap_check(dictLimit, repIndex)) ) + && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) { + repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch; + } + if (dictMode == ZSTD_dictMatchState + && ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `curr > repIndex >= dmsLowLimit` */ + & (ZSTD_index_overlap_check(dictLimit, repIndex)) ) + && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) { + repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch; + } } + /* save longer solution */ + if (repLen > bestLength) { + DEBUGLOG(8, "found repCode %u (ll0:%u, offset:%u) of length %u", + repCode, ll0, repOffset, repLen); + bestLength = repLen; + matches[mnum].off = REPCODE_TO_OFFBASE(repCode - ll0 + 1); /* expect value between 1 and 3 */ + matches[mnum].len = (U32)repLen; + mnum++; + if ( (repLen > sufficient_len) + | (ip+repLen == iLimit) ) { /* best possible */ + return mnum; + } } } } + + /* HC3 match finder */ + if ((mls == 3) /*static*/ && (bestLength < mls)) { + U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip); + if ((matchIndex3 >= matchLow) + & (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) { + size_t mlen; + if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) { + const BYTE* const match = base + matchIndex3; + mlen = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex3; + mlen = ZSTD_count_2segments(ip, match, iLimit, dictEnd, prefixStart); + } + + /* save best solution */ + if (mlen >= mls /* == 3 > bestLength */) { + DEBUGLOG(8, "found small match with hlog3, of length %u", + (U32)mlen); + bestLength = mlen; + assert(curr > matchIndex3); + assert(mnum==0); /* no prior solution */ + matches[0].off = OFFSET_TO_OFFBASE(curr - matchIndex3); + matches[0].len = (U32)mlen; + mnum = 1; + if ( (mlen > sufficient_len) | + (ip+mlen == iLimit) ) { /* best possible length */ + ms->nextToUpdate = curr+1; /* skip insertion */ + return 1; + } } } + /* no dictMatchState lookup: dicts don't have a populated HC3 table */ + } /* if (mls == 3) */ + + hashTable[h] = curr; /* Update Hash Table */ + + for (; nbCompares && (matchIndex >= matchLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + const BYTE* match; + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(curr > matchIndex); + + if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) { + assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */ + match = base + matchIndex; + if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */ + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit); + } else { + match = dictBase + matchIndex; + assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */ + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* prepare for match[matchLength] read */ + } + + if (matchLength > bestLength) { + DEBUGLOG(8, "found match of length %u at distance %u (offBase=%u)", + (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex)); + assert(matchEndIdx > matchIndex); + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + bestLength = matchLength; + matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex); + matches[mnum].len = (U32)matchLength; + mnum++; + if ( (matchLength > ZSTD_OPT_NUM) + | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) { + if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */ + break; /* drop, to preserve bt consistency (miss a little bit of compression) */ + } } + + if (match[matchLength] < ip[matchLength]) { + /* match smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new candidate => larger than match, which was smaller than current */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous, closer to current */ + } else { + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + + assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dictMatchState && nbCompares) { + size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls); + U32 dictMatchIndex = dms->hashTable[dmsH]; + const U32* const dmsBt = dms->chainTable; + commonLengthSmaller = commonLengthLarger = 0; + for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) { + const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match = dmsBase + dictMatchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dmsEnd, prefixStart); + if (dictMatchIndex+matchLength >= dmsHighLimit) + match = base + dictMatchIndex + dmsIndexDelta; /* to prepare for next usage of match[matchLength] */ + + if (matchLength > bestLength) { + matchIndex = dictMatchIndex + dmsIndexDelta; + DEBUGLOG(8, "found dms match of length %u at distance %u (offBase=%u)", + (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex)); + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + bestLength = matchLength; + matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex); + matches[mnum].len = (U32)matchLength; + mnum++; + if ( (matchLength > ZSTD_OPT_NUM) + | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) { + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } } + + if (dictMatchIndex <= dmsBtLow) { break; } /* beyond tree size, stop the search */ + if (match[matchLength] < ip[matchLength]) { + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + commonLengthLarger = matchLength; + dictMatchIndex = nextPtr[0]; + } } } /* if (dictMode == ZSTD_dictMatchState) */ + + assert(matchEndIdx > curr+8); + ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ + return mnum; +} + +typedef U32 (*ZSTD_getAllMatchesFn)( + ZSTD_match_t*, + ZSTD_MatchState_t*, + U32*, + const BYTE*, + const BYTE*, + const U32 rep[ZSTD_REP_NUM], + U32 const ll0, + U32 const lengthToBeat); + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_btGetAllMatches_internal( + ZSTD_match_t* matches, + ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* ip, + const BYTE* const iHighLimit, + const U32 rep[ZSTD_REP_NUM], + U32 const ll0, + U32 const lengthToBeat, + const ZSTD_dictMode_e dictMode, + const U32 mls) +{ + assert(BOUNDED(3, ms->cParams.minMatch, 6) == mls); + DEBUGLOG(8, "ZSTD_BtGetAllMatches(dictMode=%d, mls=%u)", (int)dictMode, mls); + if (ip < ms->window.base + ms->nextToUpdate) + return 0; /* skipped area */ + ZSTD_updateTree_internal(ms, ip, iHighLimit, mls, dictMode); + return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, mls); +} + +#define ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls) ZSTD_btGetAllMatches_##dictMode##_##mls + +#define GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, mls) \ + static U32 ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls)( \ + ZSTD_match_t* matches, \ + ZSTD_MatchState_t* ms, \ + U32* nextToUpdate3, \ + const BYTE* ip, \ + const BYTE* const iHighLimit, \ + const U32 rep[ZSTD_REP_NUM], \ + U32 const ll0, \ + U32 const lengthToBeat) \ + { \ + return ZSTD_btGetAllMatches_internal( \ + matches, ms, nextToUpdate3, ip, iHighLimit, \ + rep, ll0, lengthToBeat, ZSTD_##dictMode, mls); \ + } + +#define GEN_ZSTD_BT_GET_ALL_MATCHES(dictMode) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 3) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 4) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 5) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 6) + +GEN_ZSTD_BT_GET_ALL_MATCHES(noDict) +GEN_ZSTD_BT_GET_ALL_MATCHES(extDict) +GEN_ZSTD_BT_GET_ALL_MATCHES(dictMatchState) + +#define ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMode) \ + { \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 3), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 4), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 5), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 6) \ + } + +static ZSTD_getAllMatchesFn +ZSTD_selectBtGetAllMatches(ZSTD_MatchState_t const* ms, ZSTD_dictMode_e const dictMode) +{ + ZSTD_getAllMatchesFn const getAllMatchesFns[3][4] = { + ZSTD_BT_GET_ALL_MATCHES_ARRAY(noDict), + ZSTD_BT_GET_ALL_MATCHES_ARRAY(extDict), + ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMatchState) + }; + U32 const mls = BOUNDED(3, ms->cParams.minMatch, 6); + assert((U32)dictMode < 3); + assert(mls - 3 < 4); + return getAllMatchesFns[(int)dictMode][mls - 3]; +} + +/************************* +* LDM helper functions * +*************************/ + +/* Struct containing info needed to make decision about ldm inclusion */ +typedef struct { + RawSeqStore_t seqStore; /* External match candidates store for this block */ + U32 startPosInBlock; /* Start position of the current match candidate */ + U32 endPosInBlock; /* End position of the current match candidate */ + U32 offset; /* Offset of the match candidate */ +} ZSTD_optLdm_t; + +/* ZSTD_optLdm_skipRawSeqStoreBytes(): + * Moves forward in @rawSeqStore by @nbBytes, + * which will update the fields 'pos' and 'posInSequence'. + */ +static void ZSTD_optLdm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes) +{ + U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes); + while (currPos && rawSeqStore->pos < rawSeqStore->size) { + rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos]; + if (currPos >= currSeq.litLength + currSeq.matchLength) { + currPos -= currSeq.litLength + currSeq.matchLength; + rawSeqStore->pos++; + } else { + rawSeqStore->posInSequence = currPos; + break; + } + } + if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) { + rawSeqStore->posInSequence = 0; + } +} + +/* ZSTD_opt_getNextMatchAndUpdateSeqStore(): + * Calculates the beginning and end of the next match in the current block. + * Updates 'pos' and 'posInSequence' of the ldmSeqStore. + */ +static void +ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock, + U32 blockBytesRemaining) +{ + rawSeq currSeq; + U32 currBlockEndPos; + U32 literalsBytesRemaining; + U32 matchBytesRemaining; + + /* Setting match end position to MAX to ensure we never use an LDM during this block */ + if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) { + optLdm->startPosInBlock = UINT_MAX; + optLdm->endPosInBlock = UINT_MAX; + return; + } + /* Calculate appropriate bytes left in matchLength and litLength + * after adjusting based on ldmSeqStore->posInSequence */ + currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos]; + assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength); + currBlockEndPos = currPosInBlock + blockBytesRemaining; + literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ? + currSeq.litLength - (U32)optLdm->seqStore.posInSequence : + 0; + matchBytesRemaining = (literalsBytesRemaining == 0) ? + currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) : + currSeq.matchLength; + + /* If there are more literal bytes than bytes remaining in block, no ldm is possible */ + if (literalsBytesRemaining >= blockBytesRemaining) { + optLdm->startPosInBlock = UINT_MAX; + optLdm->endPosInBlock = UINT_MAX; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining); + return; + } + + /* Matches may be < minMatch by this process. In that case, we will reject them + when we are deciding whether or not to add the ldm */ + optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining; + optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining; + optLdm->offset = currSeq.offset; + + if (optLdm->endPosInBlock > currBlockEndPos) { + /* Match ends after the block ends, we can't use the whole match */ + optLdm->endPosInBlock = currBlockEndPos; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock); + } else { + /* Consume nb of bytes equal to size of sequence left */ + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining); + } +} + +/* ZSTD_optLdm_maybeAddMatch(): + * Adds a match if it's long enough, + * based on it's 'matchStartPosInBlock' and 'matchEndPosInBlock', + * into 'matches'. Maintains the correct ordering of 'matches'. + */ +static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches, + const ZSTD_optLdm_t* optLdm, U32 currPosInBlock, + U32 minMatch) +{ + U32 const posDiff = currPosInBlock - optLdm->startPosInBlock; + /* Note: ZSTD_match_t actually contains offBase and matchLength (before subtracting MINMATCH) */ + U32 const candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff; + + /* Ensure that current block position is not outside of the match */ + if (currPosInBlock < optLdm->startPosInBlock + || currPosInBlock >= optLdm->endPosInBlock + || candidateMatchLength < minMatch) { + return; + } + + if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) { + U32 const candidateOffBase = OFFSET_TO_OFFBASE(optLdm->offset); + DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offBase: %u matchLength %u) at block position=%u", + candidateOffBase, candidateMatchLength, currPosInBlock); + matches[*nbMatches].len = candidateMatchLength; + matches[*nbMatches].off = candidateOffBase; + (*nbMatches)++; + } +} + +/* ZSTD_optLdm_processMatchCandidate(): + * Wrapper function to update ldm seq store and call ldm functions as necessary. + */ +static void +ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, + ZSTD_match_t* matches, U32* nbMatches, + U32 currPosInBlock, U32 remainingBytes, + U32 minMatch) +{ + if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) { + return; + } + + if (currPosInBlock >= optLdm->endPosInBlock) { + if (currPosInBlock > optLdm->endPosInBlock) { + /* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily + * at the end of a match from the ldm seq store, and will often be some bytes + * over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots" + */ + U32 const posOvershoot = currPosInBlock - optLdm->endPosInBlock; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot); + } + ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes); + } + ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock, minMatch); +} + + +/*-******************************* +* Optimal parser +*********************************/ + +#if 0 /* debug */ + +static void +listStats(const U32* table, int lastEltID) +{ + int const nbElts = lastEltID + 1; + int enb; + for (enb=0; enb < nbElts; enb++) { + (void)table; + /* RAWLOG(2, "%3i:%3i, ", enb, table[enb]); */ + RAWLOG(2, "%4i,", table[enb]); + } + RAWLOG(2, " \n"); +} + +#endif + +#define LIT_PRICE(_p) (int)ZSTD_rawLiteralsCost(_p, 1, optStatePtr, optLevel) +#define LL_PRICE(_l) (int)ZSTD_litLengthPrice(_l, optStatePtr, optLevel) +#define LL_INCPRICE(_l) (LL_PRICE(_l) - LL_PRICE(_l-1)) + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t +ZSTD_compressBlock_opt_generic(ZSTD_MatchState_t* ms, + SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const int optLevel, + const ZSTD_dictMode_e dictMode) +{ + optState_t* const optStatePtr = &ms->opt; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + const BYTE* const base = ms->window.base; + const BYTE* const prefixStart = base + ms->window.dictLimit; + const ZSTD_compressionParameters* const cParams = &ms->cParams; + + ZSTD_getAllMatchesFn getAllMatches = ZSTD_selectBtGetAllMatches(ms, dictMode); + + U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); + U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4; + U32 nextToUpdate3 = ms->nextToUpdate; + + ZSTD_optimal_t* const opt = optStatePtr->priceTable; + ZSTD_match_t* const matches = optStatePtr->matchTable; + ZSTD_optimal_t lastStretch; + ZSTD_optLdm_t optLdm; + + ZSTD_memset(&lastStretch, 0, sizeof(ZSTD_optimal_t)); + + optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore; + optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0; + ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip)); + + /* init */ + DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u", + (U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate); + assert(optLevel <= 2); + ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel); + ip += (ip==prefixStart); + + /* Match Loop */ + while (ip < ilimit) { + U32 cur, last_pos = 0; + + /* find first match */ + { U32 const litlen = (U32)(ip - anchor); + U32 const ll0 = !litlen; + U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, ip, iend, rep, ll0, minMatch); + ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, + (U32)(ip-istart), (U32)(iend-ip), + minMatch); + if (!nbMatches) { + DEBUGLOG(8, "no match found at cPos %u", (unsigned)(ip-istart)); + ip++; + continue; + } + + /* Match found: let's store this solution, and eventually find more candidates. + * During this forward pass, @opt is used to store stretches, + * defined as "a match followed by N literals". + * Note how this is different from a Sequence, which is "N literals followed by a match". + * Storing stretches allows us to store different match predecessors + * for each literal position part of a literals run. */ + + /* initialize opt[0] */ + opt[0].mlen = 0; /* there are only literals so far */ + opt[0].litlen = litlen; + /* No need to include the actual price of the literals before the first match + * because it is static for the duration of the forward pass, and is included + * in every subsequent price. But, we include the literal length because + * the cost variation of litlen depends on the value of litlen. + */ + opt[0].price = LL_PRICE(litlen); + ZSTD_STATIC_ASSERT(sizeof(opt[0].rep[0]) == sizeof(rep[0])); + ZSTD_memcpy(&opt[0].rep, rep, sizeof(opt[0].rep)); + + /* large match -> immediate encoding */ + { U32 const maxML = matches[nbMatches-1].len; + U32 const maxOffBase = matches[nbMatches-1].off; + DEBUGLOG(6, "found %u matches of maxLength=%u and maxOffBase=%u at cPos=%u => start new series", + nbMatches, maxML, maxOffBase, (U32)(ip-prefixStart)); + + if (maxML > sufficient_len) { + lastStretch.litlen = 0; + lastStretch.mlen = maxML; + lastStretch.off = maxOffBase; + DEBUGLOG(6, "large match (%u>%u) => immediate encoding", + maxML, sufficient_len); + cur = 0; + last_pos = maxML; + goto _shortestPath; + } } + + /* set prices for first matches starting position == 0 */ + assert(opt[0].price >= 0); + { U32 pos; + U32 matchNb; + for (pos = 1; pos < minMatch; pos++) { + opt[pos].price = ZSTD_MAX_PRICE; + opt[pos].mlen = 0; + opt[pos].litlen = litlen + pos; + } + for (matchNb = 0; matchNb < nbMatches; matchNb++) { + U32 const offBase = matches[matchNb].off; + U32 const end = matches[matchNb].len; + for ( ; pos <= end ; pos++ ) { + int const matchPrice = (int)ZSTD_getMatchPrice(offBase, pos, optStatePtr, optLevel); + int const sequencePrice = opt[0].price + matchPrice; + DEBUGLOG(7, "rPos:%u => set initial price : %.2f", + pos, ZSTD_fCost(sequencePrice)); + opt[pos].mlen = pos; + opt[pos].off = offBase; + opt[pos].litlen = 0; /* end of match */ + opt[pos].price = sequencePrice + LL_PRICE(0); + } + } + last_pos = pos-1; + opt[pos].price = ZSTD_MAX_PRICE; + } + } + + /* check further positions */ + for (cur = 1; cur <= last_pos; cur++) { + const BYTE* const inr = ip + cur; + assert(cur <= ZSTD_OPT_NUM); + DEBUGLOG(7, "cPos:%i==rPos:%u", (int)(inr-istart), cur); + + /* Fix current position with one literal if cheaper */ + { U32 const litlen = opt[cur-1].litlen + 1; + int const price = opt[cur-1].price + + LIT_PRICE(ip+cur-1) + + LL_INCPRICE(litlen); + assert(price < 1000000000); /* overflow check */ + if (price <= opt[cur].price) { + ZSTD_optimal_t const prevMatch = opt[cur]; + DEBUGLOG(7, "cPos:%i==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)", + (int)(inr-istart), cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price), litlen, + opt[cur-1].rep[0], opt[cur-1].rep[1], opt[cur-1].rep[2]); + opt[cur] = opt[cur-1]; + opt[cur].litlen = litlen; + opt[cur].price = price; + if ( (optLevel >= 1) /* additional check only for higher modes */ + && (prevMatch.litlen == 0) /* replace a match */ + && (LL_INCPRICE(1) < 0) /* ll1 is cheaper than ll0 */ + && LIKELY(ip + cur < iend) + ) { + /* check next position, in case it would be cheaper */ + int with1literal = prevMatch.price + LIT_PRICE(ip+cur) + LL_INCPRICE(1); + int withMoreLiterals = price + LIT_PRICE(ip+cur) + LL_INCPRICE(litlen+1); + DEBUGLOG(7, "then at next rPos %u : match+1lit %.2f vs %ulits %.2f", + cur+1, ZSTD_fCost(with1literal), litlen+1, ZSTD_fCost(withMoreLiterals)); + if ( (with1literal < withMoreLiterals) + && (with1literal < opt[cur+1].price) ) { + /* update offset history - before it disappears */ + U32 const prev = cur - prevMatch.mlen; + Repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, prevMatch.off, opt[prev].litlen==0); + assert(cur >= prevMatch.mlen); + DEBUGLOG(7, "==> match+1lit is cheaper (%.2f < %.2f) (hist:%u,%u,%u) !", + ZSTD_fCost(with1literal), ZSTD_fCost(withMoreLiterals), + newReps.rep[0], newReps.rep[1], newReps.rep[2] ); + opt[cur+1] = prevMatch; /* mlen & offbase */ + ZSTD_memcpy(opt[cur+1].rep, &newReps, sizeof(Repcodes_t)); + opt[cur+1].litlen = 1; + opt[cur+1].price = with1literal; + if (last_pos < cur+1) last_pos = cur+1; + } + } + } else { + DEBUGLOG(7, "cPos:%i==rPos:%u : literal would cost more (%.2f>%.2f)", + (int)(inr-istart), cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price)); + } + } + + /* Offset history is not updated during match comparison. + * Do it here, now that the match is selected and confirmed. + */ + ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(Repcodes_t)); + assert(cur >= opt[cur].mlen); + if (opt[cur].litlen == 0) { + /* just finished a match => alter offset history */ + U32 const prev = cur - opt[cur].mlen; + Repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, opt[cur].off, opt[prev].litlen==0); + ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(Repcodes_t)); + } + + /* last match must start at a minimum distance of 8 from oend */ + if (inr > ilimit) continue; + + if (cur == last_pos) break; + + if ( (optLevel==0) /*static_test*/ + && (opt[cur+1].price <= opt[cur].price + (BITCOST_MULTIPLIER/2)) ) { + DEBUGLOG(7, "skip current position : next rPos(%u) price is cheaper", cur+1); + continue; /* skip unpromising positions; about ~+6% speed, -0.01 ratio */ + } + + assert(opt[cur].price >= 0); + { U32 const ll0 = (opt[cur].litlen == 0); + int const previousPrice = opt[cur].price; + int const basePrice = previousPrice + LL_PRICE(0); + U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, inr, iend, opt[cur].rep, ll0, minMatch); + U32 matchNb; + + ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, + (U32)(inr-istart), (U32)(iend-inr), + minMatch); + + if (!nbMatches) { + DEBUGLOG(7, "rPos:%u : no match found", cur); + continue; + } + + { U32 const longestML = matches[nbMatches-1].len; + DEBUGLOG(7, "cPos:%i==rPos:%u, found %u matches, of longest ML=%u", + (int)(inr-istart), cur, nbMatches, longestML); + + if ( (longestML > sufficient_len) + || (cur + longestML >= ZSTD_OPT_NUM) + || (ip + cur + longestML >= iend) ) { + lastStretch.mlen = longestML; + lastStretch.off = matches[nbMatches-1].off; + lastStretch.litlen = 0; + last_pos = cur + longestML; + goto _shortestPath; + } } + + /* set prices using matches found at position == cur */ + for (matchNb = 0; matchNb < nbMatches; matchNb++) { + U32 const offset = matches[matchNb].off; + U32 const lastML = matches[matchNb].len; + U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch; + U32 mlen; + + DEBUGLOG(7, "testing match %u => offBase=%4u, mlen=%2u, llen=%2u", + matchNb, matches[matchNb].off, lastML, opt[cur].litlen); + + for (mlen = lastML; mlen >= startML; mlen--) { /* scan downward */ + U32 const pos = cur + mlen; + int const price = basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel); + + if ((pos > last_pos) || (price < opt[pos].price)) { + DEBUGLOG(7, "rPos:%u (ml=%2u) => new better price (%.2f<%.2f)", + pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price)); + while (last_pos < pos) { + /* fill empty positions, for future comparisons */ + last_pos++; + opt[last_pos].price = ZSTD_MAX_PRICE; + opt[last_pos].litlen = !0; /* just needs to be != 0, to mean "not an end of match" */ + } + opt[pos].mlen = mlen; + opt[pos].off = offset; + opt[pos].litlen = 0; + opt[pos].price = price; + } else { + DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)", + pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price)); + if (optLevel==0) break; /* early update abort; gets ~+10% speed for about -0.01 ratio loss */ + } + } } } + opt[last_pos+1].price = ZSTD_MAX_PRICE; + } /* for (cur = 1; cur <= last_pos; cur++) */ + + lastStretch = opt[last_pos]; + assert(cur >= lastStretch.mlen); + cur = last_pos - lastStretch.mlen; + +_shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */ + assert(opt[0].mlen == 0); + assert(last_pos >= lastStretch.mlen); + assert(cur == last_pos - lastStretch.mlen); + + if (lastStretch.mlen==0) { + /* no solution : all matches have been converted into literals */ + assert(lastStretch.litlen == (ip - anchor) + last_pos); + ip += last_pos; + continue; + } + assert(lastStretch.off > 0); + + /* Update offset history */ + if (lastStretch.litlen == 0) { + /* finishing on a match : update offset history */ + Repcodes_t const reps = ZSTD_newRep(opt[cur].rep, lastStretch.off, opt[cur].litlen==0); + ZSTD_memcpy(rep, &reps, sizeof(Repcodes_t)); + } else { + ZSTD_memcpy(rep, lastStretch.rep, sizeof(Repcodes_t)); + assert(cur >= lastStretch.litlen); + cur -= lastStretch.litlen; + } + + /* Let's write the shortest path solution. + * It is stored in @opt in reverse order, + * starting from @storeEnd (==cur+2), + * effectively partially @opt overwriting. + * Content is changed too: + * - So far, @opt stored stretches, aka a match followed by literals + * - Now, it will store sequences, aka literals followed by a match + */ + { U32 const storeEnd = cur + 2; + U32 storeStart = storeEnd; + U32 stretchPos = cur; + + DEBUGLOG(6, "start reverse traversal (last_pos:%u, cur:%u)", + last_pos, cur); (void)last_pos; + assert(storeEnd < ZSTD_OPT_SIZE); + DEBUGLOG(6, "last stretch copied into pos=%u (llen=%u,mlen=%u,ofc=%u)", + storeEnd, lastStretch.litlen, lastStretch.mlen, lastStretch.off); + if (lastStretch.litlen > 0) { + /* last "sequence" is unfinished: just a bunch of literals */ + opt[storeEnd].litlen = lastStretch.litlen; + opt[storeEnd].mlen = 0; + storeStart = storeEnd-1; + opt[storeStart] = lastStretch; + } { + opt[storeEnd] = lastStretch; /* note: litlen will be fixed */ + storeStart = storeEnd; + } + while (1) { + ZSTD_optimal_t nextStretch = opt[stretchPos]; + opt[storeStart].litlen = nextStretch.litlen; + DEBUGLOG(6, "selected sequence (llen=%u,mlen=%u,ofc=%u)", + opt[storeStart].litlen, opt[storeStart].mlen, opt[storeStart].off); + if (nextStretch.mlen == 0) { + /* reaching beginning of segment */ + break; + } + storeStart--; + opt[storeStart] = nextStretch; /* note: litlen will be fixed */ + assert(nextStretch.litlen + nextStretch.mlen <= stretchPos); + stretchPos -= nextStretch.litlen + nextStretch.mlen; + } + + /* save sequences */ + DEBUGLOG(6, "sending selected sequences into seqStore"); + { U32 storePos; + for (storePos=storeStart; storePos <= storeEnd; storePos++) { + U32 const llen = opt[storePos].litlen; + U32 const mlen = opt[storePos].mlen; + U32 const offBase = opt[storePos].off; + U32 const advance = llen + mlen; + DEBUGLOG(6, "considering seq starting at %i, llen=%u, mlen=%u", + (int)(anchor - istart), (unsigned)llen, (unsigned)mlen); + + if (mlen==0) { /* only literals => must be last "sequence", actually starting a new stream of sequences */ + assert(storePos == storeEnd); /* must be last sequence */ + ip = anchor + llen; /* last "sequence" is a bunch of literals => don't progress anchor */ + continue; /* will finish */ + } + + assert(anchor + llen <= iend); + ZSTD_updateStats(optStatePtr, llen, anchor, offBase, mlen); + ZSTD_storeSeq(seqStore, llen, anchor, iend, offBase, mlen); + anchor += advance; + ip = anchor; + } } + DEBUGLOG(7, "new offset history : %u, %u, %u", rep[0], rep[1], rep[2]); + + /* update all costs */ + ZSTD_setBasePrices(optStatePtr, optLevel); + } + } /* while (ip < ilimit) */ + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +static size_t ZSTD_compressBlock_opt0( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) +{ + return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /* optLevel */, dictMode); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +static size_t ZSTD_compressBlock_opt2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) +{ + return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /* optLevel */, dictMode); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock_btopt"); + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} +#endif + + + + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +/* ZSTD_initStats_ultra(): + * make a first compression pass, just to seed stats with more accurate starting values. + * only works on first block, with no dictionary and no ldm. + * this function cannot error out, its narrow contract must be respected. + */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_initStats_ultra(ZSTD_MatchState_t* ms, + SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + U32 tmpRep[ZSTD_REP_NUM]; /* updated rep codes will sink here */ + ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep)); + + DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize); + assert(ms->opt.litLengthSum == 0); /* first block */ + assert(seqStore->sequences == seqStore->sequencesStart); /* no ldm */ + assert(ms->window.dictLimit == ms->window.lowLimit); /* no dictionary */ + assert(ms->window.dictLimit - ms->nextToUpdate <= 1); /* no prefix (note: intentional overflow, defined as 2-complement) */ + + ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict); /* generate stats into ms->opt*/ + + /* invalidate first scan from history, only keep entropy stats */ + ZSTD_resetSeqStore(seqStore); + ms->window.base -= srcSize; + ms->window.dictLimit += (U32)srcSize; + ms->window.lowLimit = ms->window.dictLimit; + ms->nextToUpdate = ms->window.dictLimit; + +} + +size_t ZSTD_compressBlock_btultra( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock_btultra (srcSize=%zu)", srcSize); + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_btultra2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + U32 const curr = (U32)((const BYTE*)src - ms->window.base); + DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize); + + /* 2-passes strategy: + * this strategy makes a first pass over first block to collect statistics + * in order to seed next round's statistics with it. + * After 1st pass, function forgets history, and starts a new block. + * Consequently, this can only work if no data has been previously loaded in tables, + * aka, no dictionary, no prefix, no ldm preprocessing. + * The compression ratio gain is generally small (~0.5% on first block), + * the cost is 2x cpu time on first block. */ + assert(srcSize <= ZSTD_BLOCKSIZE_MAX); + if ( (ms->opt.litLengthSum==0) /* first block */ + && (seqStore->sequences == seqStore->sequencesStart) /* no ldm */ + && (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */ + && (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */ + && (srcSize > ZSTD_PREDEF_THRESHOLD) /* input large enough to not employ default stats */ + ) { + ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize); + } + + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_btopt_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btultra_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_btultra_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict); +} +#endif + +/* note : no btultra2 variant for extDict nor dictMatchState, + * because btultra2 is not meant to work with dictionaries + * and is only specific for the first block (no prefix) */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_opt.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_opt.h new file mode 100644 index 000000000..756c7b1d0 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_opt.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_OPT_H +#define ZSTD_OPT_H + +#include "zstd_compress_internal.h" + +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) +/* used in ZSTD_loadDictionaryContent() */ +void ZSTD_updateTree(ZSTD_MatchState_t* ms, const BYTE* ip, const BYTE* iend); +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btopt_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btopt_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTOPT ZSTD_compressBlock_btopt +#define ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE ZSTD_compressBlock_btopt_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT ZSTD_compressBlock_btopt_extDict +#else +#define ZSTD_COMPRESSBLOCK_BTOPT NULL +#define ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT NULL +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btultra( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btultra_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btultra_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + + /* note : no btultra2 variant for extDict nor dictMatchState, + * because btultra2 is not meant to work with dictionaries + * and is only specific for the first block (no prefix) */ +size_t ZSTD_compressBlock_btultra2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTULTRA ZSTD_compressBlock_btultra +#define ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE ZSTD_compressBlock_btultra_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT ZSTD_compressBlock_btultra_extDict +#define ZSTD_COMPRESSBLOCK_BTULTRA2 ZSTD_compressBlock_btultra2 +#else +#define ZSTD_COMPRESSBLOCK_BTULTRA NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA2 NULL +#endif + +#endif /* ZSTD_OPT_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_preSplit.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_preSplit.c new file mode 100644 index 000000000..d820c20ac --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_preSplit.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "../common/compiler.h" /* ZSTD_ALIGNOF */ +#include "../common/mem.h" /* S64 */ +#include "../common/zstd_deps.h" /* ZSTD_memset */ +#include "../common/zstd_internal.h" /* ZSTD_STATIC_ASSERT */ +#include "hist.h" /* HIST_add */ +#include "zstd_preSplit.h" + + +#define BLOCKSIZE_MIN 3500 +#define THRESHOLD_PENALTY_RATE 16 +#define THRESHOLD_BASE (THRESHOLD_PENALTY_RATE - 2) +#define THRESHOLD_PENALTY 3 + +#define HASHLENGTH 2 +#define HASHLOG_MAX 10 +#define HASHTABLESIZE (1 << HASHLOG_MAX) +#define HASHMASK (HASHTABLESIZE - 1) +#define KNUTH 0x9e3779b9 + +/* for hashLog > 8, hash 2 bytes. + * for hashLog == 8, just take the byte, no hashing. + * The speed of this method relies on compile-time constant propagation */ +FORCE_INLINE_TEMPLATE unsigned hash2(const void *p, unsigned hashLog) +{ + assert(hashLog >= 8); + if (hashLog == 8) return (U32)((const BYTE*)p)[0]; + assert(hashLog <= HASHLOG_MAX); + return (U32)(MEM_read16(p)) * KNUTH >> (32 - hashLog); +} + + +typedef struct { + unsigned events[HASHTABLESIZE]; + size_t nbEvents; +} Fingerprint; +typedef struct { + Fingerprint pastEvents; + Fingerprint newEvents; +} FPStats; + +static void initStats(FPStats* fpstats) +{ + ZSTD_memset(fpstats, 0, sizeof(FPStats)); +} + +FORCE_INLINE_TEMPLATE void +addEvents_generic(Fingerprint* fp, const void* src, size_t srcSize, size_t samplingRate, unsigned hashLog) +{ + const char* p = (const char*)src; + size_t limit = srcSize - HASHLENGTH + 1; + size_t n; + assert(srcSize >= HASHLENGTH); + for (n = 0; n < limit; n+=samplingRate) { + fp->events[hash2(p+n, hashLog)]++; + } + fp->nbEvents += limit/samplingRate; +} + +FORCE_INLINE_TEMPLATE void +recordFingerprint_generic(Fingerprint* fp, const void* src, size_t srcSize, size_t samplingRate, unsigned hashLog) +{ + ZSTD_memset(fp, 0, sizeof(unsigned) * ((size_t)1 << hashLog)); + fp->nbEvents = 0; + addEvents_generic(fp, src, srcSize, samplingRate, hashLog); +} + +typedef void (*RecordEvents_f)(Fingerprint* fp, const void* src, size_t srcSize); + +#define FP_RECORD(_rate) ZSTD_recordFingerprint_##_rate + +#define ZSTD_GEN_RECORD_FINGERPRINT(_rate, _hSize) \ + static void FP_RECORD(_rate)(Fingerprint* fp, const void* src, size_t srcSize) \ + { \ + recordFingerprint_generic(fp, src, srcSize, _rate, _hSize); \ + } + +ZSTD_GEN_RECORD_FINGERPRINT(1, 10) +ZSTD_GEN_RECORD_FINGERPRINT(5, 10) +ZSTD_GEN_RECORD_FINGERPRINT(11, 9) +ZSTD_GEN_RECORD_FINGERPRINT(43, 8) + + +static U64 abs64(S64 s64) { return (U64)((s64 < 0) ? -s64 : s64); } + +static U64 fpDistance(const Fingerprint* fp1, const Fingerprint* fp2, unsigned hashLog) +{ + U64 distance = 0; + size_t n; + assert(hashLog <= HASHLOG_MAX); + for (n = 0; n < ((size_t)1 << hashLog); n++) { + distance += + abs64((S64)fp1->events[n] * (S64)fp2->nbEvents - (S64)fp2->events[n] * (S64)fp1->nbEvents); + } + return distance; +} + +/* Compare newEvents with pastEvents + * return 1 when considered "too different" + */ +static int compareFingerprints(const Fingerprint* ref, + const Fingerprint* newfp, + int penalty, + unsigned hashLog) +{ + assert(ref->nbEvents > 0); + assert(newfp->nbEvents > 0); + { U64 p50 = (U64)ref->nbEvents * (U64)newfp->nbEvents; + U64 deviation = fpDistance(ref, newfp, hashLog); + U64 threshold = p50 * (U64)(THRESHOLD_BASE + penalty) / THRESHOLD_PENALTY_RATE; + return deviation >= threshold; + } +} + +static void mergeEvents(Fingerprint* acc, const Fingerprint* newfp) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + acc->events[n] += newfp->events[n]; + } + acc->nbEvents += newfp->nbEvents; +} + +static void flushEvents(FPStats* fpstats) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + fpstats->pastEvents.events[n] = fpstats->newEvents.events[n]; + } + fpstats->pastEvents.nbEvents = fpstats->newEvents.nbEvents; + ZSTD_memset(&fpstats->newEvents, 0, sizeof(fpstats->newEvents)); +} + +static void removeEvents(Fingerprint* acc, const Fingerprint* slice) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + assert(acc->events[n] >= slice->events[n]); + acc->events[n] -= slice->events[n]; + } + acc->nbEvents -= slice->nbEvents; +} + +#define CHUNKSIZE (8 << 10) +static size_t ZSTD_splitBlock_byChunks(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize) +{ + static const RecordEvents_f records_fs[] = { + FP_RECORD(43), FP_RECORD(11), FP_RECORD(5), FP_RECORD(1) + }; + static const unsigned hashParams[] = { 8, 9, 10, 10 }; + const RecordEvents_f record_f = (assert(0<=level && level<=3), records_fs[level]); + FPStats* const fpstats = (FPStats*)workspace; + const char* p = (const char*)blockStart; + int penalty = THRESHOLD_PENALTY; + size_t pos = 0; + assert(blockSize == (128 << 10)); + assert(workspace != NULL); + assert((size_t)workspace % ZSTD_ALIGNOF(FPStats) == 0); + ZSTD_STATIC_ASSERT(ZSTD_SLIPBLOCK_WORKSPACESIZE >= sizeof(FPStats)); + assert(wkspSize >= sizeof(FPStats)); (void)wkspSize; + + initStats(fpstats); + record_f(&fpstats->pastEvents, p, CHUNKSIZE); + for (pos = CHUNKSIZE; pos <= blockSize - CHUNKSIZE; pos += CHUNKSIZE) { + record_f(&fpstats->newEvents, p + pos, CHUNKSIZE); + if (compareFingerprints(&fpstats->pastEvents, &fpstats->newEvents, penalty, hashParams[level])) { + return pos; + } else { + mergeEvents(&fpstats->pastEvents, &fpstats->newEvents); + if (penalty > 0) penalty--; + } + } + assert(pos == blockSize); + return blockSize; + (void)flushEvents; (void)removeEvents; +} + +/* ZSTD_splitBlock_fromBorders(): very fast strategy : + * compare fingerprint from beginning and end of the block, + * derive from their difference if it's preferable to split in the middle, + * repeat the process a second time, for finer grained decision. + * 3 times did not brought improvements, so I stopped at 2. + * Benefits are good enough for a cheap heuristic. + * More accurate splitting saves more, but speed impact is also more perceptible. + * For better accuracy, use more elaborate variant *_byChunks. + */ +static size_t ZSTD_splitBlock_fromBorders(const void* blockStart, size_t blockSize, + void* workspace, size_t wkspSize) +{ +#define SEGMENT_SIZE 512 + FPStats* const fpstats = (FPStats*)workspace; + Fingerprint* middleEvents = (Fingerprint*)(void*)((char*)workspace + 512 * sizeof(unsigned)); + assert(blockSize == (128 << 10)); + assert(workspace != NULL); + assert((size_t)workspace % ZSTD_ALIGNOF(FPStats) == 0); + ZSTD_STATIC_ASSERT(ZSTD_SLIPBLOCK_WORKSPACESIZE >= sizeof(FPStats)); + assert(wkspSize >= sizeof(FPStats)); (void)wkspSize; + + initStats(fpstats); + HIST_add(fpstats->pastEvents.events, blockStart, SEGMENT_SIZE); + HIST_add(fpstats->newEvents.events, (const char*)blockStart + blockSize - SEGMENT_SIZE, SEGMENT_SIZE); + fpstats->pastEvents.nbEvents = fpstats->newEvents.nbEvents = SEGMENT_SIZE; + if (!compareFingerprints(&fpstats->pastEvents, &fpstats->newEvents, 0, 8)) + return blockSize; + + HIST_add(middleEvents->events, (const char*)blockStart + blockSize/2 - SEGMENT_SIZE/2, SEGMENT_SIZE); + middleEvents->nbEvents = SEGMENT_SIZE; + { U64 const distFromBegin = fpDistance(&fpstats->pastEvents, middleEvents, 8); + U64 const distFromEnd = fpDistance(&fpstats->newEvents, middleEvents, 8); + U64 const minDistance = SEGMENT_SIZE * SEGMENT_SIZE / 3; + if (abs64((S64)distFromBegin - (S64)distFromEnd) < minDistance) + return 64 KB; + return (distFromBegin > distFromEnd) ? 32 KB : 96 KB; + } +} + +size_t ZSTD_splitBlock(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize) +{ + DEBUGLOG(6, "ZSTD_splitBlock (level=%i)", level); + assert(0<=level && level<=4); + if (level == 0) + return ZSTD_splitBlock_fromBorders(blockStart, blockSize, workspace, wkspSize); + /* level >= 1*/ + return ZSTD_splitBlock_byChunks(blockStart, blockSize, level-1, workspace, wkspSize); +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstd_preSplit.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_preSplit.h new file mode 100644 index 000000000..b89a200dc --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstd_preSplit.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_PRESPLIT_H +#define ZSTD_PRESPLIT_H + +#include /* size_t */ + +#define ZSTD_SLIPBLOCK_WORKSPACESIZE 8208 + +/* ZSTD_splitBlock(): + * @level must be a value between 0 and 4. + * higher levels spend more energy to detect block boundaries. + * @workspace must be aligned for size_t. + * @wkspSize must be at least >= ZSTD_SLIPBLOCK_WORKSPACESIZE + * note: + * For the time being, this function only accepts full 128 KB blocks. + * Therefore, @blockSize must be == 128 KB. + * While this could be extended to smaller sizes in the future, + * it is not yet clear if this would be useful. TBD. + */ +size_t ZSTD_splitBlock(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize); + +#endif /* ZSTD_PRESPLIT_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstdmt_compress.c b/cpp/third_party/zstd-1.5.7/lib/compress/zstdmt_compress.c new file mode 100644 index 000000000..0f1fe6d74 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstdmt_compress.c @@ -0,0 +1,1923 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* ====== Compiler specifics ====== */ +#if defined(_MSC_VER) +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ +#endif + + +/* ====== Dependencies ====== */ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset, INT_MAX, UINT_MAX */ +#include "../common/mem.h" /* MEM_STATIC */ +#include "../common/pool.h" /* threadpool */ +#include "../common/threading.h" /* mutex */ +#include "zstd_compress_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */ +#include "zstd_ldm.h" +#include "zstdmt_compress.h" + +/* Guards code to support resizing the SeqPool. + * We will want to resize the SeqPool to save memory in the future. + * Until then, comment the code out since it is unused. + */ +#define ZSTD_RESIZE_SEQPOOL 0 + +/* ====== Debug ====== */ +#if defined(DEBUGLEVEL) && (DEBUGLEVEL>=2) \ + && !defined(_MSC_VER) \ + && !defined(__MINGW32__) + +# include +# include +# include + +# define DEBUG_PRINTHEX(l,p,n) \ + do { \ + unsigned debug_u; \ + for (debug_u=0; debug_u<(n); debug_u++) \ + RAWLOG(l, "%02X ", ((const unsigned char*)(p))[debug_u]); \ + RAWLOG(l, " \n"); \ + } while (0) + +static unsigned long long GetCurrentClockTimeMicroseconds(void) +{ + static clock_t _ticksPerSecond = 0; + if (_ticksPerSecond <= 0) _ticksPerSecond = sysconf(_SC_CLK_TCK); + + { struct tms junk; clock_t newTicks = (clock_t) times(&junk); + return ((((unsigned long long)newTicks)*(1000000))/_ticksPerSecond); +} } + +#define MUTEX_WAIT_TIME_DLEVEL 6 +#define ZSTD_PTHREAD_MUTEX_LOCK(mutex) \ + do { \ + if (DEBUGLEVEL >= MUTEX_WAIT_TIME_DLEVEL) { \ + unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \ + ZSTD_pthread_mutex_lock(mutex); \ + { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \ + unsigned long long const elapsedTime = (afterTime-beforeTime); \ + if (elapsedTime > 1000) { \ + /* or whatever threshold you like; I'm using 1 millisecond here */ \ + DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, \ + "Thread took %llu microseconds to acquire mutex %s \n", \ + elapsedTime, #mutex); \ + } } \ + } else { \ + ZSTD_pthread_mutex_lock(mutex); \ + } \ + } while (0) + +#else + +# define ZSTD_PTHREAD_MUTEX_LOCK(m) ZSTD_pthread_mutex_lock(m) +# define DEBUG_PRINTHEX(l,p,n) do { } while (0) + +#endif + + +/* ===== Buffer Pool ===== */ +/* a single Buffer Pool can be invoked from multiple threads in parallel */ + +typedef struct buffer_s { + void* start; + size_t capacity; +} Buffer; + +static const Buffer g_nullBuffer = { NULL, 0 }; + +typedef struct ZSTDMT_bufferPool_s { + ZSTD_pthread_mutex_t poolMutex; + size_t bufferSize; + unsigned totalBuffers; + unsigned nbBuffers; + ZSTD_customMem cMem; + Buffer* buffers; +} ZSTDMT_bufferPool; + +static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool) +{ + DEBUGLOG(3, "ZSTDMT_freeBufferPool (address:%08X)", (U32)(size_t)bufPool); + if (!bufPool) return; /* compatibility with free on NULL */ + if (bufPool->buffers) { + unsigned u; + for (u=0; utotalBuffers; u++) { + DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->buffers[u].start); + ZSTD_customFree(bufPool->buffers[u].start, bufPool->cMem); + } + ZSTD_customFree(bufPool->buffers, bufPool->cMem); + } + ZSTD_pthread_mutex_destroy(&bufPool->poolMutex); + ZSTD_customFree(bufPool, bufPool->cMem); +} + +static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_customMem cMem) +{ + ZSTDMT_bufferPool* const bufPool = + (ZSTDMT_bufferPool*)ZSTD_customCalloc(sizeof(ZSTDMT_bufferPool), cMem); + if (bufPool==NULL) return NULL; + if (ZSTD_pthread_mutex_init(&bufPool->poolMutex, NULL)) { + ZSTD_customFree(bufPool, cMem); + return NULL; + } + bufPool->buffers = (Buffer*)ZSTD_customCalloc(maxNbBuffers * sizeof(Buffer), cMem); + if (bufPool->buffers==NULL) { + ZSTDMT_freeBufferPool(bufPool); + return NULL; + } + bufPool->bufferSize = 64 KB; + bufPool->totalBuffers = maxNbBuffers; + bufPool->nbBuffers = 0; + bufPool->cMem = cMem; + return bufPool; +} + +/* only works at initialization, not during compression */ +static size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool* bufPool) +{ + size_t const poolSize = sizeof(*bufPool); + size_t const arraySize = bufPool->totalBuffers * sizeof(Buffer); + unsigned u; + size_t totalBufferSize = 0; + ZSTD_pthread_mutex_lock(&bufPool->poolMutex); + for (u=0; utotalBuffers; u++) + totalBufferSize += bufPool->buffers[u].capacity; + ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); + + return poolSize + arraySize + totalBufferSize; +} + +/* ZSTDMT_setBufferSize() : + * all future buffers provided by this buffer pool will have _at least_ this size + * note : it's better for all buffers to have same size, + * as they become freely interchangeable, reducing malloc/free usages and memory fragmentation */ +static void ZSTDMT_setBufferSize(ZSTDMT_bufferPool* const bufPool, size_t const bSize) +{ + ZSTD_pthread_mutex_lock(&bufPool->poolMutex); + DEBUGLOG(4, "ZSTDMT_setBufferSize: bSize = %u", (U32)bSize); + bufPool->bufferSize = bSize; + ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); +} + + +static ZSTDMT_bufferPool* ZSTDMT_expandBufferPool(ZSTDMT_bufferPool* srcBufPool, unsigned maxNbBuffers) +{ + if (srcBufPool==NULL) return NULL; + if (srcBufPool->totalBuffers >= maxNbBuffers) /* good enough */ + return srcBufPool; + /* need a larger buffer pool */ + { ZSTD_customMem const cMem = srcBufPool->cMem; + size_t const bSize = srcBufPool->bufferSize; /* forward parameters */ + ZSTDMT_bufferPool* newBufPool; + ZSTDMT_freeBufferPool(srcBufPool); + newBufPool = ZSTDMT_createBufferPool(maxNbBuffers, cMem); + if (newBufPool==NULL) return newBufPool; + ZSTDMT_setBufferSize(newBufPool, bSize); + return newBufPool; + } +} + +/** ZSTDMT_getBuffer() : + * assumption : bufPool must be valid + * @return : a buffer, with start pointer and size + * note: allocation may fail, in this case, start==NULL and size==0 */ +static Buffer ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool) +{ + size_t const bSize = bufPool->bufferSize; + DEBUGLOG(5, "ZSTDMT_getBuffer: bSize = %u", (U32)bufPool->bufferSize); + ZSTD_pthread_mutex_lock(&bufPool->poolMutex); + if (bufPool->nbBuffers) { /* try to use an existing buffer */ + Buffer const buf = bufPool->buffers[--(bufPool->nbBuffers)]; + size_t const availBufferSize = buf.capacity; + bufPool->buffers[bufPool->nbBuffers] = g_nullBuffer; + if ((availBufferSize >= bSize) & ((availBufferSize>>3) <= bSize)) { + /* large enough, but not too much */ + DEBUGLOG(5, "ZSTDMT_getBuffer: provide buffer %u of size %u", + bufPool->nbBuffers, (U32)buf.capacity); + ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); + return buf; + } + /* size conditions not respected : scratch this buffer, create new one */ + DEBUGLOG(5, "ZSTDMT_getBuffer: existing buffer does not meet size conditions => freeing"); + ZSTD_customFree(buf.start, bufPool->cMem); + } + ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); + /* create new buffer */ + DEBUGLOG(5, "ZSTDMT_getBuffer: create a new buffer"); + { Buffer buffer; + void* const start = ZSTD_customMalloc(bSize, bufPool->cMem); + buffer.start = start; /* note : start can be NULL if malloc fails ! */ + buffer.capacity = (start==NULL) ? 0 : bSize; + if (start==NULL) { + DEBUGLOG(5, "ZSTDMT_getBuffer: buffer allocation failure !!"); + } else { + DEBUGLOG(5, "ZSTDMT_getBuffer: created buffer of size %u", (U32)bSize); + } + return buffer; + } +} + +#if ZSTD_RESIZE_SEQPOOL +/** ZSTDMT_resizeBuffer() : + * assumption : bufPool must be valid + * @return : a buffer that is at least the buffer pool buffer size. + * If a reallocation happens, the data in the input buffer is copied. + */ +static Buffer ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, Buffer buffer) +{ + size_t const bSize = bufPool->bufferSize; + if (buffer.capacity < bSize) { + void* const start = ZSTD_customMalloc(bSize, bufPool->cMem); + Buffer newBuffer; + newBuffer.start = start; + newBuffer.capacity = start == NULL ? 0 : bSize; + if (start != NULL) { + assert(newBuffer.capacity >= buffer.capacity); + ZSTD_memcpy(newBuffer.start, buffer.start, buffer.capacity); + DEBUGLOG(5, "ZSTDMT_resizeBuffer: created buffer of size %u", (U32)bSize); + return newBuffer; + } + DEBUGLOG(5, "ZSTDMT_resizeBuffer: buffer allocation failure !!"); + } + return buffer; +} +#endif + +/* store buffer for later re-use, up to pool capacity */ +static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, Buffer buf) +{ + DEBUGLOG(5, "ZSTDMT_releaseBuffer"); + if (buf.start == NULL) return; /* compatible with release on NULL */ + ZSTD_pthread_mutex_lock(&bufPool->poolMutex); + if (bufPool->nbBuffers < bufPool->totalBuffers) { + bufPool->buffers[bufPool->nbBuffers++] = buf; /* stored for later use */ + DEBUGLOG(5, "ZSTDMT_releaseBuffer: stored buffer of size %u in slot %u", + (U32)buf.capacity, (U32)(bufPool->nbBuffers-1)); + ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); + return; + } + ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); + /* Reached bufferPool capacity (note: should not happen) */ + DEBUGLOG(5, "ZSTDMT_releaseBuffer: pool capacity reached => freeing "); + ZSTD_customFree(buf.start, bufPool->cMem); +} + +/* We need 2 output buffers per worker since each dstBuff must be flushed after it is released. + * The 3 additional buffers are as follows: + * 1 buffer for input loading + * 1 buffer for "next input" when submitting current one + * 1 buffer stuck in queue */ +#define BUF_POOL_MAX_NB_BUFFERS(nbWorkers) (2*(nbWorkers) + 3) + +/* After a worker releases its rawSeqStore, it is immediately ready for reuse. + * So we only need one seq buffer per worker. */ +#define SEQ_POOL_MAX_NB_BUFFERS(nbWorkers) (nbWorkers) + +/* ===== Seq Pool Wrapper ====== */ + +typedef ZSTDMT_bufferPool ZSTDMT_seqPool; + +static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool) +{ + return ZSTDMT_sizeof_bufferPool(seqPool); +} + +static RawSeqStore_t bufferToSeq(Buffer buffer) +{ + RawSeqStore_t seq = kNullRawSeqStore; + seq.seq = (rawSeq*)buffer.start; + seq.capacity = buffer.capacity / sizeof(rawSeq); + return seq; +} + +static Buffer seqToBuffer(RawSeqStore_t seq) +{ + Buffer buffer; + buffer.start = seq.seq; + buffer.capacity = seq.capacity * sizeof(rawSeq); + return buffer; +} + +static RawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool* seqPool) +{ + if (seqPool->bufferSize == 0) { + return kNullRawSeqStore; + } + return bufferToSeq(ZSTDMT_getBuffer(seqPool)); +} + +#if ZSTD_RESIZE_SEQPOOL +static RawSeqStore_t ZSTDMT_resizeSeq(ZSTDMT_seqPool* seqPool, RawSeqStore_t seq) +{ + return bufferToSeq(ZSTDMT_resizeBuffer(seqPool, seqToBuffer(seq))); +} +#endif + +static void ZSTDMT_releaseSeq(ZSTDMT_seqPool* seqPool, RawSeqStore_t seq) +{ + ZSTDMT_releaseBuffer(seqPool, seqToBuffer(seq)); +} + +static void ZSTDMT_setNbSeq(ZSTDMT_seqPool* const seqPool, size_t const nbSeq) +{ + ZSTDMT_setBufferSize(seqPool, nbSeq * sizeof(rawSeq)); +} + +static ZSTDMT_seqPool* ZSTDMT_createSeqPool(unsigned nbWorkers, ZSTD_customMem cMem) +{ + ZSTDMT_seqPool* const seqPool = ZSTDMT_createBufferPool(SEQ_POOL_MAX_NB_BUFFERS(nbWorkers), cMem); + if (seqPool == NULL) return NULL; + ZSTDMT_setNbSeq(seqPool, 0); + return seqPool; +} + +static void ZSTDMT_freeSeqPool(ZSTDMT_seqPool* seqPool) +{ + ZSTDMT_freeBufferPool(seqPool); +} + +static ZSTDMT_seqPool* ZSTDMT_expandSeqPool(ZSTDMT_seqPool* pool, U32 nbWorkers) +{ + return ZSTDMT_expandBufferPool(pool, SEQ_POOL_MAX_NB_BUFFERS(nbWorkers)); +} + + +/* ===== CCtx Pool ===== */ +/* a single CCtx Pool can be invoked from multiple threads in parallel */ + +typedef struct { + ZSTD_pthread_mutex_t poolMutex; + int totalCCtx; + int availCCtx; + ZSTD_customMem cMem; + ZSTD_CCtx** cctxs; +} ZSTDMT_CCtxPool; + +/* note : all CCtx borrowed from the pool must be reverted back to the pool _before_ freeing the pool */ +static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool) +{ + if (!pool) return; + ZSTD_pthread_mutex_destroy(&pool->poolMutex); + if (pool->cctxs) { + int cid; + for (cid=0; cidtotalCCtx; cid++) + ZSTD_freeCCtx(pool->cctxs[cid]); /* free compatible with NULL */ + ZSTD_customFree(pool->cctxs, pool->cMem); + } + ZSTD_customFree(pool, pool->cMem); +} + +/* ZSTDMT_createCCtxPool() : + * implies nbWorkers >= 1 , checked by caller ZSTDMT_createCCtx() */ +static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(int nbWorkers, + ZSTD_customMem cMem) +{ + ZSTDMT_CCtxPool* const cctxPool = + (ZSTDMT_CCtxPool*) ZSTD_customCalloc(sizeof(ZSTDMT_CCtxPool), cMem); + assert(nbWorkers > 0); + if (!cctxPool) return NULL; + if (ZSTD_pthread_mutex_init(&cctxPool->poolMutex, NULL)) { + ZSTD_customFree(cctxPool, cMem); + return NULL; + } + cctxPool->totalCCtx = nbWorkers; + cctxPool->cctxs = (ZSTD_CCtx**)ZSTD_customCalloc(nbWorkers * sizeof(ZSTD_CCtx*), cMem); + if (!cctxPool->cctxs) { + ZSTDMT_freeCCtxPool(cctxPool); + return NULL; + } + cctxPool->cMem = cMem; + cctxPool->cctxs[0] = ZSTD_createCCtx_advanced(cMem); + if (!cctxPool->cctxs[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; } + cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */ + DEBUGLOG(3, "cctxPool created, with %u workers", nbWorkers); + return cctxPool; +} + +static ZSTDMT_CCtxPool* ZSTDMT_expandCCtxPool(ZSTDMT_CCtxPool* srcPool, + int nbWorkers) +{ + if (srcPool==NULL) return NULL; + if (nbWorkers <= srcPool->totalCCtx) return srcPool; /* good enough */ + /* need a larger cctx pool */ + { ZSTD_customMem const cMem = srcPool->cMem; + ZSTDMT_freeCCtxPool(srcPool); + return ZSTDMT_createCCtxPool(nbWorkers, cMem); + } +} + +/* only works during initialization phase, not during compression */ +static size_t ZSTDMT_sizeof_CCtxPool(ZSTDMT_CCtxPool* cctxPool) +{ + ZSTD_pthread_mutex_lock(&cctxPool->poolMutex); + { unsigned const nbWorkers = cctxPool->totalCCtx; + size_t const poolSize = sizeof(*cctxPool); + size_t const arraySize = cctxPool->totalCCtx * sizeof(ZSTD_CCtx*); + size_t totalCCtxSize = 0; + unsigned u; + for (u=0; ucctxs[u]); + } + ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex); + assert(nbWorkers > 0); + return poolSize + arraySize + totalCCtxSize; + } +} + +static ZSTD_CCtx* ZSTDMT_getCCtx(ZSTDMT_CCtxPool* cctxPool) +{ + DEBUGLOG(5, "ZSTDMT_getCCtx"); + ZSTD_pthread_mutex_lock(&cctxPool->poolMutex); + if (cctxPool->availCCtx) { + cctxPool->availCCtx--; + { ZSTD_CCtx* const cctx = cctxPool->cctxs[cctxPool->availCCtx]; + ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex); + return cctx; + } } + ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex); + DEBUGLOG(5, "create one more CCtx"); + return ZSTD_createCCtx_advanced(cctxPool->cMem); /* note : can be NULL, when creation fails ! */ +} + +static void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool* pool, ZSTD_CCtx* cctx) +{ + if (cctx==NULL) return; /* compatibility with release on NULL */ + ZSTD_pthread_mutex_lock(&pool->poolMutex); + if (pool->availCCtx < pool->totalCCtx) + pool->cctxs[pool->availCCtx++] = cctx; + else { + /* pool overflow : should not happen, since totalCCtx==nbWorkers */ + DEBUGLOG(4, "CCtx pool overflow : free cctx"); + ZSTD_freeCCtx(cctx); + } + ZSTD_pthread_mutex_unlock(&pool->poolMutex); +} + +/* ==== Serial State ==== */ + +typedef struct { + void const* start; + size_t size; +} Range; + +typedef struct { + /* All variables in the struct are protected by mutex. */ + ZSTD_pthread_mutex_t mutex; + ZSTD_pthread_cond_t cond; + ZSTD_CCtx_params params; + ldmState_t ldmState; + XXH64_state_t xxhState; + unsigned nextJobID; + /* Protects ldmWindow. + * Must be acquired after the main mutex when acquiring both. + */ + ZSTD_pthread_mutex_t ldmWindowMutex; + ZSTD_pthread_cond_t ldmWindowCond; /* Signaled when ldmWindow is updated */ + ZSTD_window_t ldmWindow; /* A thread-safe copy of ldmState.window */ +} SerialState; + +static int +ZSTDMT_serialState_reset(SerialState* serialState, + ZSTDMT_seqPool* seqPool, + ZSTD_CCtx_params params, + size_t jobSize, + const void* dict, size_t const dictSize, + ZSTD_dictContentType_e dictContentType) +{ + /* Adjust parameters */ + if (params.ldmParams.enableLdm == ZSTD_ps_enable) { + DEBUGLOG(4, "LDM window size = %u KB", (1U << params.cParams.windowLog) >> 10); + ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams); + assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog); + assert(params.ldmParams.hashRateLog < 32); + } else { + ZSTD_memset(¶ms.ldmParams, 0, sizeof(params.ldmParams)); + } + serialState->nextJobID = 0; + if (params.fParams.checksumFlag) + XXH64_reset(&serialState->xxhState, 0); + if (params.ldmParams.enableLdm == ZSTD_ps_enable) { + ZSTD_customMem cMem = params.customMem; + unsigned const hashLog = params.ldmParams.hashLog; + size_t const hashSize = ((size_t)1 << hashLog) * sizeof(ldmEntry_t); + unsigned const bucketLog = + params.ldmParams.hashLog - params.ldmParams.bucketSizeLog; + unsigned const prevBucketLog = + serialState->params.ldmParams.hashLog - + serialState->params.ldmParams.bucketSizeLog; + size_t const numBuckets = (size_t)1 << bucketLog; + /* Size the seq pool tables */ + ZSTDMT_setNbSeq(seqPool, ZSTD_ldm_getMaxNbSeq(params.ldmParams, jobSize)); + /* Reset the window */ + ZSTD_window_init(&serialState->ldmState.window); + /* Resize tables and output space if necessary. */ + if (serialState->ldmState.hashTable == NULL || serialState->params.ldmParams.hashLog < hashLog) { + ZSTD_customFree(serialState->ldmState.hashTable, cMem); + serialState->ldmState.hashTable = (ldmEntry_t*)ZSTD_customMalloc(hashSize, cMem); + } + if (serialState->ldmState.bucketOffsets == NULL || prevBucketLog < bucketLog) { + ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem); + serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_customMalloc(numBuckets, cMem); + } + if (!serialState->ldmState.hashTable || !serialState->ldmState.bucketOffsets) + return 1; + /* Zero the tables */ + ZSTD_memset(serialState->ldmState.hashTable, 0, hashSize); + ZSTD_memset(serialState->ldmState.bucketOffsets, 0, numBuckets); + + /* Update window state and fill hash table with dict */ + serialState->ldmState.loadedDictEnd = 0; + if (dictSize > 0) { + if (dictContentType == ZSTD_dct_rawContent) { + BYTE const* const dictEnd = (const BYTE*)dict + dictSize; + ZSTD_window_update(&serialState->ldmState.window, dict, dictSize, /* forceNonContiguous */ 0); + ZSTD_ldm_fillHashTable(&serialState->ldmState, (const BYTE*)dict, dictEnd, ¶ms.ldmParams); + serialState->ldmState.loadedDictEnd = params.forceWindow ? 0 : (U32)(dictEnd - serialState->ldmState.window.base); + } else { + /* don't even load anything */ + } + } + + /* Initialize serialState's copy of ldmWindow. */ + serialState->ldmWindow = serialState->ldmState.window; + } + + serialState->params = params; + serialState->params.jobSize = (U32)jobSize; + return 0; +} + +static int ZSTDMT_serialState_init(SerialState* serialState) +{ + int initError = 0; + ZSTD_memset(serialState, 0, sizeof(*serialState)); + initError |= ZSTD_pthread_mutex_init(&serialState->mutex, NULL); + initError |= ZSTD_pthread_cond_init(&serialState->cond, NULL); + initError |= ZSTD_pthread_mutex_init(&serialState->ldmWindowMutex, NULL); + initError |= ZSTD_pthread_cond_init(&serialState->ldmWindowCond, NULL); + return initError; +} + +static void ZSTDMT_serialState_free(SerialState* serialState) +{ + ZSTD_customMem cMem = serialState->params.customMem; + ZSTD_pthread_mutex_destroy(&serialState->mutex); + ZSTD_pthread_cond_destroy(&serialState->cond); + ZSTD_pthread_mutex_destroy(&serialState->ldmWindowMutex); + ZSTD_pthread_cond_destroy(&serialState->ldmWindowCond); + ZSTD_customFree(serialState->ldmState.hashTable, cMem); + ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem); +} + +static void +ZSTDMT_serialState_genSequences(SerialState* serialState, + RawSeqStore_t* seqStore, + Range src, unsigned jobID) +{ + /* Wait for our turn */ + ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex); + while (serialState->nextJobID < jobID) { + DEBUGLOG(5, "wait for serialState->cond"); + ZSTD_pthread_cond_wait(&serialState->cond, &serialState->mutex); + } + /* A future job may error and skip our job */ + if (serialState->nextJobID == jobID) { + /* It is now our turn, do any processing necessary */ + if (serialState->params.ldmParams.enableLdm == ZSTD_ps_enable) { + size_t error; + DEBUGLOG(6, "ZSTDMT_serialState_genSequences: LDM update"); + assert(seqStore->seq != NULL && seqStore->pos == 0 && + seqStore->size == 0 && seqStore->capacity > 0); + assert(src.size <= serialState->params.jobSize); + ZSTD_window_update(&serialState->ldmState.window, src.start, src.size, /* forceNonContiguous */ 0); + error = ZSTD_ldm_generateSequences( + &serialState->ldmState, seqStore, + &serialState->params.ldmParams, src.start, src.size); + /* We provide a large enough buffer to never fail. */ + assert(!ZSTD_isError(error)); (void)error; + /* Update ldmWindow to match the ldmState.window and signal the main + * thread if it is waiting for a buffer. + */ + ZSTD_PTHREAD_MUTEX_LOCK(&serialState->ldmWindowMutex); + serialState->ldmWindow = serialState->ldmState.window; + ZSTD_pthread_cond_signal(&serialState->ldmWindowCond); + ZSTD_pthread_mutex_unlock(&serialState->ldmWindowMutex); + } + if (serialState->params.fParams.checksumFlag && src.size > 0) + XXH64_update(&serialState->xxhState, src.start, src.size); + } + /* Now it is the next jobs turn */ + serialState->nextJobID++; + ZSTD_pthread_cond_broadcast(&serialState->cond); + ZSTD_pthread_mutex_unlock(&serialState->mutex); +} + +static void +ZSTDMT_serialState_applySequences(const SerialState* serialState, /* just for an assert() check */ + ZSTD_CCtx* jobCCtx, + const RawSeqStore_t* seqStore) +{ + if (seqStore->size > 0) { + DEBUGLOG(5, "ZSTDMT_serialState_applySequences: uploading %u external sequences", (unsigned)seqStore->size); + assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable); (void)serialState; + assert(jobCCtx); + ZSTD_referenceExternalSequences(jobCCtx, seqStore->seq, seqStore->size); + } +} + +static void ZSTDMT_serialState_ensureFinished(SerialState* serialState, + unsigned jobID, size_t cSize) +{ + ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex); + if (serialState->nextJobID <= jobID) { + assert(ZSTD_isError(cSize)); (void)cSize; + DEBUGLOG(5, "Skipping past job %u because of error", jobID); + serialState->nextJobID = jobID + 1; + ZSTD_pthread_cond_broadcast(&serialState->cond); + + ZSTD_PTHREAD_MUTEX_LOCK(&serialState->ldmWindowMutex); + ZSTD_window_clear(&serialState->ldmWindow); + ZSTD_pthread_cond_signal(&serialState->ldmWindowCond); + ZSTD_pthread_mutex_unlock(&serialState->ldmWindowMutex); + } + ZSTD_pthread_mutex_unlock(&serialState->mutex); + +} + + +/* ------------------------------------------ */ +/* ===== Worker thread ===== */ +/* ------------------------------------------ */ + +static const Range kNullRange = { NULL, 0 }; + +typedef struct { + size_t consumed; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx */ + size_t cSize; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx, then set0 by mtctx */ + ZSTD_pthread_mutex_t job_mutex; /* Thread-safe - used by mtctx and worker */ + ZSTD_pthread_cond_t job_cond; /* Thread-safe - used by mtctx and worker */ + ZSTDMT_CCtxPool* cctxPool; /* Thread-safe - used by mtctx and (all) workers */ + ZSTDMT_bufferPool* bufPool; /* Thread-safe - used by mtctx and (all) workers */ + ZSTDMT_seqPool* seqPool; /* Thread-safe - used by mtctx and (all) workers */ + SerialState* serial; /* Thread-safe - used by mtctx and (all) workers */ + Buffer dstBuff; /* set by worker (or mtctx), then read by worker & mtctx, then modified by mtctx => no barrier */ + Range prefix; /* set by mtctx, then read by worker & mtctx => no barrier */ + Range src; /* set by mtctx, then read by worker & mtctx => no barrier */ + unsigned jobID; /* set by mtctx, then read by worker => no barrier */ + unsigned firstJob; /* set by mtctx, then read by worker => no barrier */ + unsigned lastJob; /* set by mtctx, then read by worker => no barrier */ + ZSTD_CCtx_params params; /* set by mtctx, then read by worker => no barrier */ + const ZSTD_CDict* cdict; /* set by mtctx, then read by worker => no barrier */ + unsigned long long fullFrameSize; /* set by mtctx, then read by worker => no barrier */ + size_t dstFlushed; /* used only by mtctx */ + unsigned frameChecksumNeeded; /* used only by mtctx */ +} ZSTDMT_jobDescription; + +#define JOB_ERROR(e) \ + do { \ + ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); \ + job->cSize = e; \ + ZSTD_pthread_mutex_unlock(&job->job_mutex); \ + goto _endJob; \ + } while (0) + +/* ZSTDMT_compressionJob() is a POOL_function type */ +static void ZSTDMT_compressionJob(void* jobDescription) +{ + ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription; + ZSTD_CCtx_params jobParams = job->params; /* do not modify job->params ! copy it, modify the copy */ + ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(job->cctxPool); + RawSeqStore_t rawSeqStore = ZSTDMT_getSeq(job->seqPool); + Buffer dstBuff = job->dstBuff; + size_t lastCBlockSize = 0; + + DEBUGLOG(5, "ZSTDMT_compressionJob: job %u", job->jobID); + /* resources */ + if (cctx==NULL) JOB_ERROR(ERROR(memory_allocation)); + if (dstBuff.start == NULL) { /* streaming job : doesn't provide a dstBuffer */ + dstBuff = ZSTDMT_getBuffer(job->bufPool); + if (dstBuff.start==NULL) JOB_ERROR(ERROR(memory_allocation)); + job->dstBuff = dstBuff; /* this value can be read in ZSTDMT_flush, when it copies the whole job */ + } + if (jobParams.ldmParams.enableLdm == ZSTD_ps_enable && rawSeqStore.seq == NULL) + JOB_ERROR(ERROR(memory_allocation)); + + /* Don't compute the checksum for chunks, since we compute it externally, + * but write it in the header. + */ + if (job->jobID != 0) jobParams.fParams.checksumFlag = 0; + /* Don't run LDM for the chunks, since we handle it externally */ + jobParams.ldmParams.enableLdm = ZSTD_ps_disable; + /* Correct nbWorkers to 0. */ + jobParams.nbWorkers = 0; + + + /* init */ + + /* Perform serial step as early as possible */ + ZSTDMT_serialState_genSequences(job->serial, &rawSeqStore, job->src, job->jobID); + + if (job->cdict) { + size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, &jobParams, job->fullFrameSize); + assert(job->firstJob); /* only allowed for first job */ + if (ZSTD_isError(initError)) JOB_ERROR(initError); + } else { + U64 const pledgedSrcSize = job->firstJob ? job->fullFrameSize : job->src.size; + { size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob); + if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError); + } + if (!job->firstJob) { + size_t const err = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_deterministicRefPrefix, 0); + if (ZSTD_isError(err)) JOB_ERROR(err); + } + DEBUGLOG(6, "ZSTDMT_compressionJob: job %u: loading prefix of size %zu", job->jobID, job->prefix.size); + { size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, + job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, + ZSTD_dtlm_fast, + NULL, /*cdict*/ + &jobParams, pledgedSrcSize); + if (ZSTD_isError(initError)) JOB_ERROR(initError); + } } + + /* External Sequences can only be applied after CCtx initialization */ + ZSTDMT_serialState_applySequences(job->serial, cctx, &rawSeqStore); + + if (!job->firstJob) { /* flush and overwrite frame header when it's not first job */ + size_t const hSize = ZSTD_compressContinue_public(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0); + if (ZSTD_isError(hSize)) JOB_ERROR(hSize); + DEBUGLOG(5, "ZSTDMT_compressionJob: flush and overwrite %u bytes of frame header (not first job)", (U32)hSize); + ZSTD_invalidateRepCodes(cctx); + } + + /* compress the entire job by smaller chunks, for better granularity */ + { size_t const chunkSize = 4*ZSTD_BLOCKSIZE_MAX; + int const nbChunks = (int)((job->src.size + (chunkSize-1)) / chunkSize); + const BYTE* ip = (const BYTE*) job->src.start; + BYTE* const ostart = (BYTE*)dstBuff.start; + BYTE* op = ostart; + BYTE* oend = op + dstBuff.capacity; + int chunkNb; + if (sizeof(size_t) > sizeof(int)) assert(job->src.size < ((size_t)INT_MAX) * chunkSize); /* check overflow */ + DEBUGLOG(5, "ZSTDMT_compressionJob: compress %u bytes in %i blocks", (U32)job->src.size, nbChunks); + assert(job->cSize == 0); + for (chunkNb = 1; chunkNb < nbChunks; chunkNb++) { + size_t const cSize = ZSTD_compressContinue_public(cctx, op, oend-op, ip, chunkSize); + if (ZSTD_isError(cSize)) JOB_ERROR(cSize); + ip += chunkSize; + op += cSize; assert(op < oend); + /* stats */ + ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); + job->cSize += cSize; + job->consumed = chunkSize * chunkNb; + DEBUGLOG(5, "ZSTDMT_compressionJob: compress new block : cSize==%u bytes (total: %u)", + (U32)cSize, (U32)job->cSize); + ZSTD_pthread_cond_signal(&job->job_cond); /* warns some more data is ready to be flushed */ + ZSTD_pthread_mutex_unlock(&job->job_mutex); + } + /* last block */ + assert(chunkSize > 0); + assert((chunkSize & (chunkSize - 1)) == 0); /* chunkSize must be power of 2 for mask==(chunkSize-1) to work */ + if ((nbChunks > 0) | job->lastJob /*must output a "last block" flag*/ ) { + size_t const lastBlockSize1 = job->src.size & (chunkSize-1); + size_t const lastBlockSize = ((lastBlockSize1==0) & (job->src.size>=chunkSize)) ? chunkSize : lastBlockSize1; + size_t const cSize = (job->lastJob) ? + ZSTD_compressEnd_public(cctx, op, oend-op, ip, lastBlockSize) : + ZSTD_compressContinue_public(cctx, op, oend-op, ip, lastBlockSize); + if (ZSTD_isError(cSize)) JOB_ERROR(cSize); + lastCBlockSize = cSize; + } } + if (!job->firstJob) { + /* Double check that we don't have an ext-dict, because then our + * repcode invalidation doesn't work. + */ + assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window)); + } + ZSTD_CCtx_trace(cctx, 0); + +_endJob: + ZSTDMT_serialState_ensureFinished(job->serial, job->jobID, job->cSize); + if (job->prefix.size > 0) + DEBUGLOG(5, "Finished with prefix: %zx", (size_t)job->prefix.start); + DEBUGLOG(5, "Finished with source: %zx", (size_t)job->src.start); + /* release resources */ + ZSTDMT_releaseSeq(job->seqPool, rawSeqStore); + ZSTDMT_releaseCCtx(job->cctxPool, cctx); + /* report */ + ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); + if (ZSTD_isError(job->cSize)) assert(lastCBlockSize == 0); + job->cSize += lastCBlockSize; + job->consumed = job->src.size; /* when job->consumed == job->src.size , compression job is presumed completed */ + ZSTD_pthread_cond_signal(&job->job_cond); + ZSTD_pthread_mutex_unlock(&job->job_mutex); +} + + +/* ------------------------------------------ */ +/* ===== Multi-threaded compression ===== */ +/* ------------------------------------------ */ + +typedef struct { + Range prefix; /* read-only non-owned prefix buffer */ + Buffer buffer; + size_t filled; +} InBuff_t; + +typedef struct { + BYTE* buffer; /* The round input buffer. All jobs get references + * to pieces of the buffer. ZSTDMT_tryGetInputRange() + * handles handing out job input buffers, and makes + * sure it doesn't overlap with any pieces still in use. + */ + size_t capacity; /* The capacity of buffer. */ + size_t pos; /* The position of the current inBuff in the round + * buffer. Updated past the end if the inBuff once + * the inBuff is sent to the worker thread. + * pos <= capacity. + */ +} RoundBuff_t; + +static const RoundBuff_t kNullRoundBuff = {NULL, 0, 0}; + +#define RSYNC_LENGTH 32 +/* Don't create chunks smaller than the zstd block size. + * This stops us from regressing compression ratio too much, + * and ensures our output fits in ZSTD_compressBound(). + * + * If this is shrunk < ZSTD_BLOCKSIZELOG_MIN then + * ZSTD_COMPRESSBOUND() will need to be updated. + */ +#define RSYNC_MIN_BLOCK_LOG ZSTD_BLOCKSIZELOG_MAX +#define RSYNC_MIN_BLOCK_SIZE (1< one job is already prepared, but pool has shortage of workers. Don't create a new job. */ + InBuff_t inBuff; + RoundBuff_t roundBuff; + SerialState serial; + RSyncState_t rsync; + unsigned jobIDMask; + unsigned doneJobID; + unsigned nextJobID; + unsigned frameEnded; + unsigned allJobsCompleted; + unsigned long long frameContentSize; + unsigned long long consumed; + unsigned long long produced; + ZSTD_customMem cMem; + ZSTD_CDict* cdictLocal; + const ZSTD_CDict* cdict; + unsigned providedFactory: 1; +}; + +static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZSTD_customMem cMem) +{ + U32 jobNb; + if (jobTable == NULL) return; + for (jobNb=0; jobNb mtctx->jobIDMask+1) { /* need more job capacity */ + ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem); + mtctx->jobIDMask = 0; + mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, mtctx->cMem); + if (mtctx->jobs==NULL) return ERROR(memory_allocation); + assert((nbJobs != 0) && ((nbJobs & (nbJobs - 1)) == 0)); /* ensure nbJobs is a power of 2 */ + mtctx->jobIDMask = nbJobs - 1; + } + return 0; +} + + +/* ZSTDMT_CCtxParam_setNbWorkers(): + * Internal use only */ +static size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers) +{ + return ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, (int)nbWorkers); +} + +MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool) +{ + ZSTDMT_CCtx* mtctx; + U32 nbJobs = nbWorkers + 2; + int initError; + DEBUGLOG(3, "ZSTDMT_createCCtx_advanced (nbWorkers = %u)", nbWorkers); + + if (nbWorkers < 1) return NULL; + nbWorkers = MIN(nbWorkers , ZSTDMT_NBWORKERS_MAX); + if ((cMem.customAlloc!=NULL) ^ (cMem.customFree!=NULL)) + /* invalid custom allocator */ + return NULL; + + mtctx = (ZSTDMT_CCtx*) ZSTD_customCalloc(sizeof(ZSTDMT_CCtx), cMem); + if (!mtctx) return NULL; + ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers); + mtctx->cMem = cMem; + mtctx->allJobsCompleted = 1; + if (pool != NULL) { + mtctx->factory = pool; + mtctx->providedFactory = 1; + } + else { + mtctx->factory = POOL_create_advanced(nbWorkers, 0, cMem); + mtctx->providedFactory = 0; + } + mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, cMem); + assert(nbJobs > 0); assert((nbJobs & (nbJobs - 1)) == 0); /* ensure nbJobs is a power of 2 */ + mtctx->jobIDMask = nbJobs - 1; + mtctx->bufPool = ZSTDMT_createBufferPool(BUF_POOL_MAX_NB_BUFFERS(nbWorkers), cMem); + mtctx->cctxPool = ZSTDMT_createCCtxPool(nbWorkers, cMem); + mtctx->seqPool = ZSTDMT_createSeqPool(nbWorkers, cMem); + initError = ZSTDMT_serialState_init(&mtctx->serial); + mtctx->roundBuff = kNullRoundBuff; + if (!mtctx->factory | !mtctx->jobs | !mtctx->bufPool | !mtctx->cctxPool | !mtctx->seqPool | initError) { + ZSTDMT_freeCCtx(mtctx); + return NULL; + } + DEBUGLOG(3, "mt_cctx created, for %u threads", nbWorkers); + return mtctx; +} + +ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool) +{ +#ifdef ZSTD_MULTITHREAD + return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem, pool); +#else + (void)nbWorkers; + (void)cMem; + (void)pool; + return NULL; +#endif +} + + +/* ZSTDMT_releaseAllJobResources() : + * note : ensure all workers are killed first ! */ +static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx) +{ + unsigned jobID; + DEBUGLOG(3, "ZSTDMT_releaseAllJobResources"); + for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) { + /* Copy the mutex/cond out */ + ZSTD_pthread_mutex_t const mutex = mtctx->jobs[jobID].job_mutex; + ZSTD_pthread_cond_t const cond = mtctx->jobs[jobID].job_cond; + + DEBUGLOG(4, "job%02u: release dst address %08X", jobID, (U32)(size_t)mtctx->jobs[jobID].dstBuff.start); + ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff); + + /* Clear the job description, but keep the mutex/cond */ + ZSTD_memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID])); + mtctx->jobs[jobID].job_mutex = mutex; + mtctx->jobs[jobID].job_cond = cond; + } + mtctx->inBuff.buffer = g_nullBuffer; + mtctx->inBuff.filled = 0; + mtctx->allJobsCompleted = 1; +} + +static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* mtctx) +{ + DEBUGLOG(4, "ZSTDMT_waitForAllJobsCompleted"); + while (mtctx->doneJobID < mtctx->nextJobID) { + unsigned const jobID = mtctx->doneJobID & mtctx->jobIDMask; + ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex); + while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) { + DEBUGLOG(4, "waiting for jobCompleted signal from job %u", mtctx->doneJobID); /* we want to block when waiting for data to flush */ + ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex); + } + ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex); + mtctx->doneJobID++; + } +} + +size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx) +{ + if (mtctx==NULL) return 0; /* compatible with free on NULL */ + if (!mtctx->providedFactory) + POOL_free(mtctx->factory); /* stop and free worker threads */ + ZSTDMT_releaseAllJobResources(mtctx); /* release job resources into pools first */ + ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem); + ZSTDMT_freeBufferPool(mtctx->bufPool); + ZSTDMT_freeCCtxPool(mtctx->cctxPool); + ZSTDMT_freeSeqPool(mtctx->seqPool); + ZSTDMT_serialState_free(&mtctx->serial); + ZSTD_freeCDict(mtctx->cdictLocal); + if (mtctx->roundBuff.buffer) + ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem); + ZSTD_customFree(mtctx, mtctx->cMem); + return 0; +} + +size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx) +{ + if (mtctx == NULL) return 0; /* supports sizeof NULL */ + return sizeof(*mtctx) + + POOL_sizeof(mtctx->factory) + + ZSTDMT_sizeof_bufferPool(mtctx->bufPool) + + (mtctx->jobIDMask+1) * sizeof(ZSTDMT_jobDescription) + + ZSTDMT_sizeof_CCtxPool(mtctx->cctxPool) + + ZSTDMT_sizeof_seqPool(mtctx->seqPool) + + ZSTD_sizeof_CDict(mtctx->cdictLocal) + + mtctx->roundBuff.capacity; +} + + +/* ZSTDMT_resize() : + * @return : error code if fails, 0 on success */ +static size_t ZSTDMT_resize(ZSTDMT_CCtx* mtctx, unsigned nbWorkers) +{ + if (POOL_resize(mtctx->factory, nbWorkers)) return ERROR(memory_allocation); + FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) , ""); + mtctx->bufPool = ZSTDMT_expandBufferPool(mtctx->bufPool, BUF_POOL_MAX_NB_BUFFERS(nbWorkers)); + if (mtctx->bufPool == NULL) return ERROR(memory_allocation); + mtctx->cctxPool = ZSTDMT_expandCCtxPool(mtctx->cctxPool, nbWorkers); + if (mtctx->cctxPool == NULL) return ERROR(memory_allocation); + mtctx->seqPool = ZSTDMT_expandSeqPool(mtctx->seqPool, nbWorkers); + if (mtctx->seqPool == NULL) return ERROR(memory_allocation); + ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers); + return 0; +} + + +/*! ZSTDMT_updateCParams_whileCompressing() : + * Updates a selected set of compression parameters, remaining compatible with currently active frame. + * New parameters will be applied to next compression job. */ +void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_params* cctxParams) +{ + U32 const saved_wlog = mtctx->params.cParams.windowLog; /* Do not modify windowLog while compressing */ + int const compressionLevel = cctxParams->compressionLevel; + DEBUGLOG(5, "ZSTDMT_updateCParams_whileCompressing (level:%i)", + compressionLevel); + mtctx->params.compressionLevel = compressionLevel; + { ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); + cParams.windowLog = saved_wlog; + mtctx->params.cParams = cParams; + } +} + +/* ZSTDMT_getFrameProgression(): + * tells how much data has been consumed (input) and produced (output) for current frame. + * able to count progression inside worker threads. + * Note : mutex will be acquired during statistics collection inside workers. */ +ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx) +{ + ZSTD_frameProgression fps; + DEBUGLOG(5, "ZSTDMT_getFrameProgression"); + fps.ingested = mtctx->consumed + mtctx->inBuff.filled; + fps.consumed = mtctx->consumed; + fps.produced = fps.flushed = mtctx->produced; + fps.currentJobID = mtctx->nextJobID; + fps.nbActiveWorkers = 0; + { unsigned jobNb; + unsigned lastJobNb = mtctx->nextJobID + mtctx->jobReady; assert(mtctx->jobReady <= 1); + DEBUGLOG(6, "ZSTDMT_getFrameProgression: jobs: from %u to <%u (jobReady:%u)", + mtctx->doneJobID, lastJobNb, mtctx->jobReady); + for (jobNb = mtctx->doneJobID ; jobNb < lastJobNb ; jobNb++) { + unsigned const wJobID = jobNb & mtctx->jobIDMask; + ZSTDMT_jobDescription* jobPtr = &mtctx->jobs[wJobID]; + ZSTD_pthread_mutex_lock(&jobPtr->job_mutex); + { size_t const cResult = jobPtr->cSize; + size_t const produced = ZSTD_isError(cResult) ? 0 : cResult; + size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed; + assert(flushed <= produced); + fps.ingested += jobPtr->src.size; + fps.consumed += jobPtr->consumed; + fps.produced += produced; + fps.flushed += flushed; + fps.nbActiveWorkers += (jobPtr->consumed < jobPtr->src.size); + } + ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex); + } + } + return fps; +} + + +size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx) +{ + size_t toFlush; + unsigned const jobID = mtctx->doneJobID; + assert(jobID <= mtctx->nextJobID); + if (jobID == mtctx->nextJobID) return 0; /* no active job => nothing to flush */ + + /* look into oldest non-fully-flushed job */ + { unsigned const wJobID = jobID & mtctx->jobIDMask; + ZSTDMT_jobDescription* const jobPtr = &mtctx->jobs[wJobID]; + ZSTD_pthread_mutex_lock(&jobPtr->job_mutex); + { size_t const cResult = jobPtr->cSize; + size_t const produced = ZSTD_isError(cResult) ? 0 : cResult; + size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed; + assert(flushed <= produced); + assert(jobPtr->consumed <= jobPtr->src.size); + toFlush = produced - flushed; + /* if toFlush==0, nothing is available to flush. + * However, jobID is expected to still be active: + * if jobID was already completed and fully flushed, + * ZSTDMT_flushProduced() should have already moved onto next job. + * Therefore, some input has not yet been consumed. */ + if (toFlush==0) { + assert(jobPtr->consumed < jobPtr->src.size); + } + } + ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex); + } + + return toFlush; +} + + +/* ------------------------------------------ */ +/* ===== Multi-threaded compression ===== */ +/* ------------------------------------------ */ + +static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params) +{ + unsigned jobLog; + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* In Long Range Mode, the windowLog is typically oversized. + * In which case, it's preferable to determine the jobSize + * based on cycleLog instead. */ + jobLog = MAX(21, ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy) + 3); + } else { + jobLog = MAX(20, params->cParams.windowLog + 2); + } + return MIN(jobLog, (unsigned)ZSTDMT_JOBLOG_MAX); +} + +static int ZSTDMT_overlapLog_default(ZSTD_strategy strat) +{ + switch(strat) + { + case ZSTD_btultra2: + return 9; + case ZSTD_btultra: + case ZSTD_btopt: + return 8; + case ZSTD_btlazy2: + case ZSTD_lazy2: + return 7; + case ZSTD_lazy: + case ZSTD_greedy: + case ZSTD_dfast: + case ZSTD_fast: + default:; + } + return 6; +} + +static int ZSTDMT_overlapLog(int ovlog, ZSTD_strategy strat) +{ + assert(0 <= ovlog && ovlog <= 9); + if (ovlog == 0) return ZSTDMT_overlapLog_default(strat); + return ovlog; +} + +static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params) +{ + int const overlapRLog = 9 - ZSTDMT_overlapLog(params->overlapLog, params->cParams.strategy); + int ovLog = (overlapRLog >= 8) ? 0 : (params->cParams.windowLog - overlapRLog); + assert(0 <= overlapRLog && overlapRLog <= 8); + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* In Long Range Mode, the windowLog is typically oversized. + * In which case, it's preferable to determine the jobSize + * based on chainLog instead. + * Then, ovLog becomes a fraction of the jobSize, rather than windowSize */ + ovLog = MIN(params->cParams.windowLog, ZSTDMT_computeTargetJobLog(params) - 2) + - overlapRLog; + } + assert(0 <= ovLog && ovLog <= ZSTD_WINDOWLOG_MAX); + DEBUGLOG(4, "overlapLog : %i", params->overlapLog); + DEBUGLOG(4, "overlap size : %i", 1 << ovLog); + return (ovLog==0) ? 0 : (size_t)1 << ovLog; +} + +/* ====================================== */ +/* ======= Streaming API ======= */ +/* ====================================== */ + +size_t ZSTDMT_initCStream_internal( + ZSTDMT_CCtx* mtctx, + const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, + const ZSTD_CDict* cdict, ZSTD_CCtx_params params, + unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTDMT_initCStream_internal (pledgedSrcSize=%u, nbWorkers=%u, cctxPool=%u)", + (U32)pledgedSrcSize, params.nbWorkers, mtctx->cctxPool->totalCCtx); + + /* params supposed partially fully validated at this point */ + assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); + assert(!((dict) && (cdict))); /* either dict or cdict, not both */ + + /* init */ + if (params.nbWorkers != mtctx->params.nbWorkers) + FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, (unsigned)params.nbWorkers) , ""); + + if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN; + if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX; + + if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */ + ZSTDMT_waitForAllJobsCompleted(mtctx); + ZSTDMT_releaseAllJobResources(mtctx); + mtctx->allJobsCompleted = 1; + } + + mtctx->params = params; + mtctx->frameContentSize = pledgedSrcSize; + ZSTD_freeCDict(mtctx->cdictLocal); + if (dict) { + mtctx->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_dlm_byCopy, dictContentType, /* note : a loadPrefix becomes an internal CDict */ + params.cParams, mtctx->cMem); + mtctx->cdict = mtctx->cdictLocal; + if (mtctx->cdictLocal == NULL) return ERROR(memory_allocation); + } else { + mtctx->cdictLocal = NULL; + mtctx->cdict = cdict; + } + + mtctx->targetPrefixSize = ZSTDMT_computeOverlapSize(¶ms); + DEBUGLOG(4, "overlapLog=%i => %u KB", params.overlapLog, (U32)(mtctx->targetPrefixSize>>10)); + mtctx->targetSectionSize = params.jobSize; + if (mtctx->targetSectionSize == 0) { + mtctx->targetSectionSize = 1ULL << ZSTDMT_computeTargetJobLog(¶ms); + } + assert(mtctx->targetSectionSize <= (size_t)ZSTDMT_JOBSIZE_MAX); + + if (params.rsyncable) { + /* Aim for the targetsectionSize as the average job size. */ + U32 const jobSizeKB = (U32)(mtctx->targetSectionSize >> 10); + U32 const rsyncBits = (assert(jobSizeKB >= 1), ZSTD_highbit32(jobSizeKB) + 10); + /* We refuse to create jobs < RSYNC_MIN_BLOCK_SIZE bytes, so make sure our + * expected job size is at least 4x larger. */ + assert(rsyncBits >= RSYNC_MIN_BLOCK_LOG + 2); + DEBUGLOG(4, "rsyncLog = %u", rsyncBits); + mtctx->rsync.hash = 0; + mtctx->rsync.hitMask = (1ULL << rsyncBits) - 1; + mtctx->rsync.primePower = ZSTD_rollingHash_primePower(RSYNC_LENGTH); + } + if (mtctx->targetSectionSize < mtctx->targetPrefixSize) mtctx->targetSectionSize = mtctx->targetPrefixSize; /* job size must be >= overlap size */ + DEBUGLOG(4, "Job Size : %u KB (note : set to %u)", (U32)(mtctx->targetSectionSize>>10), (U32)params.jobSize); + DEBUGLOG(4, "inBuff Size : %u KB", (U32)(mtctx->targetSectionSize>>10)); + ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(mtctx->targetSectionSize)); + { + /* If ldm is enabled we need windowSize space. */ + size_t const windowSize = mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable ? (1U << mtctx->params.cParams.windowLog) : 0; + /* Two buffers of slack, plus extra space for the overlap + * This is the minimum slack that LDM works with. One extra because + * flush might waste up to targetSectionSize-1 bytes. Another extra + * for the overlap (if > 0), then one to fill which doesn't overlap + * with the LDM window. + */ + size_t const nbSlackBuffers = 2 + (mtctx->targetPrefixSize > 0); + size_t const slackSize = mtctx->targetSectionSize * nbSlackBuffers; + /* Compute the total size, and always have enough slack */ + size_t const nbWorkers = MAX(mtctx->params.nbWorkers, 1); + size_t const sectionsSize = mtctx->targetSectionSize * nbWorkers; + size_t const capacity = MAX(windowSize, sectionsSize) + slackSize; + if (mtctx->roundBuff.capacity < capacity) { + if (mtctx->roundBuff.buffer) + ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem); + mtctx->roundBuff.buffer = (BYTE*)ZSTD_customMalloc(capacity, mtctx->cMem); + if (mtctx->roundBuff.buffer == NULL) { + mtctx->roundBuff.capacity = 0; + return ERROR(memory_allocation); + } + mtctx->roundBuff.capacity = capacity; + } + } + DEBUGLOG(4, "roundBuff capacity : %u KB", (U32)(mtctx->roundBuff.capacity>>10)); + mtctx->roundBuff.pos = 0; + mtctx->inBuff.buffer = g_nullBuffer; + mtctx->inBuff.filled = 0; + mtctx->inBuff.prefix = kNullRange; + mtctx->doneJobID = 0; + mtctx->nextJobID = 0; + mtctx->frameEnded = 0; + mtctx->allJobsCompleted = 0; + mtctx->consumed = 0; + mtctx->produced = 0; + + /* update dictionary */ + ZSTD_freeCDict(mtctx->cdictLocal); + mtctx->cdictLocal = NULL; + mtctx->cdict = NULL; + if (dict) { + if (dictContentType == ZSTD_dct_rawContent) { + mtctx->inBuff.prefix.start = (const BYTE*)dict; + mtctx->inBuff.prefix.size = dictSize; + } else { + /* note : a loadPrefix becomes an internal CDict */ + mtctx->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_dlm_byRef, dictContentType, + params.cParams, mtctx->cMem); + mtctx->cdict = mtctx->cdictLocal; + if (mtctx->cdictLocal == NULL) return ERROR(memory_allocation); + } + } else { + mtctx->cdict = cdict; + } + + if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize, + dict, dictSize, dictContentType)) + return ERROR(memory_allocation); + + + return 0; +} + + +/* ZSTDMT_writeLastEmptyBlock() + * Write a single empty block with an end-of-frame to finish a frame. + * Job must be created from streaming variant. + * This function is always successful if expected conditions are fulfilled. + */ +static void ZSTDMT_writeLastEmptyBlock(ZSTDMT_jobDescription* job) +{ + assert(job->lastJob == 1); + assert(job->src.size == 0); /* last job is empty -> will be simplified into a last empty block */ + assert(job->firstJob == 0); /* cannot be first job, as it also needs to create frame header */ + assert(job->dstBuff.start == NULL); /* invoked from streaming variant only (otherwise, dstBuff might be user's output) */ + job->dstBuff = ZSTDMT_getBuffer(job->bufPool); + if (job->dstBuff.start == NULL) { + job->cSize = ERROR(memory_allocation); + return; + } + assert(job->dstBuff.capacity >= ZSTD_blockHeaderSize); /* no buffer should ever be that small */ + job->src = kNullRange; + job->cSize = ZSTD_writeLastEmptyBlock(job->dstBuff.start, job->dstBuff.capacity); + assert(!ZSTD_isError(job->cSize)); + assert(job->consumed == 0); +} + +static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* mtctx, size_t srcSize, ZSTD_EndDirective endOp) +{ + unsigned const jobID = mtctx->nextJobID & mtctx->jobIDMask; + int const endFrame = (endOp == ZSTD_e_end); + + if (mtctx->nextJobID > mtctx->doneJobID + mtctx->jobIDMask) { + DEBUGLOG(5, "ZSTDMT_createCompressionJob: will not create new job : table is full"); + assert((mtctx->nextJobID & mtctx->jobIDMask) == (mtctx->doneJobID & mtctx->jobIDMask)); + return 0; + } + + if (!mtctx->jobReady) { + BYTE const* src = (BYTE const*)mtctx->inBuff.buffer.start; + DEBUGLOG(5, "ZSTDMT_createCompressionJob: preparing job %u to compress %u bytes with %u preload ", + mtctx->nextJobID, (U32)srcSize, (U32)mtctx->inBuff.prefix.size); + mtctx->jobs[jobID].src.start = src; + mtctx->jobs[jobID].src.size = srcSize; + assert(mtctx->inBuff.filled >= srcSize); + mtctx->jobs[jobID].prefix = mtctx->inBuff.prefix; + mtctx->jobs[jobID].consumed = 0; + mtctx->jobs[jobID].cSize = 0; + mtctx->jobs[jobID].params = mtctx->params; + mtctx->jobs[jobID].cdict = mtctx->nextJobID==0 ? mtctx->cdict : NULL; + mtctx->jobs[jobID].fullFrameSize = mtctx->frameContentSize; + mtctx->jobs[jobID].dstBuff = g_nullBuffer; + mtctx->jobs[jobID].cctxPool = mtctx->cctxPool; + mtctx->jobs[jobID].bufPool = mtctx->bufPool; + mtctx->jobs[jobID].seqPool = mtctx->seqPool; + mtctx->jobs[jobID].serial = &mtctx->serial; + mtctx->jobs[jobID].jobID = mtctx->nextJobID; + mtctx->jobs[jobID].firstJob = (mtctx->nextJobID==0); + mtctx->jobs[jobID].lastJob = endFrame; + mtctx->jobs[jobID].frameChecksumNeeded = mtctx->params.fParams.checksumFlag && endFrame && (mtctx->nextJobID>0); + mtctx->jobs[jobID].dstFlushed = 0; + + /* Update the round buffer pos and clear the input buffer to be reset */ + mtctx->roundBuff.pos += srcSize; + mtctx->inBuff.buffer = g_nullBuffer; + mtctx->inBuff.filled = 0; + /* Set the prefix for next job */ + if (!endFrame) { + size_t const newPrefixSize = MIN(srcSize, mtctx->targetPrefixSize); + mtctx->inBuff.prefix.start = src + srcSize - newPrefixSize; + mtctx->inBuff.prefix.size = newPrefixSize; + } else { /* endFrame==1 => no need for another input buffer */ + mtctx->inBuff.prefix = kNullRange; + mtctx->frameEnded = endFrame; + if (mtctx->nextJobID == 0) { + /* single job exception : checksum is already calculated directly within worker thread */ + mtctx->params.fParams.checksumFlag = 0; + } } + + if ( (srcSize == 0) + && (mtctx->nextJobID>0)/*single job must also write frame header*/ ) { + DEBUGLOG(5, "ZSTDMT_createCompressionJob: creating a last empty block to end frame"); + assert(endOp == ZSTD_e_end); /* only possible case : need to end the frame with an empty last block */ + ZSTDMT_writeLastEmptyBlock(mtctx->jobs + jobID); + mtctx->nextJobID++; + return 0; + } + } + + DEBUGLOG(5, "ZSTDMT_createCompressionJob: posting job %u : %u bytes (end:%u, jobNb == %u (mod:%u))", + mtctx->nextJobID, + (U32)mtctx->jobs[jobID].src.size, + mtctx->jobs[jobID].lastJob, + mtctx->nextJobID, + jobID); + if (POOL_tryAdd(mtctx->factory, ZSTDMT_compressionJob, &mtctx->jobs[jobID])) { + mtctx->nextJobID++; + mtctx->jobReady = 0; + } else { + DEBUGLOG(5, "ZSTDMT_createCompressionJob: no worker available for job %u", mtctx->nextJobID); + mtctx->jobReady = 1; + } + return 0; +} + + +/*! ZSTDMT_flushProduced() : + * flush whatever data has been produced but not yet flushed in current job. + * move to next job if current one is fully flushed. + * `output` : `pos` will be updated with amount of data flushed . + * `blockToFlush` : if >0, the function will block and wait if there is no data available to flush . + * @return : amount of data remaining within internal buffer, 0 if no more, 1 if unknown but > 0, or an error code */ +static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, unsigned blockToFlush, ZSTD_EndDirective end) +{ + unsigned const wJobID = mtctx->doneJobID & mtctx->jobIDMask; + DEBUGLOG(5, "ZSTDMT_flushProduced (blocking:%u , job %u <= %u)", + blockToFlush, mtctx->doneJobID, mtctx->nextJobID); + assert(output->size >= output->pos); + + ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[wJobID].job_mutex); + if ( blockToFlush + && (mtctx->doneJobID < mtctx->nextJobID) ) { + assert(mtctx->jobs[wJobID].dstFlushed <= mtctx->jobs[wJobID].cSize); + while (mtctx->jobs[wJobID].dstFlushed == mtctx->jobs[wJobID].cSize) { /* nothing to flush */ + if (mtctx->jobs[wJobID].consumed == mtctx->jobs[wJobID].src.size) { + DEBUGLOG(5, "job %u is completely consumed (%u == %u) => don't wait for cond, there will be none", + mtctx->doneJobID, (U32)mtctx->jobs[wJobID].consumed, (U32)mtctx->jobs[wJobID].src.size); + break; + } + DEBUGLOG(5, "waiting for something to flush from job %u (currently flushed: %u bytes)", + mtctx->doneJobID, (U32)mtctx->jobs[wJobID].dstFlushed); + ZSTD_pthread_cond_wait(&mtctx->jobs[wJobID].job_cond, &mtctx->jobs[wJobID].job_mutex); /* block when nothing to flush but some to come */ + } } + + /* try to flush something */ + { size_t cSize = mtctx->jobs[wJobID].cSize; /* shared */ + size_t const srcConsumed = mtctx->jobs[wJobID].consumed; /* shared */ + size_t const srcSize = mtctx->jobs[wJobID].src.size; /* read-only, could be done after mutex lock, but no-declaration-after-statement */ + ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex); + if (ZSTD_isError(cSize)) { + DEBUGLOG(5, "ZSTDMT_flushProduced: job %u : compression error detected : %s", + mtctx->doneJobID, ZSTD_getErrorName(cSize)); + ZSTDMT_waitForAllJobsCompleted(mtctx); + ZSTDMT_releaseAllJobResources(mtctx); + return cSize; + } + /* add frame checksum if necessary (can only happen once) */ + assert(srcConsumed <= srcSize); + if ( (srcConsumed == srcSize) /* job completed -> worker no longer active */ + && mtctx->jobs[wJobID].frameChecksumNeeded ) { + U32 const checksum = (U32)XXH64_digest(&mtctx->serial.xxhState); + DEBUGLOG(4, "ZSTDMT_flushProduced: writing checksum : %08X \n", checksum); + MEM_writeLE32((char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].cSize, checksum); + cSize += 4; + mtctx->jobs[wJobID].cSize += 4; /* can write this shared value, as worker is no longer active */ + mtctx->jobs[wJobID].frameChecksumNeeded = 0; + } + + if (cSize > 0) { /* compression is ongoing or completed */ + size_t const toFlush = MIN(cSize - mtctx->jobs[wJobID].dstFlushed, output->size - output->pos); + DEBUGLOG(5, "ZSTDMT_flushProduced: Flushing %u bytes from job %u (completion:%u/%u, generated:%u)", + (U32)toFlush, mtctx->doneJobID, (U32)srcConsumed, (U32)srcSize, (U32)cSize); + assert(mtctx->doneJobID < mtctx->nextJobID); + assert(cSize >= mtctx->jobs[wJobID].dstFlushed); + assert(mtctx->jobs[wJobID].dstBuff.start != NULL); + if (toFlush > 0) { + ZSTD_memcpy((char*)output->dst + output->pos, + (const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed, + toFlush); + } + output->pos += toFlush; + mtctx->jobs[wJobID].dstFlushed += toFlush; /* can write : this value is only used by mtctx */ + + if ( (srcConsumed == srcSize) /* job is completed */ + && (mtctx->jobs[wJobID].dstFlushed == cSize) ) { /* output buffer fully flushed => free this job position */ + DEBUGLOG(5, "Job %u completed (%u bytes), moving to next one", + mtctx->doneJobID, (U32)mtctx->jobs[wJobID].dstFlushed); + ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[wJobID].dstBuff); + DEBUGLOG(5, "dstBuffer released"); + mtctx->jobs[wJobID].dstBuff = g_nullBuffer; + mtctx->jobs[wJobID].cSize = 0; /* ensure this job slot is considered "not started" in future check */ + mtctx->consumed += srcSize; + mtctx->produced += cSize; + mtctx->doneJobID++; + } } + + /* return value : how many bytes left in buffer ; fake it to 1 when unknown but >0 */ + if (cSize > mtctx->jobs[wJobID].dstFlushed) return (cSize - mtctx->jobs[wJobID].dstFlushed); + if (srcSize > srcConsumed) return 1; /* current job not completely compressed */ + } + if (mtctx->doneJobID < mtctx->nextJobID) return 1; /* some more jobs ongoing */ + if (mtctx->jobReady) return 1; /* one job is ready to push, just not yet in the list */ + if (mtctx->inBuff.filled > 0) return 1; /* input is not empty, and still needs to be converted into a job */ + mtctx->allJobsCompleted = mtctx->frameEnded; /* all jobs are entirely flushed => if this one is last one, frame is completed */ + if (end == ZSTD_e_end) return !mtctx->frameEnded; /* for ZSTD_e_end, question becomes : is frame completed ? instead of : are internal buffers fully flushed ? */ + return 0; /* internal buffers fully flushed */ +} + +/** + * Returns the range of data used by the earliest job that is not yet complete. + * If the data of the first job is broken up into two segments, we cover both + * sections. + */ +static Range ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx) +{ + unsigned const firstJobID = mtctx->doneJobID; + unsigned const lastJobID = mtctx->nextJobID; + unsigned jobID; + + /* no need to check during first round */ + size_t roundBuffCapacity = mtctx->roundBuff.capacity; + size_t nbJobs1stRoundMin = roundBuffCapacity / mtctx->targetSectionSize; + if (lastJobID < nbJobs1stRoundMin) return kNullRange; + + for (jobID = firstJobID; jobID < lastJobID; ++jobID) { + unsigned const wJobID = jobID & mtctx->jobIDMask; + size_t consumed; + + ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[wJobID].job_mutex); + consumed = mtctx->jobs[wJobID].consumed; + ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex); + + if (consumed < mtctx->jobs[wJobID].src.size) { + Range range = mtctx->jobs[wJobID].prefix; + if (range.size == 0) { + /* Empty prefix */ + range = mtctx->jobs[wJobID].src; + } + /* Job source in multiple segments not supported yet */ + assert(range.start <= mtctx->jobs[wJobID].src.start); + return range; + } + } + return kNullRange; +} + +/** + * Returns non-zero iff buffer and range overlap. + */ +static int ZSTDMT_isOverlapped(Buffer buffer, Range range) +{ + BYTE const* const bufferStart = (BYTE const*)buffer.start; + BYTE const* const rangeStart = (BYTE const*)range.start; + + if (rangeStart == NULL || bufferStart == NULL) + return 0; + + { + BYTE const* const bufferEnd = bufferStart + buffer.capacity; + BYTE const* const rangeEnd = rangeStart + range.size; + + /* Empty ranges cannot overlap */ + if (bufferStart == bufferEnd || rangeStart == rangeEnd) + return 0; + + return bufferStart < rangeEnd && rangeStart < bufferEnd; + } +} + +static int ZSTDMT_doesOverlapWindow(Buffer buffer, ZSTD_window_t window) +{ + Range extDict; + Range prefix; + + DEBUGLOG(5, "ZSTDMT_doesOverlapWindow"); + extDict.start = window.dictBase + window.lowLimit; + extDict.size = window.dictLimit - window.lowLimit; + + prefix.start = window.base + window.dictLimit; + prefix.size = window.nextSrc - (window.base + window.dictLimit); + DEBUGLOG(5, "extDict [0x%zx, 0x%zx)", + (size_t)extDict.start, + (size_t)extDict.start + extDict.size); + DEBUGLOG(5, "prefix [0x%zx, 0x%zx)", + (size_t)prefix.start, + (size_t)prefix.start + prefix.size); + + return ZSTDMT_isOverlapped(buffer, extDict) + || ZSTDMT_isOverlapped(buffer, prefix); +} + +static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, Buffer buffer) +{ + if (mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable) { + ZSTD_pthread_mutex_t* mutex = &mtctx->serial.ldmWindowMutex; + DEBUGLOG(5, "ZSTDMT_waitForLdmComplete"); + DEBUGLOG(5, "source [0x%zx, 0x%zx)", + (size_t)buffer.start, + (size_t)buffer.start + buffer.capacity); + ZSTD_PTHREAD_MUTEX_LOCK(mutex); + while (ZSTDMT_doesOverlapWindow(buffer, mtctx->serial.ldmWindow)) { + DEBUGLOG(5, "Waiting for LDM to finish..."); + ZSTD_pthread_cond_wait(&mtctx->serial.ldmWindowCond, mutex); + } + DEBUGLOG(6, "Done waiting for LDM to finish"); + ZSTD_pthread_mutex_unlock(mutex); + } +} + +/** + * Attempts to set the inBuff to the next section to fill. + * If any part of the new section is still in use we give up. + * Returns non-zero if the buffer is filled. + */ +static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx) +{ + Range const inUse = ZSTDMT_getInputDataInUse(mtctx); + size_t const spaceLeft = mtctx->roundBuff.capacity - mtctx->roundBuff.pos; + size_t const spaceNeeded = mtctx->targetSectionSize; + Buffer buffer; + + DEBUGLOG(5, "ZSTDMT_tryGetInputRange"); + assert(mtctx->inBuff.buffer.start == NULL); + assert(mtctx->roundBuff.capacity >= spaceNeeded); + + if (spaceLeft < spaceNeeded) { + /* ZSTD_invalidateRepCodes() doesn't work for extDict variants. + * Simply copy the prefix to the beginning in that case. + */ + BYTE* const start = (BYTE*)mtctx->roundBuff.buffer; + size_t const prefixSize = mtctx->inBuff.prefix.size; + + buffer.start = start; + buffer.capacity = prefixSize; + if (ZSTDMT_isOverlapped(buffer, inUse)) { + DEBUGLOG(5, "Waiting for buffer..."); + return 0; + } + ZSTDMT_waitForLdmComplete(mtctx, buffer); + ZSTD_memmove(start, mtctx->inBuff.prefix.start, prefixSize); + mtctx->inBuff.prefix.start = start; + mtctx->roundBuff.pos = prefixSize; + } + buffer.start = mtctx->roundBuff.buffer + mtctx->roundBuff.pos; + buffer.capacity = spaceNeeded; + + if (ZSTDMT_isOverlapped(buffer, inUse)) { + DEBUGLOG(5, "Waiting for buffer..."); + return 0; + } + assert(!ZSTDMT_isOverlapped(buffer, mtctx->inBuff.prefix)); + + ZSTDMT_waitForLdmComplete(mtctx, buffer); + + DEBUGLOG(5, "Using prefix range [%zx, %zx)", + (size_t)mtctx->inBuff.prefix.start, + (size_t)mtctx->inBuff.prefix.start + mtctx->inBuff.prefix.size); + DEBUGLOG(5, "Using source range [%zx, %zx)", + (size_t)buffer.start, + (size_t)buffer.start + buffer.capacity); + + + mtctx->inBuff.buffer = buffer; + mtctx->inBuff.filled = 0; + assert(mtctx->roundBuff.pos + buffer.capacity <= mtctx->roundBuff.capacity); + return 1; +} + +typedef struct { + size_t toLoad; /* The number of bytes to load from the input. */ + int flush; /* Boolean declaring if we must flush because we found a synchronization point. */ +} SyncPoint; + +/** + * Searches through the input for a synchronization point. If one is found, we + * will instruct the caller to flush, and return the number of bytes to load. + * Otherwise, we will load as many bytes as possible and instruct the caller + * to continue as normal. + */ +static SyncPoint +findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input) +{ + BYTE const* const istart = (BYTE const*)input.src + input.pos; + U64 const primePower = mtctx->rsync.primePower; + U64 const hitMask = mtctx->rsync.hitMask; + + SyncPoint syncPoint; + U64 hash; + BYTE const* prev; + size_t pos; + + syncPoint.toLoad = MIN(input.size - input.pos, mtctx->targetSectionSize - mtctx->inBuff.filled); + syncPoint.flush = 0; + if (!mtctx->params.rsyncable) + /* Rsync is disabled. */ + return syncPoint; + if (mtctx->inBuff.filled + input.size - input.pos < RSYNC_MIN_BLOCK_SIZE) + /* We don't emit synchronization points if it would produce too small blocks. + * We don't have enough input to find a synchronization point, so don't look. + */ + return syncPoint; + if (mtctx->inBuff.filled + syncPoint.toLoad < RSYNC_LENGTH) + /* Not enough to compute the hash. + * We will miss any synchronization points in this RSYNC_LENGTH byte + * window. However, since it depends only in the internal buffers, if the + * state is already synchronized, we will remain synchronized. + * Additionally, the probability that we miss a synchronization point is + * low: RSYNC_LENGTH / targetSectionSize. + */ + return syncPoint; + /* Initialize the loop variables. */ + if (mtctx->inBuff.filled < RSYNC_MIN_BLOCK_SIZE) { + /* We don't need to scan the first RSYNC_MIN_BLOCK_SIZE positions + * because they can't possibly be a sync point. So we can start + * part way through the input buffer. + */ + pos = RSYNC_MIN_BLOCK_SIZE - mtctx->inBuff.filled; + if (pos >= RSYNC_LENGTH) { + prev = istart + pos - RSYNC_LENGTH; + hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH); + } else { + assert(mtctx->inBuff.filled >= RSYNC_LENGTH); + prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH; + hash = ZSTD_rollingHash_compute(prev + pos, (RSYNC_LENGTH - pos)); + hash = ZSTD_rollingHash_append(hash, istart, pos); + } + } else { + /* We have enough bytes buffered to initialize the hash, + * and have processed enough bytes to find a sync point. + * Start scanning at the beginning of the input. + */ + assert(mtctx->inBuff.filled >= RSYNC_MIN_BLOCK_SIZE); + assert(RSYNC_MIN_BLOCK_SIZE >= RSYNC_LENGTH); + pos = 0; + prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH; + hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH); + if ((hash & hitMask) == hitMask) { + /* We're already at a sync point so don't load any more until + * we're able to flush this sync point. + * This likely happened because the job table was full so we + * couldn't add our job. + */ + syncPoint.toLoad = 0; + syncPoint.flush = 1; + return syncPoint; + } + } + /* Starting with the hash of the previous RSYNC_LENGTH bytes, roll + * through the input. If we hit a synchronization point, then cut the + * job off, and tell the compressor to flush the job. Otherwise, load + * all the bytes and continue as normal. + * If we go too long without a synchronization point (targetSectionSize) + * then a block will be emitted anyways, but this is okay, since if we + * are already synchronized we will remain synchronized. + */ + assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash); + for (; pos < syncPoint.toLoad; ++pos) { + BYTE const toRemove = pos < RSYNC_LENGTH ? prev[pos] : istart[pos - RSYNC_LENGTH]; + /* This assert is very expensive, and Debian compiles with asserts enabled. + * So disable it for now. We can get similar coverage by checking it at the + * beginning & end of the loop. + * assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash); + */ + hash = ZSTD_rollingHash_rotate(hash, toRemove, istart[pos], primePower); + assert(mtctx->inBuff.filled + pos >= RSYNC_MIN_BLOCK_SIZE); + if ((hash & hitMask) == hitMask) { + syncPoint.toLoad = pos + 1; + syncPoint.flush = 1; + ++pos; /* for assert */ + break; + } + } + assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash); + return syncPoint; +} + +size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx) +{ + size_t hintInSize = mtctx->targetSectionSize - mtctx->inBuff.filled; + if (hintInSize==0) hintInSize = mtctx->targetSectionSize; + return hintInSize; +} + +/** ZSTDMT_compressStream_generic() : + * internal use only - exposed to be invoked from zstd_compress.c + * assumption : output and input are valid (pos <= size) + * @return : minimum amount of data remaining to flush, 0 if none */ +size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp) +{ + unsigned forwardInputProgress = 0; + DEBUGLOG(5, "ZSTDMT_compressStream_generic (endOp=%u, srcSize=%u)", + (U32)endOp, (U32)(input->size - input->pos)); + assert(output->pos <= output->size); + assert(input->pos <= input->size); + + if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) { + /* current frame being ended. Only flush/end are allowed */ + return ERROR(stage_wrong); + } + + /* fill input buffer */ + if ( (!mtctx->jobReady) + && (input->size > input->pos) ) { /* support NULL input */ + if (mtctx->inBuff.buffer.start == NULL) { + assert(mtctx->inBuff.filled == 0); /* Can't fill an empty buffer */ + if (!ZSTDMT_tryGetInputRange(mtctx)) { + /* It is only possible for this operation to fail if there are + * still compression jobs ongoing. + */ + DEBUGLOG(5, "ZSTDMT_tryGetInputRange failed"); + assert(mtctx->doneJobID != mtctx->nextJobID); + } else + DEBUGLOG(5, "ZSTDMT_tryGetInputRange completed successfully : mtctx->inBuff.buffer.start = %p", mtctx->inBuff.buffer.start); + } + if (mtctx->inBuff.buffer.start != NULL) { + SyncPoint const syncPoint = findSynchronizationPoint(mtctx, *input); + if (syncPoint.flush && endOp == ZSTD_e_continue) { + endOp = ZSTD_e_flush; + } + assert(mtctx->inBuff.buffer.capacity >= mtctx->targetSectionSize); + DEBUGLOG(5, "ZSTDMT_compressStream_generic: adding %u bytes on top of %u to buffer of size %u", + (U32)syncPoint.toLoad, (U32)mtctx->inBuff.filled, (U32)mtctx->targetSectionSize); + ZSTD_memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, syncPoint.toLoad); + input->pos += syncPoint.toLoad; + mtctx->inBuff.filled += syncPoint.toLoad; + forwardInputProgress = syncPoint.toLoad>0; + } + } + if ((input->pos < input->size) && (endOp == ZSTD_e_end)) { + /* Can't end yet because the input is not fully consumed. + * We are in one of these cases: + * - mtctx->inBuff is NULL & empty: we couldn't get an input buffer so don't create a new job. + * - We filled the input buffer: flush this job but don't end the frame. + * - We hit a synchronization point: flush this job but don't end the frame. + */ + assert(mtctx->inBuff.filled == 0 || mtctx->inBuff.filled == mtctx->targetSectionSize || mtctx->params.rsyncable); + endOp = ZSTD_e_flush; + } + + if ( (mtctx->jobReady) + || (mtctx->inBuff.filled >= mtctx->targetSectionSize) /* filled enough : let's compress */ + || ((endOp != ZSTD_e_continue) && (mtctx->inBuff.filled > 0)) /* something to flush : let's go */ + || ((endOp == ZSTD_e_end) && (!mtctx->frameEnded)) ) { /* must finish the frame with a zero-size block */ + size_t const jobSize = mtctx->inBuff.filled; + assert(mtctx->inBuff.filled <= mtctx->targetSectionSize); + FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp) , ""); + } + + /* check for potential compressed data ready to be flushed */ + { size_t const remainingToFlush = ZSTDMT_flushProduced(mtctx, output, !forwardInputProgress, endOp); /* block if there was no forward input progress */ + if (input->pos < input->size) return MAX(remainingToFlush, 1); /* input not consumed : do not end flush yet */ + DEBUGLOG(5, "end of ZSTDMT_compressStream_generic: remainingToFlush = %u", (U32)remainingToFlush); + return remainingToFlush; + } +} diff --git a/cpp/third_party/zstd-1.5.7/lib/compress/zstdmt_compress.h b/cpp/third_party/zstd-1.5.7/lib/compress/zstdmt_compress.h new file mode 100644 index 000000000..91b489b9c --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/compress/zstdmt_compress.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + #ifndef ZSTDMT_COMPRESS_H + #define ZSTDMT_COMPRESS_H + +/* === Dependencies === */ +#include "../common/zstd_deps.h" /* size_t */ +#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */ +#include "../zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */ + +/* Note : This is an internal API. + * These APIs used to be exposed with ZSTDLIB_API, + * because it used to be the only way to invoke MT compression. + * Now, you must use ZSTD_compress2 and ZSTD_compressStream2() instead. + * + * This API requires ZSTD_MULTITHREAD to be defined during compilation, + * otherwise ZSTDMT_createCCtx*() will fail. + */ + +/* === Constants === */ +#ifndef ZSTDMT_NBWORKERS_MAX /* a different value can be selected at compile time */ +# define ZSTDMT_NBWORKERS_MAX ((sizeof(void*)==4) /*32-bit*/ ? 64 : 256) +#endif +#ifndef ZSTDMT_JOBSIZE_MIN /* a different value can be selected at compile time */ +# define ZSTDMT_JOBSIZE_MIN (512 KB) +#endif +#define ZSTDMT_JOBLOG_MAX (MEM_32bits() ? 29 : 30) +#define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB)) + + +/* ======================================================== + * === Private interface, for use by ZSTD_compress.c === + * === Not exposed in libzstd. Never invoke directly === + * ======================================================== */ + +/* === Memory management === */ +typedef struct ZSTDMT_CCtx_s ZSTDMT_CCtx; +/* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */ +ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, + ZSTD_customMem cMem, + ZSTD_threadPool *pool); +size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx); + +size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx); + +/* === Streaming functions === */ + +size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx); + +/*! ZSTDMT_initCStream_internal() : + * Private use only. Init streaming operation. + * expects params to be valid. + * must receive dict, or cdict, or none, but not both. + * mtctx can be freshly constructed or reused from a prior compression. + * If mtctx is reused, memory allocations from the prior compression may not be freed, + * even if they are not needed for the current compression. + * @return : 0, or an error code */ +size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* mtctx, + const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, + const ZSTD_CDict* cdict, + ZSTD_CCtx_params params, unsigned long long pledgedSrcSize); + +/*! ZSTDMT_compressStream_generic() : + * Combines ZSTDMT_compressStream() with optional ZSTDMT_flushStream() or ZSTDMT_endStream() + * depending on flush directive. + * @return : minimum amount of data still to be flushed + * 0 if fully flushed + * or an error code + * note : needs to be init using any ZSTD_initCStream*() variant */ +size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp); + + /*! ZSTDMT_toFlushNow() + * Tell how many bytes are ready to be flushed immediately. + * Probe the oldest active job (not yet entirely flushed) and check its output buffer. + * If return 0, it means there is no active job, + * or, it means oldest job is still active, but everything produced has been flushed so far, + * therefore flushing is limited by speed of oldest job. */ +size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx); + +/*! ZSTDMT_updateCParams_whileCompressing() : + * Updates only a selected set of compression parameters, to remain compatible with current frame. + * New parameters will be applied to next compression job. */ +void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_params* cctxParams); + +/*! ZSTDMT_getFrameProgression(): + * tells how much data has been consumed (input) and produced (output) for current frame. + * able to count progression inside worker threads. + */ +ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx); + +#endif /* ZSTDMT_COMPRESS_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/decompress/huf_decompress.c b/cpp/third_party/zstd-1.5.7/lib/decompress/huf_decompress.c new file mode 100644 index 000000000..f85dd0bee --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/decompress/huf_decompress.c @@ -0,0 +1,1944 @@ +/* ****************************************************************** + * huff0 huffman decoder, + * part of Finite State Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Dependencies +****************************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */ +#include "../common/compiler.h" +#include "../common/bitstream.h" /* BIT_* */ +#include "../common/fse.h" /* to compress headers */ +#include "../common/huf.h" +#include "../common/error_private.h" +#include "../common/zstd_internal.h" +#include "../common/bits.h" /* ZSTD_highbit32, ZSTD_countTrailingZeros64 */ + +/* ************************************************************** +* Constants +****************************************************************/ + +#define HUF_DECODER_FAST_TABLELOG 11 + +/* ************************************************************** +* Macros +****************************************************************/ + +#ifdef HUF_DISABLE_FAST_DECODE +# define HUF_ENABLE_FAST_DECODE 0 +#else +# define HUF_ENABLE_FAST_DECODE 1 +#endif + +/* These two optional macros force the use one way or another of the two + * Huffman decompression implementations. You can't force in both directions + * at the same time. + */ +#if defined(HUF_FORCE_DECOMPRESS_X1) && \ + defined(HUF_FORCE_DECOMPRESS_X2) +#error "Cannot force the use of the X1 and X2 decoders at the same time!" +#endif + +/* When DYNAMIC_BMI2 is enabled, fast decoders are only called when bmi2 is + * supported at runtime, so we can add the BMI2 target attribute. + * When it is disabled, we will still get BMI2 if it is enabled statically. + */ +#if DYNAMIC_BMI2 +# define HUF_FAST_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE +#else +# define HUF_FAST_BMI2_ATTRS +#endif + +#ifdef __cplusplus +# define HUF_EXTERN_C extern "C" +#else +# define HUF_EXTERN_C +#endif +#define HUF_ASM_DECL HUF_EXTERN_C + +#if DYNAMIC_BMI2 +# define HUF_NEED_BMI2_FUNCTION 1 +#else +# define HUF_NEED_BMI2_FUNCTION 0 +#endif + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_isError ERR_isError + + +/* ************************************************************** +* Byte alignment for workSpace management +****************************************************************/ +#define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1) +#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) + + +/* ************************************************************** +* BMI2 Variant Wrappers +****************************************************************/ +typedef size_t (*HUF_DecompressUsingDTableFn)(void *dst, size_t dstSize, + const void *cSrc, + size_t cSrcSize, + const HUF_DTable *DTable); + +#if DYNAMIC_BMI2 + +#define HUF_DGEN(fn) \ + \ + static size_t fn##_default( \ + void* dst, size_t dstSize, \ + const void* cSrc, size_t cSrcSize, \ + const HUF_DTable* DTable) \ + { \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + \ + static BMI2_TARGET_ATTRIBUTE size_t fn##_bmi2( \ + void* dst, size_t dstSize, \ + const void* cSrc, size_t cSrcSize, \ + const HUF_DTable* DTable) \ + { \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + \ + static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ + size_t cSrcSize, HUF_DTable const* DTable, int flags) \ + { \ + if (flags & HUF_flags_bmi2) { \ + return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable); \ + } + +#else + +#define HUF_DGEN(fn) \ + static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ + size_t cSrcSize, HUF_DTable const* DTable, int flags) \ + { \ + (void)flags; \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } + +#endif + + +/*-***************************/ +/* generic DTableDesc */ +/*-***************************/ +typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc; + +static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) +{ + DTableDesc dtd; + ZSTD_memcpy(&dtd, table, sizeof(dtd)); + return dtd; +} + +static size_t HUF_initFastDStream(BYTE const* ip) { + BYTE const lastByte = ip[7]; + size_t const bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; + size_t const value = MEM_readLEST(ip) | 1; + assert(bitsConsumed <= 8); + assert(sizeof(size_t) == 8); + return value << bitsConsumed; +} + + +/** + * The input/output arguments to the Huffman fast decoding loop: + * + * ip [in/out] - The input pointers, must be updated to reflect what is consumed. + * op [in/out] - The output pointers, must be updated to reflect what is written. + * bits [in/out] - The bitstream containers, must be updated to reflect the current state. + * dt [in] - The decoding table. + * ilowest [in] - The beginning of the valid range of the input. Decoders may read + * down to this pointer. It may be below iend[0]. + * oend [in] - The end of the output stream. op[3] must not cross oend. + * iend [in] - The end of each input stream. ip[i] may cross iend[i], + * as long as it is above ilowest, but that indicates corruption. + */ +typedef struct { + BYTE const* ip[4]; + BYTE* op[4]; + U64 bits[4]; + void const* dt; + BYTE const* ilowest; + BYTE* oend; + BYTE const* iend[4]; +} HUF_DecompressFastArgs; + +typedef void (*HUF_DecompressFastLoopFn)(HUF_DecompressFastArgs*); + +/** + * Initializes args for the fast decoding loop. + * @returns 1 on success + * 0 if the fallback implementation should be used. + * Or an error code on failure. + */ +static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* dst, size_t dstSize, void const* src, size_t srcSize, const HUF_DTable* DTable) +{ + void const* dt = DTable + 1; + U32 const dtLog = HUF_getDTableDesc(DTable).tableLog; + + const BYTE* const istart = (const BYTE*)src; + + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + + /* The fast decoding loop assumes 64-bit little-endian. + * This condition is false on x32. + */ + if (!MEM_isLittleEndian() || MEM_32bits()) + return 0; + + /* Avoid nullptr addition */ + if (dstSize == 0) + return 0; + assert(dst != NULL); + + /* strict minimum : jump table + 1 byte per stream */ + if (srcSize < 10) + return ERROR(corruption_detected); + + /* Must have at least 8 bytes per stream because we don't handle initializing smaller bit containers. + * If table log is not correct at this point, fallback to the old decoder. + * On small inputs we don't have enough data to trigger the fast loop, so use the old decoder. + */ + if (dtLog != HUF_DECODER_FAST_TABLELOG) + return 0; + + /* Read the jump table. */ + { + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = srcSize - (length1 + length2 + length3 + 6); + args->iend[0] = istart + 6; /* jumpTable */ + args->iend[1] = args->iend[0] + length1; + args->iend[2] = args->iend[1] + length2; + args->iend[3] = args->iend[2] + length3; + + /* HUF_initFastDStream() requires this, and this small of an input + * won't benefit from the ASM loop anyways. + */ + if (length1 < 8 || length2 < 8 || length3 < 8 || length4 < 8) + return 0; + if (length4 > srcSize) return ERROR(corruption_detected); /* overflow */ + } + /* ip[] contains the position that is currently loaded into bits[]. */ + args->ip[0] = args->iend[1] - sizeof(U64); + args->ip[1] = args->iend[2] - sizeof(U64); + args->ip[2] = args->iend[3] - sizeof(U64); + args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64); + + /* op[] contains the output pointers. */ + args->op[0] = (BYTE*)dst; + args->op[1] = args->op[0] + (dstSize+3)/4; + args->op[2] = args->op[1] + (dstSize+3)/4; + args->op[3] = args->op[2] + (dstSize+3)/4; + + /* No point to call the ASM loop for tiny outputs. */ + if (args->op[3] >= oend) + return 0; + + /* bits[] is the bit container. + * It is read from the MSB down to the LSB. + * It is shifted left as it is read, and zeros are + * shifted in. After the lowest valid bit a 1 is + * set, so that CountTrailingZeros(bits[]) can be used + * to count how many bits we've consumed. + */ + args->bits[0] = HUF_initFastDStream(args->ip[0]); + args->bits[1] = HUF_initFastDStream(args->ip[1]); + args->bits[2] = HUF_initFastDStream(args->ip[2]); + args->bits[3] = HUF_initFastDStream(args->ip[3]); + + /* The decoders must be sure to never read beyond ilowest. + * This is lower than iend[0], but allowing decoders to read + * down to ilowest can allow an extra iteration or two in the + * fast loop. + */ + args->ilowest = istart; + + args->oend = oend; + args->dt = dt; + + return 1; +} + +static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressFastArgs const* args, int stream, BYTE* segmentEnd) +{ + /* Validate that we haven't overwritten. */ + if (args->op[stream] > segmentEnd) + return ERROR(corruption_detected); + /* Validate that we haven't read beyond iend[]. + * Note that ip[] may be < iend[] because the MSB is + * the next bit to read, and we may have consumed 100% + * of the stream, so down to iend[i] - 8 is valid. + */ + if (args->ip[stream] < args->iend[stream] - 8) + return ERROR(corruption_detected); + + /* Construct the BIT_DStream_t. */ + assert(sizeof(size_t) == 8); + bit->bitContainer = MEM_readLEST(args->ip[stream]); + bit->bitsConsumed = ZSTD_countTrailingZeros64(args->bits[stream]); + bit->start = (const char*)args->ilowest; + bit->limitPtr = bit->start + sizeof(size_t); + bit->ptr = (const char*)args->ip[stream]; + + return 0; +} + +/* Calls X(N) for each stream 0, 1, 2, 3. */ +#define HUF_4X_FOR_EACH_STREAM(X) \ + do { \ + X(0); \ + X(1); \ + X(2); \ + X(3); \ + } while (0) + +/* Calls X(N, var) for each stream 0, 1, 2, 3. */ +#define HUF_4X_FOR_EACH_STREAM_WITH_VAR(X, var) \ + do { \ + X(0, (var)); \ + X(1, (var)); \ + X(2, (var)); \ + X(3, (var)); \ + } while (0) + + +#ifndef HUF_FORCE_DECOMPRESS_X2 + +/*-***************************/ +/* single-symbol decoding */ +/*-***************************/ +typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1; /* single-symbol decoding */ + +/** + * Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at + * a time. + */ +static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) { + U64 D4; + if (MEM_isLittleEndian()) { + D4 = (U64)((symbol << 8) + nbBits); + } else { + D4 = (U64)(symbol + (nbBits << 8)); + } + assert(D4 < (1U << 16)); + D4 *= 0x0001000100010001ULL; + return D4; +} + +/** + * Increase the tableLog to targetTableLog and rescales the stats. + * If tableLog > targetTableLog this is a no-op. + * @returns New tableLog + */ +static U32 HUF_rescaleStats(BYTE* huffWeight, U32* rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog) +{ + if (tableLog > targetTableLog) + return tableLog; + if (tableLog < targetTableLog) { + U32 const scale = targetTableLog - tableLog; + U32 s; + /* Increase the weight for all non-zero probability symbols by scale. */ + for (s = 0; s < nbSymbols; ++s) { + huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale); + } + /* Update rankVal to reflect the new weights. + * All weights except 0 get moved to weight + scale. + * Weights [1, scale] are empty. + */ + for (s = targetTableLog; s > scale; --s) { + rankVal[s] = rankVal[s - scale]; + } + for (s = scale; s > 0; --s) { + rankVal[s] = 0; + } + } + return targetTableLog; +} + +typedef struct { + U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; + BYTE symbols[HUF_SYMBOLVALUE_MAX + 1]; + BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; +} HUF_ReadDTableX1_Workspace; + +size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags) +{ + U32 tableLog = 0; + U32 nbSymbols = 0; + size_t iSize; + void* const dtPtr = DTable + 1; + HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr; + HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace; + + DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp)); + if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge); + + DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); + /* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), flags); + if (HUF_isError(iSize)) return iSize; + + + /* Table header */ + { DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 const maxTableLog = dtd.maxTableLog + 1; + U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG); + tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog); + if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */ + dtd.tableType = 0; + dtd.tableLog = (BYTE)tableLog; + ZSTD_memcpy(DTable, &dtd, sizeof(dtd)); + } + + /* Compute symbols and rankStart given rankVal: + * + * rankVal already contains the number of values of each weight. + * + * symbols contains the symbols ordered by weight. First are the rankVal[0] + * weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on. + * symbols[0] is filled (but unused) to avoid a branch. + * + * rankStart contains the offset where each rank belongs in the DTable. + * rankStart[0] is not filled because there are no entries in the table for + * weight 0. + */ + { int n; + U32 nextRankStart = 0; + int const unroll = 4; + int const nLimit = (int)nbSymbols - unroll + 1; + for (n=0; n<(int)tableLog+1; n++) { + U32 const curr = nextRankStart; + nextRankStart += wksp->rankVal[n]; + wksp->rankStart[n] = curr; + } + for (n=0; n < nLimit; n += unroll) { + int u; + for (u=0; u < unroll; ++u) { + size_t const w = wksp->huffWeight[n+u]; + wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u); + } + } + for (; n < (int)nbSymbols; ++n) { + size_t const w = wksp->huffWeight[n]; + wksp->symbols[wksp->rankStart[w]++] = (BYTE)n; + } + } + + /* fill DTable + * We fill all entries of each weight in order. + * That way length is a constant for each iteration of the outer loop. + * We can switch based on the length to a different inner loop which is + * optimized for that particular case. + */ + { U32 w; + int symbol = wksp->rankVal[0]; + int rankStart = 0; + for (w=1; wrankVal[w]; + int const length = (1 << w) >> 1; + int uStart = rankStart; + BYTE const nbBits = (BYTE)(tableLog + 1 - w); + int s; + int u; + switch (length) { + case 1: + for (s=0; ssymbols[symbol + s]; + D.nbBits = nbBits; + dt[uStart] = D; + uStart += 1; + } + break; + case 2: + for (s=0; ssymbols[symbol + s]; + D.nbBits = nbBits; + dt[uStart+0] = D; + dt[uStart+1] = D; + uStart += 2; + } + break; + case 4: + for (s=0; ssymbols[symbol + s], nbBits); + MEM_write64(dt + uStart, D4); + uStart += 4; + } + break; + case 8: + for (s=0; ssymbols[symbol + s], nbBits); + MEM_write64(dt + uStart, D4); + MEM_write64(dt + uStart + 4, D4); + uStart += 8; + } + break; + default: + for (s=0; ssymbols[symbol + s], nbBits); + for (u=0; u < length; u += 16) { + MEM_write64(dt + uStart + u + 0, D4); + MEM_write64(dt + uStart + u + 4, D4); + MEM_write64(dt + uStart + u + 8, D4); + MEM_write64(dt + uStart + u + 12, D4); + } + assert(u == length); + uStart += length; + } + break; + } + symbol += symbolCount; + rankStart += symbolCount * length; + } + } + return iSize; +} + +FORCE_INLINE_TEMPLATE BYTE +HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ + BYTE const c = dt[val].byte; + BIT_skipBits(Dstream, dt[val].nbBits); + return c; +} + +#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \ + do { *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog); } while (0) + +#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \ + } while (0) + +#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits()) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \ + } while (0) + +HINT_INLINE size_t +HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 4 symbols at a time */ + if ((pEnd - p) > 3) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) { + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_1(p, bitDPtr); + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + } + } else { + BIT_reloadDStream(bitDPtr); + } + + /* [0-3] symbols remaining */ + if (MEM_32bits()) + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd)) + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + + /* no more data to retrieve from bitstream, no need to reload */ + while (p < pEnd) + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + + return (size_t)(pEnd-pStart); +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress1X1_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + BYTE* op = (BYTE*)dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(op, dstSize); + const void* dtPtr = DTable + 1; + const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; + BIT_DStream_t bitD; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); + + HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog); + + if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); + + return dstSize; +} + +/* HUF_decompress4X1_usingDTable_internal_body(): + * Conditions : + * @dstSize >= 6 + */ +FORCE_INLINE_TEMPLATE size_t +HUF_decompress4X1_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + /* Check */ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ + + { const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* const olimit = oend - 3; + const void* const dtPtr = DTable + 1; + const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + const size_t segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + U32 endSignal = 1; + + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ + assert(dstSize >= 6); /* validated above */ + CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); + CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); + CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); + CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); + + /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */ + if ((size_t)(oend - op4) >= sizeof(size_t)) { + for ( ; (endSignal) & (op4 < olimit) ; ) { + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_1(op1, &bitD1); + HUF_DECODE_SYMBOLX1_1(op2, &bitD2); + HUF_DECODE_SYMBOLX1_1(op3, &bitD3); + HUF_DECODE_SYMBOLX1_1(op4, &bitD4); + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_0(op1, &bitD1); + HUF_DECODE_SYMBOLX1_0(op2, &bitD2); + HUF_DECODE_SYMBOLX1_0(op3, &bitD3); + HUF_DECODE_SYMBOLX1_0(op4, &bitD4); + endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; + } + } + + /* check corruption */ + /* note : should not be necessary : op# advance in lock step, and we control op4. + * but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 supposed already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX1(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) return ERROR(corruption_detected); } + + /* decoded size */ + return dstSize; + } +} + +#if HUF_NEED_BMI2_FUNCTION +static BMI2_TARGET_ATTRIBUTE +size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} +#endif + +static +size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 + +HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN; + +#endif + +static HUF_FAST_BMI2_ATTRS +void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* args) +{ + U64 bits[4]; + BYTE const* ip[4]; + BYTE* op[4]; + U16 const* const dtable = (U16 const*)args->dt; + BYTE* const oend = args->oend; + BYTE const* const ilowest = args->ilowest; + + /* Copy the arguments to local variables */ + ZSTD_memcpy(&bits, &args->bits, sizeof(bits)); + ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip)); + ZSTD_memcpy(&op, &args->op, sizeof(op)); + + assert(MEM_isLittleEndian()); + assert(!MEM_32bits()); + + for (;;) { + BYTE* olimit; + int stream; + + /* Assert loop preconditions */ +#ifndef NDEBUG + for (stream = 0; stream < 4; ++stream) { + assert(op[stream] <= (stream == 3 ? oend : op[stream + 1])); + assert(ip[stream] >= ilowest); + } +#endif + /* Compute olimit */ + { + /* Each iteration produces 5 output symbols per stream */ + size_t const oiters = (size_t)(oend - op[3]) / 5; + /* Each iteration consumes up to 11 bits * 5 = 55 bits < 7 bytes + * per stream. + */ + size_t const iiters = (size_t)(ip[0] - ilowest) / 7; + /* We can safely run iters iterations before running bounds checks */ + size_t const iters = MIN(oiters, iiters); + size_t const symbols = iters * 5; + + /* We can simply check that op[3] < olimit, instead of checking all + * of our bounds, since we can't hit the other bounds until we've run + * iters iterations, which only happens when op[3] == olimit. + */ + olimit = op[3] + symbols; + + /* Exit fast decoding loop once we reach the end. */ + if (op[3] == olimit) + break; + + /* Exit the decoding loop if any input pointer has crossed the + * previous one. This indicates corruption, and a precondition + * to our loop is that ip[i] >= ip[0]. + */ + for (stream = 1; stream < 4; ++stream) { + if (ip[stream] < ip[stream - 1]) + goto _out; + } + } + +#ifndef NDEBUG + for (stream = 1; stream < 4; ++stream) { + assert(ip[stream] >= ip[stream - 1]); + } +#endif + +#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol) \ + do { \ + int const index = (int)(bits[(_stream)] >> 53); \ + int const entry = (int)dtable[index]; \ + bits[(_stream)] <<= (entry & 0x3F); \ + op[(_stream)][(_symbol)] = (BYTE)((entry >> 8) & 0xFF); \ + } while (0) + +#define HUF_4X1_RELOAD_STREAM(_stream) \ + do { \ + int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \ + int const nbBits = ctz & 7; \ + int const nbBytes = ctz >> 3; \ + op[(_stream)] += 5; \ + ip[(_stream)] -= nbBytes; \ + bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \ + bits[(_stream)] <<= nbBits; \ + } while (0) + + /* Manually unroll the loop because compilers don't consistently + * unroll the inner loops, which destroys performance. + */ + do { + /* Decode 5 symbols in each of the 4 streams */ + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 1); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 2); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 3); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4); + + /* Reload each of the 4 the bitstreams */ + HUF_4X_FOR_EACH_STREAM(HUF_4X1_RELOAD_STREAM); + } while (op[3] < olimit); + +#undef HUF_4X1_DECODE_SYMBOL +#undef HUF_4X1_RELOAD_STREAM + } + +_out: + + /* Save the final values of each of the state variables back to args. */ + ZSTD_memcpy(&args->bits, &bits, sizeof(bits)); + ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip)); + ZSTD_memcpy(&args->op, &op, sizeof(op)); +} + +/** + * @returns @p dstSize on success (>= 6) + * 0 if the fallback implementation should be used + * An error if an error occurred + */ +static HUF_FAST_BMI2_ATTRS +size_t +HUF_decompress4X1_usingDTable_internal_fast( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable, + HUF_DecompressFastLoopFn loopFn) +{ + void const* dt = DTable + 1; + BYTE const* const ilowest = (BYTE const*)cSrc; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + HUF_DecompressFastArgs args; + { size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); + FORWARD_IF_ERROR(ret, "Failed to init fast loop args"); + if (ret == 0) + return 0; + } + + assert(args.ip[0] >= args.ilowest); + loopFn(&args); + + /* Our loop guarantees that ip[] >= ilowest and that we haven't + * overwritten any op[]. + */ + assert(args.ip[0] >= ilowest); + assert(args.ip[0] >= ilowest); + assert(args.ip[1] >= ilowest); + assert(args.ip[2] >= ilowest); + assert(args.ip[3] >= ilowest); + assert(args.op[3] <= oend); + + assert(ilowest == args.ilowest); + assert(ilowest + 6 == args.iend[0]); + (void)ilowest; + + /* finish bit streams one by one. */ + { size_t const segmentSize = (dstSize+3) / 4; + BYTE* segmentEnd = (BYTE*)dst; + int i; + for (i = 0; i < 4; ++i) { + BIT_DStream_t bit; + if (segmentSize <= (size_t)(oend - segmentEnd)) + segmentEnd += segmentSize; + else + segmentEnd = oend; + FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption"); + /* Decompress and validate that we've produced exactly the expected length. */ + args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG); + if (args.op[i] != segmentEnd) return ERROR(corruption_detected); + } + } + + /* decoded size */ + assert(dstSize != 0); + return dstSize; +} + +HUF_DGEN(HUF_decompress1X1_usingDTable_internal) + +static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable, int flags) +{ + HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X1_usingDTable_internal_default; + HUF_DecompressFastLoopFn loopFn = HUF_decompress4X1_usingDTable_internal_fast_c_loop; + +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + fallbackFn = HUF_decompress4X1_usingDTable_internal_bmi2; +# if ZSTD_ENABLE_ASM_X86_64_BMI2 + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop; + } +# endif + } else { + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); + } +#endif + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop; + } +#endif + + if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) { + size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn); + if (ret != 0) + return ret; + } + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); +} + +static size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} + +#endif /* HUF_FORCE_DECOMPRESS_X2 */ + + +#ifndef HUF_FORCE_DECOMPRESS_X1 + +/* *************************/ +/* double-symbols decoding */ +/* *************************/ + +typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */ +typedef struct { BYTE symbol; } sortedSymbol_t; +typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; +typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX]; + +/** + * Constructs a HUF_DEltX2 in a U32. + */ +static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level) +{ + U32 seq; + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0); + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2); + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3); + DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32)); + if (MEM_isLittleEndian()) { + seq = level == 1 ? symbol : (baseSeq + (symbol << 8)); + return seq + (nbBits << 16) + ((U32)level << 24); + } else { + seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol); + return (seq << 16) + (nbBits << 8) + (U32)level; + } +} + +/** + * Constructs a HUF_DEltX2. + */ +static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level) +{ + HUF_DEltX2 DElt; + U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level); + DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val)); + ZSTD_memcpy(&DElt, &val, sizeof(val)); + return DElt; +} + +/** + * Constructs 2 HUF_DEltX2s and packs them into a U64. + */ +static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level) +{ + U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level); + return (U64)DElt + ((U64)DElt << 32); +} + +/** + * Fills the DTable rank with all the symbols from [begin, end) that are each + * nbBits long. + * + * @param DTableRank The start of the rank in the DTable. + * @param begin The first symbol to fill (inclusive). + * @param end The last symbol to fill (exclusive). + * @param nbBits Each symbol is nbBits long. + * @param tableLog The table log. + * @param baseSeq If level == 1 { 0 } else { the first level symbol } + * @param level The level in the table. Must be 1 or 2. + */ +static void HUF_fillDTableX2ForWeight( + HUF_DEltX2* DTableRank, + sortedSymbol_t const* begin, sortedSymbol_t const* end, + U32 nbBits, U32 tableLog, + U16 baseSeq, int const level) +{ + U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */); + const sortedSymbol_t* ptr; + assert(level >= 1 && level <= 2); + switch (length) { + case 1: + for (ptr = begin; ptr != end; ++ptr) { + HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level); + *DTableRank++ = DElt; + } + break; + case 2: + for (ptr = begin; ptr != end; ++ptr) { + HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level); + DTableRank[0] = DElt; + DTableRank[1] = DElt; + DTableRank += 2; + } + break; + case 4: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + DTableRank += 4; + } + break; + case 8: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2)); + DTableRank += 8; + } + break; + default: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + HUF_DEltX2* const DTableRankEnd = DTableRank + length; + for (; DTableRank != DTableRankEnd; DTableRank += 8) { + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2)); + } + } + break; + } +} + +/* HUF_fillDTableX2Level2() : + * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */ +static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32 consumedBits, + const U32* rankVal, const int minWeight, const int maxWeight1, + const sortedSymbol_t* sortedSymbols, U32 const* rankStart, + U32 nbBitsBaseline, U16 baseSeq) +{ + /* Fill skipped values (all positions up to rankVal[minWeight]). + * These are positions only get a single symbol because the combined weight + * is too large. + */ + if (minWeight>1) { + U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */); + U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1); + int const skipSize = rankVal[minWeight]; + assert(length > 1); + assert((U32)skipSize < length); + switch (length) { + case 2: + assert(skipSize == 1); + ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2)); + break; + case 4: + assert(skipSize <= 4); + ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2)); + break; + default: + { + int i; + for (i = 0; i < skipSize; i += 8) { + ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2)); + } + } + } + } + + /* Fill each of the second level symbols by weight. */ + { + int w; + for (w = minWeight; w < maxWeight1; ++w) { + int const begin = rankStart[w]; + int const end = rankStart[w+1]; + U32 const nbBits = nbBitsBaseline - w; + U32 const totalBits = nbBits + consumedBits; + HUF_fillDTableX2ForWeight( + DTable + rankVal[w], + sortedSymbols + begin, sortedSymbols + end, + totalBits, targetLog, + baseSeq, /* level */ 2); + } + } +} + +static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog, + const sortedSymbol_t* sortedList, + const U32* rankStart, rankValCol_t* rankValOrigin, const U32 maxWeight, + const U32 nbBitsBaseline) +{ + U32* const rankVal = rankValOrigin[0]; + const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ + const U32 minBits = nbBitsBaseline - maxWeight; + int w; + int const wEnd = (int)maxWeight + 1; + + /* Fill DTable in order of weight. */ + for (w = 1; w < wEnd; ++w) { + int const begin = (int)rankStart[w]; + int const end = (int)rankStart[w+1]; + U32 const nbBits = nbBitsBaseline - w; + + if (targetLog-nbBits >= minBits) { + /* Enough room for a second symbol. */ + int start = rankVal[w]; + U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */); + int minWeight = nbBits + scaleLog; + int s; + if (minWeight < 1) minWeight = 1; + /* Fill the DTable for every symbol of weight w. + * These symbols get at least 1 second symbol. + */ + for (s = begin; s != end; ++s) { + HUF_fillDTableX2Level2( + DTable + start, targetLog, nbBits, + rankValOrigin[nbBits], minWeight, wEnd, + sortedList, rankStart, + nbBitsBaseline, sortedList[s].symbol); + start += length; + } + } else { + /* Only a single symbol. */ + HUF_fillDTableX2ForWeight( + DTable + rankVal[w], + sortedList + begin, sortedList + end, + nbBits, targetLog, + /* baseSeq */ 0, /* level */ 1); + } + } +} + +typedef struct { + rankValCol_t rankVal[HUF_TABLELOG_MAX]; + U32 rankStats[HUF_TABLELOG_MAX + 1]; + U32 rankStart0[HUF_TABLELOG_MAX + 3]; + sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1]; + BYTE weightList[HUF_SYMBOLVALUE_MAX + 1]; + U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; +} HUF_ReadDTableX2_Workspace; + +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, int flags) +{ + U32 tableLog, maxW, nbSymbols; + DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 maxTableLog = dtd.maxTableLog; + size_t iSize; + void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */ + HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr; + U32 *rankStart; + + HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace; + + if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC); + + rankStart = wksp->rankStart0 + 1; + ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats)); + ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0)); + + DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ + if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), flags); + if (HUF_isError(iSize)) return iSize; + + /* check result */ + if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ + if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG; + + /* find maxWeight */ + for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */ + + /* Get start index of each weight */ + { U32 w, nextRankStart = 0; + for (w=1; wrankStats[w]; + rankStart[w] = curr; + } + rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/ + rankStart[maxW+1] = nextRankStart; + } + + /* sort symbols by weight */ + { U32 s; + for (s=0; sweightList[s]; + U32 const r = rankStart[w]++; + wksp->sortedSymbol[r].symbol = (BYTE)s; + } + rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */ + } + + /* Build rankVal */ + { U32* const rankVal0 = wksp->rankVal[0]; + { int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */ + U32 nextRankVal = 0; + U32 w; + for (w=1; wrankStats[w] << (w+rescale); + rankVal0[w] = curr; + } } + { U32 const minBits = tableLog+1 - maxW; + U32 consumed; + for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) { + U32* const rankValPtr = wksp->rankVal[consumed]; + U32 w; + for (w = 1; w < maxW+1; w++) { + rankValPtr[w] = rankVal0[w] >> consumed; + } } } } + + HUF_fillDTableX2(dt, maxTableLog, + wksp->sortedSymbol, + wksp->rankStart0, wksp->rankVal, maxW, + tableLog+1); + + dtd.tableLog = (BYTE)maxTableLog; + dtd.tableType = 1; + ZSTD_memcpy(DTable, &dtd, sizeof(dtd)); + return iSize; +} + + +FORCE_INLINE_TEMPLATE U32 +HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + ZSTD_memcpy(op, &dt[val].sequence, 2); + BIT_skipBits(DStream, dt[val].nbBits); + return dt[val].length; +} + +FORCE_INLINE_TEMPLATE U32 +HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + ZSTD_memcpy(op, &dt[val].sequence, 1); + if (dt[val].length==1) { + BIT_skipBits(DStream, dt[val].nbBits); + } else { + if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) { + BIT_skipBits(DStream, dt[val].nbBits); + if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8)) + /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ + DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); + } + } + return 1; +} + +#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \ + do { ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); } while (0) + +#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \ + } while (0) + +#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits()) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \ + } while (0) + +HINT_INLINE size_t +HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, + const HUF_DEltX2* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 8 symbols at a time */ + if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) { + if (dtLog <= 11 && MEM_64bits()) { + /* up to 10 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) { + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + } else { + /* up to 8 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_1(p, bitDPtr); + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + } + } else { + BIT_reloadDStream(bitDPtr); + } + + /* closer to end : up to 2 symbols at a time */ + if ((size_t)(pEnd - p) >= 2) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2)) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + + while (p <= pEnd-2) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ + } + + if (p < pEnd) + p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog); + + return p-pStart; +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress1X2_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + BIT_DStream_t bitD; + + /* Init */ + CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); + + /* decode */ + { BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, dstSize); + const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */ + const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog); + } + + /* check */ + if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); + + /* decoded size */ + return dstSize; +} + +/* HUF_decompress4X2_usingDTable_internal_body(): + * Conditions: + * @dstSize >= 6 + */ +FORCE_INLINE_TEMPLATE size_t +HUF_decompress4X2_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ + + { const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* const olimit = oend - (sizeof(size_t)-1); + const void* const dtPtr = DTable+1; + const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + size_t const segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + U32 endSignal = 1; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ + assert(dstSize >= 6 /* validated above */); + CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); + CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); + CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); + CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); + + /* 16-32 symbols per loop (4-8 symbols per stream) */ + if ((size_t)(oend - op4) >= sizeof(size_t)) { + for ( ; (endSignal) & (op4 < olimit); ) { +#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; +#else + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal = (U32)LIKELY((U32) + (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished)); +#endif + } + } + + /* check corruption */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) return ERROR(corruption_detected); } + + /* decoded size */ + return dstSize; + } +} + +#if HUF_NEED_BMI2_FUNCTION +static BMI2_TARGET_ATTRIBUTE +size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} +#endif + +static +size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 + +HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN; + +#endif + +static HUF_FAST_BMI2_ATTRS +void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* args) +{ + U64 bits[4]; + BYTE const* ip[4]; + BYTE* op[4]; + BYTE* oend[4]; + HUF_DEltX2 const* const dtable = (HUF_DEltX2 const*)args->dt; + BYTE const* const ilowest = args->ilowest; + + /* Copy the arguments to local registers. */ + ZSTD_memcpy(&bits, &args->bits, sizeof(bits)); + ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip)); + ZSTD_memcpy(&op, &args->op, sizeof(op)); + + oend[0] = op[1]; + oend[1] = op[2]; + oend[2] = op[3]; + oend[3] = args->oend; + + assert(MEM_isLittleEndian()); + assert(!MEM_32bits()); + + for (;;) { + BYTE* olimit; + int stream; + + /* Assert loop preconditions */ +#ifndef NDEBUG + for (stream = 0; stream < 4; ++stream) { + assert(op[stream] <= oend[stream]); + assert(ip[stream] >= ilowest); + } +#endif + /* Compute olimit */ + { + /* Each loop does 5 table lookups for each of the 4 streams. + * Each table lookup consumes up to 11 bits of input, and produces + * up to 2 bytes of output. + */ + /* We can consume up to 7 bytes of input per iteration per stream. + * We also know that each input pointer is >= ip[0]. So we can run + * iters loops before running out of input. + */ + size_t iters = (size_t)(ip[0] - ilowest) / 7; + /* Each iteration can produce up to 10 bytes of output per stream. + * Each output stream my advance at different rates. So take the + * minimum number of safe iterations among all the output streams. + */ + for (stream = 0; stream < 4; ++stream) { + size_t const oiters = (size_t)(oend[stream] - op[stream]) / 10; + iters = MIN(iters, oiters); + } + + /* Each iteration produces at least 5 output symbols. So until + * op[3] crosses olimit, we know we haven't executed iters + * iterations yet. This saves us maintaining an iters counter, + * at the expense of computing the remaining # of iterations + * more frequently. + */ + olimit = op[3] + (iters * 5); + + /* Exit the fast decoding loop once we reach the end. */ + if (op[3] == olimit) + break; + + /* Exit the decoding loop if any input pointer has crossed the + * previous one. This indicates corruption, and a precondition + * to our loop is that ip[i] >= ip[0]. + */ + for (stream = 1; stream < 4; ++stream) { + if (ip[stream] < ip[stream - 1]) + goto _out; + } + } + +#ifndef NDEBUG + for (stream = 1; stream < 4; ++stream) { + assert(ip[stream] >= ip[stream - 1]); + } +#endif + +#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3) \ + do { \ + if ((_decode3) || (_stream) != 3) { \ + int const index = (int)(bits[(_stream)] >> 53); \ + HUF_DEltX2 const entry = dtable[index]; \ + MEM_write16(op[(_stream)], entry.sequence); \ + bits[(_stream)] <<= (entry.nbBits) & 0x3F; \ + op[(_stream)] += (entry.length); \ + } \ + } while (0) + +#define HUF_4X2_RELOAD_STREAM(_stream) \ + do { \ + HUF_4X2_DECODE_SYMBOL(3, 1); \ + { \ + int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \ + int const nbBits = ctz & 7; \ + int const nbBytes = ctz >> 3; \ + ip[(_stream)] -= nbBytes; \ + bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \ + bits[(_stream)] <<= nbBits; \ + } \ + } while (0) + + /* Manually unroll the loop because compilers don't consistently + * unroll the inner loops, which destroys performance. + */ + do { + /* Decode 5 symbols from each of the first 3 streams. + * The final stream will be decoded during the reload phase + * to reduce register pressure. + */ + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + + /* Decode one symbol from the final stream */ + HUF_4X2_DECODE_SYMBOL(3, 1); + + /* Decode 4 symbols from the final stream & reload bitstreams. + * The final stream is reloaded last, meaning that all 5 symbols + * are decoded from the final stream before it is reloaded. + */ + HUF_4X_FOR_EACH_STREAM(HUF_4X2_RELOAD_STREAM); + } while (op[3] < olimit); + } + +#undef HUF_4X2_DECODE_SYMBOL +#undef HUF_4X2_RELOAD_STREAM + +_out: + + /* Save the final values of each of the state variables back to args. */ + ZSTD_memcpy(&args->bits, &bits, sizeof(bits)); + ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip)); + ZSTD_memcpy(&args->op, &op, sizeof(op)); +} + + +static HUF_FAST_BMI2_ATTRS size_t +HUF_decompress4X2_usingDTable_internal_fast( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable, + HUF_DecompressFastLoopFn loopFn) { + void const* dt = DTable + 1; + const BYTE* const ilowest = (const BYTE*)cSrc; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + HUF_DecompressFastArgs args; + { + size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); + FORWARD_IF_ERROR(ret, "Failed to init asm args"); + if (ret == 0) + return 0; + } + + assert(args.ip[0] >= args.ilowest); + loopFn(&args); + + /* note : op4 already verified within main loop */ + assert(args.ip[0] >= ilowest); + assert(args.ip[1] >= ilowest); + assert(args.ip[2] >= ilowest); + assert(args.ip[3] >= ilowest); + assert(args.op[3] <= oend); + + assert(ilowest == args.ilowest); + assert(ilowest + 6 == args.iend[0]); + (void)ilowest; + + /* finish bitStreams one by one */ + { + size_t const segmentSize = (dstSize+3) / 4; + BYTE* segmentEnd = (BYTE*)dst; + int i; + for (i = 0; i < 4; ++i) { + BIT_DStream_t bit; + if (segmentSize <= (size_t)(oend - segmentEnd)) + segmentEnd += segmentSize; + else + segmentEnd = oend; + FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption"); + args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG); + if (args.op[i] != segmentEnd) + return ERROR(corruption_detected); + } + } + + /* decoded size */ + return dstSize; +} + +static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable, int flags) +{ + HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X2_usingDTable_internal_default; + HUF_DecompressFastLoopFn loopFn = HUF_decompress4X2_usingDTable_internal_fast_c_loop; + +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + fallbackFn = HUF_decompress4X2_usingDTable_internal_bmi2; +# if ZSTD_ENABLE_ASM_X86_64_BMI2 + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop; + } +# endif + } else { + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); + } +#endif + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop; + } +#endif + + if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) { + size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn); + if (ret != 0) + return ret; + } + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); +} + +HUF_DGEN(HUF_decompress1X2_usingDTable_internal) + +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, + workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, flags); +} + +static size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, + workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} + +#endif /* HUF_FORCE_DECOMPRESS_X1 */ + + +/* ***********************************/ +/* Universal decompression selectors */ +/* ***********************************/ + + +#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2) +typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t; +static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] = +{ + /* single, double, quad */ + {{0,0}, {1,1}}, /* Q==0 : impossible */ + {{0,0}, {1,1}}, /* Q==1 : impossible */ + {{ 150,216}, { 381,119}}, /* Q == 2 : 12-18% */ + {{ 170,205}, { 514,112}}, /* Q == 3 : 18-25% */ + {{ 177,199}, { 539,110}}, /* Q == 4 : 25-32% */ + {{ 197,194}, { 644,107}}, /* Q == 5 : 32-38% */ + {{ 221,192}, { 735,107}}, /* Q == 6 : 38-44% */ + {{ 256,189}, { 881,106}}, /* Q == 7 : 44-50% */ + {{ 359,188}, {1167,109}}, /* Q == 8 : 50-56% */ + {{ 582,187}, {1570,114}}, /* Q == 9 : 56-62% */ + {{ 688,187}, {1712,122}}, /* Q ==10 : 62-69% */ + {{ 825,186}, {1965,136}}, /* Q ==11 : 69-75% */ + {{ 976,185}, {2131,150}}, /* Q ==12 : 75-81% */ + {{1180,186}, {2070,175}}, /* Q ==13 : 81-87% */ + {{1377,185}, {1731,202}}, /* Q ==14 : 87-93% */ + {{1412,185}, {1695,202}}, /* Q ==15 : 93-99% */ +}; +#endif + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize) +{ + assert(dstSize > 0); + assert(dstSize <= 128*1024); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dstSize; + (void)cSrcSize; + return 0; +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dstSize; + (void)cSrcSize; + return 1; +#else + /* decoder timing evaluation */ + { U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize); /* Q < 16 */ + U32 const D256 = (U32)(dstSize >> 8); + U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256); + U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256); + DTime1 += DTime1 >> 5; /* small advantage to algorithm using less memory, to reduce cache eviction */ + return DTime1 < DTime0; + } +#endif +} + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)algoNb; + assert(algoNb == 0); + return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)algoNb; + assert(algoNb == 1); + return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#else + return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags): + HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#endif + } +} + + +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dtd; + assert(dtd.tableType == 0); + return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dtd; + assert(dtd.tableType == 1); + return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#else + return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) : + HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#endif +} + +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} +#endif + +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dtd; + assert(dtd.tableType == 0); + return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dtd; + assert(dtd.tableType == 1); + return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#else + return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) : + HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#endif +} + +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize == 0) return ERROR(corruption_detected); + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)algoNb; + assert(algoNb == 0); + return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)algoNb; + assert(algoNb == 1); + return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#else + return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags) : + HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#endif + } +} diff --git a/cpp/third_party/zstd-1.5.7/lib/decompress/huf_decompress_amd64.S b/cpp/third_party/zstd-1.5.7/lib/decompress/huf_decompress_amd64.S new file mode 100644 index 000000000..656aada95 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/decompress/huf_decompress_amd64.S @@ -0,0 +1,602 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "../common/portability_macros.h" + +#if defined(__ELF__) && defined(__GNUC__) +/* Stack marking + * ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart + */ +.section .note.GNU-stack,"",%progbits + +#if defined(__aarch64__) +/* Mark that this assembly supports BTI & PAC, because it is empty for aarch64. + * See: https://github.com/facebook/zstd/issues/3841 + * See: https://gcc.godbolt.org/z/sqr5T4ffK + * See: https://lore.kernel.org/linux-arm-kernel/20200429211641.9279-8-broonie@kernel.org/ + * See: https://reviews.llvm.org/D62609 + */ +.pushsection .note.gnu.property, "a" +.p2align 3 +.long 4 /* size of the name - "GNU\0" */ +.long 0x10 /* size of descriptor */ +.long 0x5 /* NT_GNU_PROPERTY_TYPE_0 */ +.asciz "GNU" +.long 0xc0000000 /* pr_type - GNU_PROPERTY_AARCH64_FEATURE_1_AND */ +.long 4 /* pr_datasz - 4 bytes */ +.long 3 /* pr_data - GNU_PROPERTY_AARCH64_FEATURE_1_BTI | GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ +.p2align 3 /* pr_padding - bring everything to 8 byte alignment */ +.popsection +#endif + +#endif + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 + +/* Calling convention: + * + * %rdi (or %rcx on Windows) contains the first argument: HUF_DecompressAsmArgs*. + * %rbp isn't maintained (no frame pointer). + * %rsp contains the stack pointer that grows down. + * No red-zone is assumed, only addresses >= %rsp are used. + * All register contents are preserved. + */ + +ZSTD_HIDE_ASM_FUNCTION(HUF_decompress4X1_usingDTable_internal_fast_asm_loop) +ZSTD_HIDE_ASM_FUNCTION(HUF_decompress4X2_usingDTable_internal_fast_asm_loop) +ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X2_usingDTable_internal_fast_asm_loop) +ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X1_usingDTable_internal_fast_asm_loop) +.global HUF_decompress4X1_usingDTable_internal_fast_asm_loop +.global HUF_decompress4X2_usingDTable_internal_fast_asm_loop +.global _HUF_decompress4X1_usingDTable_internal_fast_asm_loop +.global _HUF_decompress4X2_usingDTable_internal_fast_asm_loop +.text + +/* Sets up register mappings for clarity. + * op[], bits[], dtable & ip[0] each get their own register. + * ip[1,2,3] & olimit alias var[]. + * %rax is a scratch register. + */ + +#define op0 rsi +#define op1 rbx +#define op2 rcx +#define op3 rdi + +#define ip0 r8 +#define ip1 r9 +#define ip2 r10 +#define ip3 r11 + +#define bits0 rbp +#define bits1 rdx +#define bits2 r12 +#define bits3 r13 +#define dtable r14 +#define olimit r15 + +/* var[] aliases ip[1,2,3] & olimit + * ip[1,2,3] are saved every iteration. + * olimit is only used in compute_olimit. + */ +#define var0 r15 +#define var1 r9 +#define var2 r10 +#define var3 r11 + +/* 32-bit var registers */ +#define vard0 r15d +#define vard1 r9d +#define vard2 r10d +#define vard3 r11d + +/* Calls X(N) for each stream 0, 1, 2, 3. */ +#define FOR_EACH_STREAM(X) \ + X(0); \ + X(1); \ + X(2); \ + X(3) + +/* Calls X(N, idx) for each stream 0, 1, 2, 3. */ +#define FOR_EACH_STREAM_WITH_INDEX(X, idx) \ + X(0, idx); \ + X(1, idx); \ + X(2, idx); \ + X(3, idx) + +/* Define both _HUF_* & HUF_* symbols because MacOS + * C symbols are prefixed with '_' & Linux symbols aren't. + */ +_HUF_decompress4X1_usingDTable_internal_fast_asm_loop: +HUF_decompress4X1_usingDTable_internal_fast_asm_loop: + ZSTD_CET_ENDBRANCH + /* Save all registers - even if they are callee saved for simplicity. */ + push %rax + push %rbx + push %rcx + push %rdx + push %rbp + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 + + /* Read HUF_DecompressAsmArgs* args from %rax */ +#if defined(_WIN32) + movq %rcx, %rax +#else + movq %rdi, %rax +#endif + movq 0(%rax), %ip0 + movq 8(%rax), %ip1 + movq 16(%rax), %ip2 + movq 24(%rax), %ip3 + movq 32(%rax), %op0 + movq 40(%rax), %op1 + movq 48(%rax), %op2 + movq 56(%rax), %op3 + movq 64(%rax), %bits0 + movq 72(%rax), %bits1 + movq 80(%rax), %bits2 + movq 88(%rax), %bits3 + movq 96(%rax), %dtable + push %rax /* argument */ + push 104(%rax) /* ilowest */ + push 112(%rax) /* oend */ + push %olimit /* olimit space */ + + subq $24, %rsp + +.L_4X1_compute_olimit: + /* Computes how many iterations we can do safely + * %r15, %rax may be clobbered + * rbx, rdx must be saved + * op3 & ip0 mustn't be clobbered + */ + movq %rbx, 0(%rsp) + movq %rdx, 8(%rsp) + + movq 32(%rsp), %rax /* rax = oend */ + subq %op3, %rax /* rax = oend - op3 */ + + /* r15 = (oend - op3) / 5 */ + movabsq $-3689348814741910323, %rdx + mulq %rdx + movq %rdx, %r15 + shrq $2, %r15 + + movq %ip0, %rax /* rax = ip0 */ + movq 40(%rsp), %rdx /* rdx = ilowest */ + subq %rdx, %rax /* rax = ip0 - ilowest */ + movq %rax, %rbx /* rbx = ip0 - ilowest */ + + /* rdx = (ip0 - ilowest) / 7 */ + movabsq $2635249153387078803, %rdx + mulq %rdx + subq %rdx, %rbx + shrq %rbx + addq %rbx, %rdx + shrq $2, %rdx + + /* r15 = min(%rdx, %r15) */ + cmpq %rdx, %r15 + cmova %rdx, %r15 + + /* r15 = r15 * 5 */ + leaq (%r15, %r15, 4), %r15 + + /* olimit = op3 + r15 */ + addq %op3, %olimit + + movq 8(%rsp), %rdx + movq 0(%rsp), %rbx + + /* If (op3 + 20 > olimit) */ + movq %op3, %rax /* rax = op3 */ + cmpq %rax, %olimit /* op3 == olimit */ + je .L_4X1_exit + + /* If (ip1 < ip0) go to exit */ + cmpq %ip0, %ip1 + jb .L_4X1_exit + + /* If (ip2 < ip1) go to exit */ + cmpq %ip1, %ip2 + jb .L_4X1_exit + + /* If (ip3 < ip2) go to exit */ + cmpq %ip2, %ip3 + jb .L_4X1_exit + +/* Reads top 11 bits from bits[n] + * Loads dt[bits[n]] into var[n] + */ +#define GET_NEXT_DELT(n) \ + movq $53, %var##n; \ + shrxq %var##n, %bits##n, %var##n; \ + movzwl (%dtable,%var##n,2),%vard##n + +/* var[n] must contain the DTable entry computed with GET_NEXT_DELT + * Moves var[n] to %rax + * bits[n] <<= var[n] & 63 + * op[n][idx] = %rax >> 8 + * %ah is a way to access bits [8, 16) of %rax + */ +#define DECODE_FROM_DELT(n, idx) \ + movq %var##n, %rax; \ + shlxq %var##n, %bits##n, %bits##n; \ + movb %ah, idx(%op##n) + +/* Assumes GET_NEXT_DELT has been called. + * Calls DECODE_FROM_DELT then GET_NEXT_DELT + */ +#define DECODE_AND_GET_NEXT(n, idx) \ + DECODE_FROM_DELT(n, idx); \ + GET_NEXT_DELT(n) \ + +/* // ctz & nbBytes is stored in bits[n] + * // nbBits is stored in %rax + * ctz = CTZ[bits[n]] + * nbBits = ctz & 7 + * nbBytes = ctz >> 3 + * op[n] += 5 + * ip[n] -= nbBytes + * // Note: x86-64 is little-endian ==> no bswap + * bits[n] = MEM_readST(ip[n]) | 1 + * bits[n] <<= nbBits + */ +#define RELOAD_BITS(n) \ + bsfq %bits##n, %bits##n; \ + movq %bits##n, %rax; \ + andq $7, %rax; \ + shrq $3, %bits##n; \ + leaq 5(%op##n), %op##n; \ + subq %bits##n, %ip##n; \ + movq (%ip##n), %bits##n; \ + orq $1, %bits##n; \ + shlx %rax, %bits##n, %bits##n + + /* Store clobbered variables on the stack */ + movq %olimit, 24(%rsp) + movq %ip1, 0(%rsp) + movq %ip2, 8(%rsp) + movq %ip3, 16(%rsp) + + /* Call GET_NEXT_DELT for each stream */ + FOR_EACH_STREAM(GET_NEXT_DELT) + + .p2align 6 + +.L_4X1_loop_body: + /* Decode 5 symbols in each of the 4 streams (20 total) + * Must have called GET_NEXT_DELT for each stream + */ + FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 0) + FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 1) + FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 2) + FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 3) + FOR_EACH_STREAM_WITH_INDEX(DECODE_FROM_DELT, 4) + + /* Load ip[1,2,3] from stack (var[] aliases them) + * ip[] is needed for RELOAD_BITS + * Each will be stored back to the stack after RELOAD + */ + movq 0(%rsp), %ip1 + movq 8(%rsp), %ip2 + movq 16(%rsp), %ip3 + + /* Reload each stream & fetch the next table entry + * to prepare for the next iteration + */ + RELOAD_BITS(0) + GET_NEXT_DELT(0) + + RELOAD_BITS(1) + movq %ip1, 0(%rsp) + GET_NEXT_DELT(1) + + RELOAD_BITS(2) + movq %ip2, 8(%rsp) + GET_NEXT_DELT(2) + + RELOAD_BITS(3) + movq %ip3, 16(%rsp) + GET_NEXT_DELT(3) + + /* If op3 < olimit: continue the loop */ + cmp %op3, 24(%rsp) + ja .L_4X1_loop_body + + /* Reload ip[1,2,3] from stack */ + movq 0(%rsp), %ip1 + movq 8(%rsp), %ip2 + movq 16(%rsp), %ip3 + + /* Re-compute olimit */ + jmp .L_4X1_compute_olimit + +#undef GET_NEXT_DELT +#undef DECODE_FROM_DELT +#undef DECODE +#undef RELOAD_BITS +.L_4X1_exit: + addq $24, %rsp + + /* Restore stack (oend & olimit) */ + pop %rax /* olimit */ + pop %rax /* oend */ + pop %rax /* ilowest */ + pop %rax /* arg */ + + /* Save ip / op / bits */ + movq %ip0, 0(%rax) + movq %ip1, 8(%rax) + movq %ip2, 16(%rax) + movq %ip3, 24(%rax) + movq %op0, 32(%rax) + movq %op1, 40(%rax) + movq %op2, 48(%rax) + movq %op3, 56(%rax) + movq %bits0, 64(%rax) + movq %bits1, 72(%rax) + movq %bits2, 80(%rax) + movq %bits3, 88(%rax) + + /* Restore registers */ + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rbp + pop %rdx + pop %rcx + pop %rbx + pop %rax + ret + +_HUF_decompress4X2_usingDTable_internal_fast_asm_loop: +HUF_decompress4X2_usingDTable_internal_fast_asm_loop: + ZSTD_CET_ENDBRANCH + /* Save all registers - even if they are callee saved for simplicity. */ + push %rax + push %rbx + push %rcx + push %rdx + push %rbp + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 + + /* Read HUF_DecompressAsmArgs* args from %rax */ +#if defined(_WIN32) + movq %rcx, %rax +#else + movq %rdi, %rax +#endif + movq 0(%rax), %ip0 + movq 8(%rax), %ip1 + movq 16(%rax), %ip2 + movq 24(%rax), %ip3 + movq 32(%rax), %op0 + movq 40(%rax), %op1 + movq 48(%rax), %op2 + movq 56(%rax), %op3 + movq 64(%rax), %bits0 + movq 72(%rax), %bits1 + movq 80(%rax), %bits2 + movq 88(%rax), %bits3 + movq 96(%rax), %dtable + push %rax /* argument */ + push %rax /* olimit */ + push 104(%rax) /* ilowest */ + + movq 112(%rax), %rax + push %rax /* oend3 */ + + movq %op3, %rax + push %rax /* oend2 */ + + movq %op2, %rax + push %rax /* oend1 */ + + movq %op1, %rax + push %rax /* oend0 */ + + /* Scratch space */ + subq $8, %rsp + +.L_4X2_compute_olimit: + /* Computes how many iterations we can do safely + * %r15, %rax may be clobbered + * rdx must be saved + * op[1,2,3,4] & ip0 mustn't be clobbered + */ + movq %rdx, 0(%rsp) + + /* We can consume up to 7 input bytes each iteration. */ + movq %ip0, %rax /* rax = ip0 */ + movq 40(%rsp), %rdx /* rdx = ilowest */ + subq %rdx, %rax /* rax = ip0 - ilowest */ + movq %rax, %r15 /* r15 = ip0 - ilowest */ + + /* rdx = rax / 7 */ + movabsq $2635249153387078803, %rdx + mulq %rdx + subq %rdx, %r15 + shrq %r15 + addq %r15, %rdx + shrq $2, %rdx + + /* r15 = (ip0 - ilowest) / 7 */ + movq %rdx, %r15 + + /* r15 = min(r15, min(oend0 - op0, oend1 - op1, oend2 - op2, oend3 - op3) / 10) */ + movq 8(%rsp), %rax /* rax = oend0 */ + subq %op0, %rax /* rax = oend0 - op0 */ + movq 16(%rsp), %rdx /* rdx = oend1 */ + subq %op1, %rdx /* rdx = oend1 - op1 */ + + cmpq %rax, %rdx + cmova %rax, %rdx /* rdx = min(%rdx, %rax) */ + + movq 24(%rsp), %rax /* rax = oend2 */ + subq %op2, %rax /* rax = oend2 - op2 */ + + cmpq %rax, %rdx + cmova %rax, %rdx /* rdx = min(%rdx, %rax) */ + + movq 32(%rsp), %rax /* rax = oend3 */ + subq %op3, %rax /* rax = oend3 - op3 */ + + cmpq %rax, %rdx + cmova %rax, %rdx /* rdx = min(%rdx, %rax) */ + + movabsq $-3689348814741910323, %rax + mulq %rdx + shrq $3, %rdx /* rdx = rdx / 10 */ + + /* r15 = min(%rdx, %r15) */ + cmpq %rdx, %r15 + cmova %rdx, %r15 + + /* olimit = op3 + 5 * r15 */ + movq %r15, %rax + leaq (%op3, %rax, 4), %olimit + addq %rax, %olimit + + movq 0(%rsp), %rdx + + /* If (op3 + 10 > olimit) */ + movq %op3, %rax /* rax = op3 */ + cmpq %rax, %olimit /* op3 == olimit */ + je .L_4X2_exit + + /* If (ip1 < ip0) go to exit */ + cmpq %ip0, %ip1 + jb .L_4X2_exit + + /* If (ip2 < ip1) go to exit */ + cmpq %ip1, %ip2 + jb .L_4X2_exit + + /* If (ip3 < ip2) go to exit */ + cmpq %ip2, %ip3 + jb .L_4X2_exit + +#define DECODE(n, idx) \ + movq %bits##n, %rax; \ + shrq $53, %rax; \ + movzwl 0(%dtable,%rax,4),%r8d; \ + movzbl 2(%dtable,%rax,4),%r15d; \ + movzbl 3(%dtable,%rax,4),%eax; \ + movw %r8w, (%op##n); \ + shlxq %r15, %bits##n, %bits##n; \ + addq %rax, %op##n + +#define RELOAD_BITS(n) \ + bsfq %bits##n, %bits##n; \ + movq %bits##n, %rax; \ + shrq $3, %bits##n; \ + andq $7, %rax; \ + subq %bits##n, %ip##n; \ + movq (%ip##n), %bits##n; \ + orq $1, %bits##n; \ + shlxq %rax, %bits##n, %bits##n + + + movq %olimit, 48(%rsp) + + .p2align 6 + +.L_4X2_loop_body: + /* We clobber r8, so store it on the stack */ + movq %r8, 0(%rsp) + + /* Decode 5 symbols from each of the 4 streams (20 symbols total). */ + FOR_EACH_STREAM_WITH_INDEX(DECODE, 0) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 1) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 2) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 3) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 4) + + /* Reload r8 */ + movq 0(%rsp), %r8 + + FOR_EACH_STREAM(RELOAD_BITS) + + cmp %op3, 48(%rsp) + ja .L_4X2_loop_body + jmp .L_4X2_compute_olimit + +#undef DECODE +#undef RELOAD_BITS +.L_4X2_exit: + addq $8, %rsp + /* Restore stack (oend & olimit) */ + pop %rax /* oend0 */ + pop %rax /* oend1 */ + pop %rax /* oend2 */ + pop %rax /* oend3 */ + pop %rax /* ilowest */ + pop %rax /* olimit */ + pop %rax /* arg */ + + /* Save ip / op / bits */ + movq %ip0, 0(%rax) + movq %ip1, 8(%rax) + movq %ip2, 16(%rax) + movq %ip3, 24(%rax) + movq %op0, 32(%rax) + movq %op1, 40(%rax) + movq %op2, 48(%rax) + movq %op3, 56(%rax) + movq %bits0, 64(%rax) + movq %bits1, 72(%rax) + movq %bits2, 80(%rax) + movq %bits3, 88(%rax) + + /* Restore registers */ + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rbp + pop %rdx + pop %rcx + pop %rbx + pop %rax + ret + +#endif diff --git a/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_ddict.c b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_ddict.c new file mode 100644 index 000000000..309ec0d03 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_ddict.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* zstd_ddict.c : + * concentrates all logic that needs to know the internals of ZSTD_DDict object */ + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customFree */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/cpu.h" /* bmi2 */ +#include "../common/mem.h" /* low level memory routines */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include "zstd_decompress_internal.h" +#include "zstd_ddict.h" + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) +# include "../legacy/zstd_legacy.h" +#endif + + + +/*-******************************************************* +* Types +*********************************************************/ +struct ZSTD_DDict_s { + void* dictBuffer; + const void* dictContent; + size_t dictSize; + ZSTD_entropyDTables_t entropy; + U32 dictID; + U32 entropyPresent; + ZSTD_customMem cMem; +}; /* typedef'd to ZSTD_DDict within "zstd.h" */ + +const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict) +{ + assert(ddict != NULL); + return ddict->dictContent; +} + +size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict) +{ + assert(ddict != NULL); + return ddict->dictSize; +} + +void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + DEBUGLOG(4, "ZSTD_copyDDictParameters"); + assert(dctx != NULL); + assert(ddict != NULL); + dctx->dictID = ddict->dictID; + dctx->prefixStart = ddict->dictContent; + dctx->virtualStart = ddict->dictContent; + dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize; + dctx->previousDstEnd = dctx->dictEnd; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentBeginForFuzzing = dctx->prefixStart; + dctx->dictContentEndForFuzzing = dctx->previousDstEnd; +#endif + if (ddict->entropyPresent) { + dctx->litEntropy = 1; + dctx->fseEntropy = 1; + dctx->LLTptr = ddict->entropy.LLTable; + dctx->MLTptr = ddict->entropy.MLTable; + dctx->OFTptr = ddict->entropy.OFTable; + dctx->HUFptr = ddict->entropy.hufTable; + dctx->entropy.rep[0] = ddict->entropy.rep[0]; + dctx->entropy.rep[1] = ddict->entropy.rep[1]; + dctx->entropy.rep[2] = ddict->entropy.rep[2]; + } else { + dctx->litEntropy = 0; + dctx->fseEntropy = 0; + } +} + + +static size_t +ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict, + ZSTD_dictContentType_e dictContentType) +{ + ddict->dictID = 0; + ddict->entropyPresent = 0; + if (dictContentType == ZSTD_dct_rawContent) return 0; + + if (ddict->dictSize < 8) { + if (dictContentType == ZSTD_dct_fullDict) + return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ + return 0; /* pure content mode */ + } + { U32 const magic = MEM_readLE32(ddict->dictContent); + if (magic != ZSTD_MAGIC_DICTIONARY) { + if (dictContentType == ZSTD_dct_fullDict) + return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ + return 0; /* pure content mode */ + } + } + ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE); + + /* load entropy tables */ + RETURN_ERROR_IF(ZSTD_isError(ZSTD_loadDEntropy( + &ddict->entropy, ddict->dictContent, ddict->dictSize)), + dictionary_corrupted, ""); + ddict->entropyPresent = 1; + return 0; +} + + +static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) { + ddict->dictBuffer = NULL; + ddict->dictContent = dict; + if (!dict) dictSize = 0; + } else { + void* const internalBuffer = ZSTD_customMalloc(dictSize, ddict->cMem); + ddict->dictBuffer = internalBuffer; + ddict->dictContent = internalBuffer; + if (!internalBuffer) return ERROR(memory_allocation); + ZSTD_memcpy(internalBuffer, dict, dictSize); + } + ddict->dictSize = dictSize; + ddict->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */ + + /* parse dictionary content */ + FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) , ""); + + return 0; +} + +ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_customMem customMem) +{ + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + + { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_customMalloc(sizeof(ZSTD_DDict), customMem); + if (ddict == NULL) return NULL; + ddict->cMem = customMem; + { size_t const initResult = ZSTD_initDDict_internal(ddict, + dict, dictSize, + dictLoadMethod, dictContentType); + if (ZSTD_isError(initResult)) { + ZSTD_freeDDict(ddict); + return NULL; + } } + return ddict; + } +} + +/*! ZSTD_createDDict() : +* Create a digested dictionary, to start decompression without startup delay. +* `dict` content is copied inside DDict. +* Consequently, `dict` can be released after `ZSTD_DDict` creation */ +ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize) +{ + ZSTD_customMem const allocator = { NULL, NULL, NULL }; + return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator); +} + +/*! ZSTD_createDDict_byReference() : + * Create a digested dictionary, to start decompression without startup delay. + * Dictionary content is simply referenced, it will be accessed during decompression. + * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */ +ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize) +{ + ZSTD_customMem const allocator = { NULL, NULL, NULL }; + return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator); +} + + +const ZSTD_DDict* ZSTD_initStaticDDict( + void* sBuffer, size_t sBufferSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + size_t const neededSpace = sizeof(ZSTD_DDict) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); + ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer; + assert(sBuffer != NULL); + assert(dict != NULL); + if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */ + if (sBufferSize < neededSpace) return NULL; + if (dictLoadMethod == ZSTD_dlm_byCopy) { + ZSTD_memcpy(ddict+1, dict, dictSize); /* local copy */ + dict = ddict+1; + } + if (ZSTD_isError( ZSTD_initDDict_internal(ddict, + dict, dictSize, + ZSTD_dlm_byRef, dictContentType) )) + return NULL; + return ddict; +} + + +size_t ZSTD_freeDDict(ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; /* support free on NULL */ + { ZSTD_customMem const cMem = ddict->cMem; + ZSTD_customFree(ddict->dictBuffer, cMem); + ZSTD_customFree(ddict, cMem); + return 0; + } +} + +/*! ZSTD_estimateDDictSize() : + * Estimate amount of memory that will be needed to create a dictionary for decompression. + * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */ +size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod) +{ + return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); +} + +size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; /* support sizeof on NULL */ + return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ; +} + +/*! ZSTD_getDictID_fromDDict() : + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; + return ddict->dictID; +} diff --git a/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_ddict.h b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_ddict.h new file mode 100644 index 000000000..c4ca8877a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_ddict.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#ifndef ZSTD_DDICT_H +#define ZSTD_DDICT_H + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/zstd_deps.h" /* size_t */ +#include "../zstd.h" /* ZSTD_DDict, and several public functions */ + + +/*-******************************************************* + * Interface + *********************************************************/ + +/* note: several prototypes are already published in `zstd.h` : + * ZSTD_createDDict() + * ZSTD_createDDict_byReference() + * ZSTD_createDDict_advanced() + * ZSTD_freeDDict() + * ZSTD_initStaticDDict() + * ZSTD_sizeof_DDict() + * ZSTD_estimateDDictSize() + * ZSTD_getDictID_fromDict() + */ + +const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict); +size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict); + +void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + + + +#endif /* ZSTD_DDICT_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress.c b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress.c new file mode 100644 index 000000000..9eb98327e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress.c @@ -0,0 +1,2410 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* *************************************************************** +* Tuning parameters +*****************************************************************/ +/*! + * HEAPMODE : + * Select how default decompression function ZSTD_decompress() allocates its context, + * on stack (0), or into heap (1, default; requires malloc()). + * Note that functions with explicit context such as ZSTD_decompressDCtx() are unaffected. + */ +#ifndef ZSTD_HEAPMODE +# define ZSTD_HEAPMODE 1 +#endif + +/*! +* LEGACY_SUPPORT : +* if set to 1+, ZSTD_decompress() can decode older formats (v0.1+) +*/ +#ifndef ZSTD_LEGACY_SUPPORT +# define ZSTD_LEGACY_SUPPORT 0 +#endif + +/*! + * MAXWINDOWSIZE_DEFAULT : + * maximum window size accepted by DStream __by default__. + * Frames requiring more memory will be rejected. + * It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize(). + */ +#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT +# define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1) +#endif + +/*! + * NO_FORWARD_PROGRESS_MAX : + * maximum allowed nb of calls to ZSTD_decompressStream() + * without any forward progress + * (defined as: no byte read from input, and no byte flushed to output) + * before triggering an error. + */ +#ifndef ZSTD_NO_FORWARD_PROGRESS_MAX +# define ZSTD_NO_FORWARD_PROGRESS_MAX 16 +#endif + + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ +#include "../common/error_private.h" +#include "../common/zstd_internal.h" /* blockProperties_t */ +#include "../common/mem.h" /* low level memory routines */ +#include "../common/bits.h" /* ZSTD_highbit32 */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */ +#include "zstd_decompress_internal.h" /* ZSTD_DCtx */ +#include "zstd_ddict.h" /* ZSTD_DDictDictContent */ +#include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */ + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) +# include "../legacy/zstd_legacy.h" +#endif + + + +/************************************* + * Multiple DDicts Hashset internals * + *************************************/ + +#define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT 4 +#define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3 /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float. + * Currently, that means a 0.75 load factor. + * So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded + * the load factor of the ddict hash set. + */ + +#define DDICT_HASHSET_TABLE_BASE_SIZE 64 +#define DDICT_HASHSET_RESIZE_FACTOR 2 + +/* Hash function to determine starting position of dict insertion within the table + * Returns an index between [0, hashSet->ddictPtrTableSize] + */ +static size_t ZSTD_DDictHashSet_getIndex(const ZSTD_DDictHashSet* hashSet, U32 dictID) { + const U64 hash = XXH64(&dictID, sizeof(U32), 0); + /* DDict ptr table size is a multiple of 2, use size - 1 as mask to get index within [0, hashSet->ddictPtrTableSize) */ + return hash & (hashSet->ddictPtrTableSize - 1); +} + +/* Adds DDict to a hashset without resizing it. + * If inserting a DDict with a dictID that already exists in the set, replaces the one in the set. + * Returns 0 if successful, or a zstd error code if something went wrong. + */ +static size_t ZSTD_DDictHashSet_emplaceDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict) { + const U32 dictID = ZSTD_getDictID_fromDDict(ddict); + size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID); + const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1; + RETURN_ERROR_IF(hashSet->ddictPtrCount == hashSet->ddictPtrTableSize, GENERIC, "Hash set is full!"); + DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx); + while (hashSet->ddictPtrTable[idx] != NULL) { + /* Replace existing ddict if inserting ddict with same dictID */ + if (ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]) == dictID) { + DEBUGLOG(4, "DictID already exists, replacing rather than adding"); + hashSet->ddictPtrTable[idx] = ddict; + return 0; + } + idx &= idxRangeMask; + idx++; + } + DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx); + hashSet->ddictPtrTable[idx] = ddict; + hashSet->ddictPtrCount++; + return 0; +} + +/* Expands hash table by factor of DDICT_HASHSET_RESIZE_FACTOR and + * rehashes all values, allocates new table, frees old table. + * Returns 0 on success, otherwise a zstd error code. + */ +static size_t ZSTD_DDictHashSet_expand(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) { + size_t newTableSize = hashSet->ddictPtrTableSize * DDICT_HASHSET_RESIZE_FACTOR; + const ZSTD_DDict** newTable = (const ZSTD_DDict**)ZSTD_customCalloc(sizeof(ZSTD_DDict*) * newTableSize, customMem); + const ZSTD_DDict** oldTable = hashSet->ddictPtrTable; + size_t oldTableSize = hashSet->ddictPtrTableSize; + size_t i; + + DEBUGLOG(4, "Expanding DDict hash table! Old size: %zu new size: %zu", oldTableSize, newTableSize); + RETURN_ERROR_IF(!newTable, memory_allocation, "Expanded hashset allocation failed!"); + hashSet->ddictPtrTable = newTable; + hashSet->ddictPtrTableSize = newTableSize; + hashSet->ddictPtrCount = 0; + for (i = 0; i < oldTableSize; ++i) { + if (oldTable[i] != NULL) { + FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, oldTable[i]), ""); + } + } + ZSTD_customFree((void*)oldTable, customMem); + DEBUGLOG(4, "Finished re-hash"); + return 0; +} + +/* Fetches a DDict with the given dictID + * Returns the ZSTD_DDict* with the requested dictID. If it doesn't exist, then returns NULL. + */ +static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet, U32 dictID) { + size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID); + const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1; + DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx); + for (;;) { + size_t currDictID = ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]); + if (currDictID == dictID || currDictID == 0) { + /* currDictID == 0 implies a NULL ddict entry */ + break; + } else { + idx &= idxRangeMask; /* Goes to start of table when we reach the end */ + idx++; + } + } + DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx); + return hashSet->ddictPtrTable[idx]; +} + +/* Allocates space for and returns a ddict hash set + * The hash set's ZSTD_DDict* table has all values automatically set to NULL to begin with. + * Returns NULL if allocation failed. + */ +static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) { + ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem); + DEBUGLOG(4, "Allocating new hash set"); + if (!ret) + return NULL; + ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem); + if (!ret->ddictPtrTable) { + ZSTD_customFree(ret, customMem); + return NULL; + } + ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE; + ret->ddictPtrCount = 0; + return ret; +} + +/* Frees the table of ZSTD_DDict* within a hashset, then frees the hashset itself. + * Note: The ZSTD_DDict* within the table are NOT freed. + */ +static void ZSTD_freeDDictHashSet(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) { + DEBUGLOG(4, "Freeing ddict hash set"); + if (hashSet && hashSet->ddictPtrTable) { + ZSTD_customFree((void*)hashSet->ddictPtrTable, customMem); + } + if (hashSet) { + ZSTD_customFree(hashSet, customMem); + } +} + +/* Public function: Adds a DDict into the ZSTD_DDictHashSet, possibly triggering a resize of the hash set. + * Returns 0 on success, or a ZSTD error. + */ +static size_t ZSTD_DDictHashSet_addDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict, ZSTD_customMem customMem) { + DEBUGLOG(4, "Adding dict ID: %u to hashset with - Count: %zu Tablesize: %zu", ZSTD_getDictID_fromDDict(ddict), hashSet->ddictPtrCount, hashSet->ddictPtrTableSize); + if (hashSet->ddictPtrCount * DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT / hashSet->ddictPtrTableSize * DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT != 0) { + FORWARD_IF_ERROR(ZSTD_DDictHashSet_expand(hashSet, customMem), ""); + } + FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, ddict), ""); + return 0; +} + +/*-************************************************************* +* Context management +***************************************************************/ +size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) +{ + if (dctx==NULL) return 0; /* support sizeof NULL */ + return sizeof(*dctx) + + ZSTD_sizeof_DDict(dctx->ddictLocal) + + dctx->inBuffSize + dctx->outBuffSize; +} + +size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); } + + +static size_t ZSTD_startingInputLength(ZSTD_format_e format) +{ + size_t const startingInputLength = ZSTD_FRAMEHEADERSIZE_PREFIX(format); + /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */ + assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) ); + return startingInputLength; +} + +static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx) +{ + assert(dctx->streamStage == zdss_init); + dctx->format = ZSTD_f_zstd1; + dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; + dctx->outBufferMode = ZSTD_bm_buffered; + dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum; + dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict; + dctx->disableHufAsm = 0; + dctx->maxBlockSizeParam = 0; +} + +static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) +{ + dctx->staticSize = 0; + dctx->ddict = NULL; + dctx->ddictLocal = NULL; + dctx->dictEnd = NULL; + dctx->ddictIsCold = 0; + dctx->dictUses = ZSTD_dont_use; + dctx->inBuff = NULL; + dctx->inBuffSize = 0; + dctx->outBuffSize = 0; + dctx->streamStage = zdss_init; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + dctx->legacyContext = NULL; + dctx->previousLegacyVersion = 0; +#endif + dctx->noForwardProgress = 0; + dctx->oversizedDuration = 0; + dctx->isFrameDecompression = 1; +#if DYNAMIC_BMI2 + dctx->bmi2 = ZSTD_cpuSupportsBmi2(); +#endif + dctx->ddictSet = NULL; + ZSTD_DCtx_resetParameters(dctx); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentEndForFuzzing = NULL; +#endif +} + +ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) +{ + ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace; + + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */ + + ZSTD_initDCtx_internal(dctx); + dctx->staticSize = workspaceSize; + dctx->inBuff = (char*)(dctx+1); + return dctx; +} + +static ZSTD_DCtx* ZSTD_createDCtx_internal(ZSTD_customMem customMem) { + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + + { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem); + if (!dctx) return NULL; + dctx->customMem = customMem; + ZSTD_initDCtx_internal(dctx); + return dctx; + } +} + +ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) +{ + return ZSTD_createDCtx_internal(customMem); +} + +ZSTD_DCtx* ZSTD_createDCtx(void) +{ + DEBUGLOG(3, "ZSTD_createDCtx"); + return ZSTD_createDCtx_internal(ZSTD_defaultCMem); +} + +static void ZSTD_clearDict(ZSTD_DCtx* dctx) +{ + ZSTD_freeDDict(dctx->ddictLocal); + dctx->ddictLocal = NULL; + dctx->ddict = NULL; + dctx->dictUses = ZSTD_dont_use; +} + +size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) +{ + if (dctx==NULL) return 0; /* support free on NULL */ + RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx"); + { ZSTD_customMem const cMem = dctx->customMem; + ZSTD_clearDict(dctx); + ZSTD_customFree(dctx->inBuff, cMem); + dctx->inBuff = NULL; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (dctx->legacyContext) + ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion); +#endif + if (dctx->ddictSet) { + ZSTD_freeDDictHashSet(dctx->ddictSet, cMem); + dctx->ddictSet = NULL; + } + ZSTD_customFree(dctx, cMem); + return 0; + } +} + +/* no longer useful */ +void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) +{ + size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx); + ZSTD_memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ +} + +/* Given a dctx with a digested frame params, re-selects the correct ZSTD_DDict based on + * the requested dict ID from the frame. If there exists a reference to the correct ZSTD_DDict, then + * accordingly sets the ddict to be used to decompress the frame. + * + * If no DDict is found, then no action is taken, and the ZSTD_DCtx::ddict remains as-is. + * + * ZSTD_d_refMultipleDDicts must be enabled for this function to be called. + */ +static void ZSTD_DCtx_selectFrameDDict(ZSTD_DCtx* dctx) { + assert(dctx->refMultipleDDicts && dctx->ddictSet); + DEBUGLOG(4, "Adjusting DDict based on requested dict ID from frame"); + if (dctx->ddict) { + const ZSTD_DDict* frameDDict = ZSTD_DDictHashSet_getDDict(dctx->ddictSet, dctx->fParams.dictID); + if (frameDDict) { + DEBUGLOG(4, "DDict found!"); + ZSTD_clearDict(dctx); + dctx->dictID = dctx->fParams.dictID; + dctx->ddict = frameDDict; + dctx->dictUses = ZSTD_use_indefinitely; + } + } +} + + +/*-************************************************************* + * Frame header decoding + ***************************************************************/ + +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +unsigned ZSTD_isFrame(const void* buffer, size_t size) +{ + if (size < ZSTD_FRAMEIDSIZE) return 0; + { U32 const magic = MEM_readLE32(buffer); + if (magic == ZSTD_MAGICNUMBER) return 1; + if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(buffer, size)) return 1; +#endif + return 0; +} + +/*! ZSTD_isSkippableFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + */ +unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size) +{ + if (size < ZSTD_FRAMEIDSIZE) return 0; + { U32 const magic = MEM_readLE32(buffer); + if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } + return 0; +} + +/** ZSTD_frameHeaderSize_internal() : + * srcSize must be large enough to reach header size fields. + * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless. + * @return : size of the Frame Header + * or an error code, which can be tested with ZSTD_isError() */ +static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format) +{ + size_t const minInputSize = ZSTD_startingInputLength(format); + RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong, ""); + + { BYTE const fhd = ((const BYTE*)src)[minInputSize-1]; + U32 const dictID= fhd & 3; + U32 const singleSegment = (fhd >> 5) & 1; + U32 const fcsId = fhd >> 6; + return minInputSize + !singleSegment + + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] + + (singleSegment && !fcsId); + } +} + +/** ZSTD_frameHeaderSize() : + * srcSize must be >= ZSTD_frameHeaderSize_prefix. + * @return : size of the Frame Header, + * or an error code (if srcSize is too small) */ +size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) +{ + return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1); +} + + +/** ZSTD_getFrameHeader_advanced() : + * decode Frame Header, or require larger `srcSize`. + * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, +** or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format) +{ + const BYTE* ip = (const BYTE*)src; + size_t const minInputSize = ZSTD_startingInputLength(format); + + DEBUGLOG(5, "ZSTD_getFrameHeader_advanced: minInputSize = %zu, srcSize = %zu", minInputSize, srcSize); + + if (srcSize > 0) { + /* note : technically could be considered an assert(), since it's an invalid entry */ + RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter : src==NULL, but srcSize>0"); + } + if (srcSize < minInputSize) { + if (srcSize > 0 && format != ZSTD_f_zstd1_magicless) { + /* when receiving less than @minInputSize bytes, + * control these bytes at least correspond to a supported magic number + * in order to error out early if they don't. + **/ + size_t const toCopy = MIN(4, srcSize); + unsigned char hbuf[4]; MEM_writeLE32(hbuf, ZSTD_MAGICNUMBER); + assert(src != NULL); + ZSTD_memcpy(hbuf, src, toCopy); + if ( MEM_readLE32(hbuf) != ZSTD_MAGICNUMBER ) { + /* not a zstd frame : let's check if it's a skippable frame */ + MEM_writeLE32(hbuf, ZSTD_MAGIC_SKIPPABLE_START); + ZSTD_memcpy(hbuf, src, toCopy); + if ((MEM_readLE32(hbuf) & ZSTD_MAGIC_SKIPPABLE_MASK) != ZSTD_MAGIC_SKIPPABLE_START) { + RETURN_ERROR(prefix_unknown, + "first bytes don't correspond to any supported magic number"); + } } } + return minInputSize; + } + + ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzers may not understand that zfhPtr will be read only if return value is zero, since they are 2 different signals */ + if ( (format != ZSTD_f_zstd1_magicless) + && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) { + if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + /* skippable frame */ + if (srcSize < ZSTD_SKIPPABLEHEADERSIZE) + return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */ + ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); + zfhPtr->frameType = ZSTD_skippableFrame; + zfhPtr->dictID = MEM_readLE32(src) - ZSTD_MAGIC_SKIPPABLE_START; + zfhPtr->headerSize = ZSTD_SKIPPABLEHEADERSIZE; + zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE); + return 0; + } + RETURN_ERROR(prefix_unknown, ""); + } + + /* ensure there is enough `srcSize` to fully read/decode frame header */ + { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format); + if (srcSize < fhsize) return fhsize; + zfhPtr->headerSize = (U32)fhsize; + } + + { BYTE const fhdByte = ip[minInputSize-1]; + size_t pos = minInputSize; + U32 const dictIDSizeCode = fhdByte&3; + U32 const checksumFlag = (fhdByte>>2)&1; + U32 const singleSegment = (fhdByte>>5)&1; + U32 const fcsID = fhdByte>>6; + U64 windowSize = 0; + U32 dictID = 0; + U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported, + "reserved bits, must be zero"); + + if (!singleSegment) { + BYTE const wlByte = ip[pos++]; + U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN; + RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge, ""); + windowSize = (1ULL << windowLog); + windowSize += (windowSize >> 3) * (wlByte&7); + } + switch(dictIDSizeCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : break; + case 1 : dictID = ip[pos]; pos++; break; + case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; + case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break; + } + switch(fcsID) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : if (singleSegment) frameContentSize = ip[pos]; break; + case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; + case 2 : frameContentSize = MEM_readLE32(ip+pos); break; + case 3 : frameContentSize = MEM_readLE64(ip+pos); break; + } + if (singleSegment) windowSize = frameContentSize; + + zfhPtr->frameType = ZSTD_frame; + zfhPtr->frameContentSize = frameContentSize; + zfhPtr->windowSize = windowSize; + zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); + zfhPtr->dictID = dictID; + zfhPtr->checksumFlag = checksumFlag; + } + return 0; +} + +/** ZSTD_getFrameHeader() : + * decode Frame Header, or require larger `srcSize`. + * note : this function does not consume input, it only reads it. + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, + * or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize) +{ + return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1); +} + +/** ZSTD_getFrameContentSize() : + * compatible with legacy mode + * @return : decompressed size of the single frame pointed to be `src` if known, otherwise + * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined + * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */ +unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize) +{ +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(src, srcSize)) { + unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize); + return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret; + } +#endif + { ZSTD_FrameHeader zfh; + if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0) + return ZSTD_CONTENTSIZE_ERROR; + if (zfh.frameType == ZSTD_skippableFrame) { + return 0; + } else { + return zfh.frameContentSize; + } } +} + +static size_t readSkippableFrameSize(void const* src, size_t srcSize) +{ + size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE; + U32 sizeU32; + + RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, ""); + + sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE); + RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32, + frameParameter_unsupported, ""); + { size_t const skippableSize = skippableHeaderSize + sizeU32; + RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, ""); + return skippableSize; + } +} + +/*! ZSTD_readSkippableFrame() : + * Retrieves content of a skippable frame, and writes it to dst buffer. + * + * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written, + * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested + * in the magicVariant. + * + * Returns an error if destination buffer is not large enough, or if this is not a valid skippable frame. + * + * @return : number of bytes written or a ZSTD error. + */ +size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, + unsigned* magicVariant, /* optional, can be NULL */ + const void* src, size_t srcSize) +{ + RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, ""); + + { U32 const magicNumber = MEM_readLE32(src); + size_t skippableFrameSize = readSkippableFrameSize(src, srcSize); + size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE; + + /* check input validity */ + RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, ""); + RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, ""); + RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, ""); + + /* deliver payload */ + if (skippableContentSize > 0 && dst != NULL) + ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize); + if (magicVariant != NULL) + *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START; + return skippableContentSize; + } +} + +/** ZSTD_findDecompressedSize() : + * `srcSize` must be the exact length of some number of ZSTD compressed and/or + * skippable frames + * note: compatible with legacy mode + * @return : decompressed size of the frames contained */ +unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) +{ + unsigned long long totalDstSize = 0; + + while (srcSize >= ZSTD_startingInputLength(ZSTD_f_zstd1)) { + U32 const magicNumber = MEM_readLE32(src); + + if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + size_t const skippableSize = readSkippableFrameSize(src, srcSize); + if (ZSTD_isError(skippableSize)) return ZSTD_CONTENTSIZE_ERROR; + assert(skippableSize <= srcSize); + + src = (const BYTE *)src + skippableSize; + srcSize -= skippableSize; + continue; + } + + { unsigned long long const fcs = ZSTD_getFrameContentSize(src, srcSize); + if (fcs >= ZSTD_CONTENTSIZE_ERROR) return fcs; + + if (totalDstSize + fcs < totalDstSize) + return ZSTD_CONTENTSIZE_ERROR; /* check for overflow */ + totalDstSize += fcs; + } + /* skip to next frame */ + { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize); + if (ZSTD_isError(frameSrcSize)) return ZSTD_CONTENTSIZE_ERROR; + assert(frameSrcSize <= srcSize); + + src = (const BYTE *)src + frameSrcSize; + srcSize -= frameSrcSize; + } + } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ + + if (srcSize) return ZSTD_CONTENTSIZE_ERROR; + + return totalDstSize; +} + +/** ZSTD_getDecompressedSize() : + * compatible with legacy mode + * @return : decompressed size if known, 0 otherwise + note : 0 can mean any of the following : + - frame content is empty + - decompressed size field is not present in frame header + - frame header unknown / not supported + - frame header not complete (`srcSize` too small) */ +unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize) +{ + unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN); + return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret; +} + + +/** ZSTD_decodeFrameHeader() : + * `headerSize` must be the size provided by ZSTD_frameHeaderSize(). + * If multiple DDict references are enabled, also will choose the correct DDict to use. + * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */ +static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize) +{ + size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format); + if (ZSTD_isError(result)) return result; /* invalid header */ + RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small"); + + /* Reference DDict requested by frame if dctx references multiple ddicts */ + if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts && dctx->ddictSet) { + ZSTD_DCtx_selectFrameDDict(dctx); + } + +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Skip the dictID check in fuzzing mode, because it makes the search + * harder. + */ + RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID), + dictionary_wrong, ""); +#endif + dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0; + if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0); + dctx->processedCSize += headerSize; + return 0; +} + +static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret) +{ + ZSTD_frameSizeInfo frameSizeInfo; + frameSizeInfo.compressedSize = ret; + frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR; + return frameSizeInfo; +} + +static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize, ZSTD_format_e format) +{ + ZSTD_frameSizeInfo frameSizeInfo; + ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo)); + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) + return ZSTD_findFrameSizeInfoLegacy(src, srcSize); +#endif + + if (format == ZSTD_f_zstd1 && (srcSize >= ZSTD_SKIPPABLEHEADERSIZE) + && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize); + assert(ZSTD_isError(frameSizeInfo.compressedSize) || + frameSizeInfo.compressedSize <= srcSize); + return frameSizeInfo; + } else { + const BYTE* ip = (const BYTE*)src; + const BYTE* const ipstart = ip; + size_t remainingSize = srcSize; + size_t nbBlocks = 0; + ZSTD_FrameHeader zfh; + + /* Extract Frame Header */ + { size_t const ret = ZSTD_getFrameHeader_advanced(&zfh, src, srcSize, format); + if (ZSTD_isError(ret)) + return ZSTD_errorFrameSizeInfo(ret); + if (ret > 0) + return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong)); + } + + ip += zfh.headerSize; + remainingSize -= zfh.headerSize; + + /* Iterate over each block */ + while (1) { + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) + return ZSTD_errorFrameSizeInfo(cBlockSize); + + if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) + return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong)); + + ip += ZSTD_blockHeaderSize + cBlockSize; + remainingSize -= ZSTD_blockHeaderSize + cBlockSize; + nbBlocks++; + + if (blockProperties.lastBlock) break; + } + + /* Final frame content checksum */ + if (zfh.checksumFlag) { + if (remainingSize < 4) + return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong)); + ip += 4; + } + + frameSizeInfo.nbBlocks = nbBlocks; + frameSizeInfo.compressedSize = (size_t)(ip - ipstart); + frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) + ? zfh.frameContentSize + : (unsigned long long)nbBlocks * zfh.blockSizeMax; + return frameSizeInfo; + } +} + +static size_t ZSTD_findFrameCompressedSize_advanced(const void *src, size_t srcSize, ZSTD_format_e format) { + ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, format); + return frameSizeInfo.compressedSize; +} + +/** ZSTD_findFrameCompressedSize() : + * See docs in zstd.h + * Note: compatible with legacy mode */ +size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize) +{ + return ZSTD_findFrameCompressedSize_advanced(src, srcSize, ZSTD_f_zstd1); +} + +/** ZSTD_decompressBound() : + * compatible with legacy mode + * `src` must point to the start of a ZSTD frame or a skippable frame + * `srcSize` must be at least as large as the frame contained + * @return : the maximum decompressed size of the compressed source + */ +unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize) +{ + unsigned long long bound = 0; + /* Iterate over each frame */ + while (srcSize > 0) { + ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1); + size_t const compressedSize = frameSizeInfo.compressedSize; + unsigned long long const decompressedBound = frameSizeInfo.decompressedBound; + if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR) + return ZSTD_CONTENTSIZE_ERROR; + assert(srcSize >= compressedSize); + src = (const BYTE*)src + compressedSize; + srcSize -= compressedSize; + bound += decompressedBound; + } + return bound; +} + +size_t ZSTD_decompressionMargin(void const* src, size_t srcSize) +{ + size_t margin = 0; + unsigned maxBlockSize = 0; + + /* Iterate over each frame */ + while (srcSize > 0) { + ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1); + size_t const compressedSize = frameSizeInfo.compressedSize; + unsigned long long const decompressedBound = frameSizeInfo.decompressedBound; + ZSTD_FrameHeader zfh; + + FORWARD_IF_ERROR(ZSTD_getFrameHeader(&zfh, src, srcSize), ""); + if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR) + return ERROR(corruption_detected); + + if (zfh.frameType == ZSTD_frame) { + /* Add the frame header to our margin */ + margin += zfh.headerSize; + /* Add the checksum to our margin */ + margin += zfh.checksumFlag ? 4 : 0; + /* Add 3 bytes per block */ + margin += 3 * frameSizeInfo.nbBlocks; + + /* Compute the max block size */ + maxBlockSize = MAX(maxBlockSize, zfh.blockSizeMax); + } else { + assert(zfh.frameType == ZSTD_skippableFrame); + /* Add the entire skippable frame size to our margin. */ + margin += compressedSize; + } + + assert(srcSize >= compressedSize); + src = (const BYTE*)src + compressedSize; + srcSize -= compressedSize; + } + + /* Add the max block size back to the margin. */ + margin += maxBlockSize; + + return margin; +} + +/*-************************************************************* + * Frame decoding + ***************************************************************/ + +/** ZSTD_insertBlock() : + * insert `src` block into `dctx` history. Useful to track uncompressed blocks. */ +size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize) +{ + DEBUGLOG(5, "ZSTD_insertBlock: %u bytes", (unsigned)blockSize); + ZSTD_checkContinuity(dctx, blockStart, blockSize); + dctx->previousDstEnd = (const char*)blockStart + blockSize; + return blockSize; +} + + +static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_copyRawBlock"); + RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, ""); + if (dst == NULL) { + if (srcSize == 0) return 0; + RETURN_ERROR(dstBuffer_null, ""); + } + ZSTD_memmove(dst, src, srcSize); + return srcSize; +} + +static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, + BYTE b, + size_t regenSize) +{ + RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, ""); + if (dst == NULL) { + if (regenSize == 0) return 0; + RETURN_ERROR(dstBuffer_null, ""); + } + ZSTD_memset(dst, b, regenSize); + return regenSize; +} + +static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, int streaming) +{ +#if ZSTD_TRACE + if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) { + ZSTD_Trace trace; + ZSTD_memset(&trace, 0, sizeof(trace)); + trace.version = ZSTD_VERSION_NUMBER; + trace.streaming = streaming; + if (dctx->ddict) { + trace.dictionaryID = ZSTD_getDictID_fromDDict(dctx->ddict); + trace.dictionarySize = ZSTD_DDict_dictSize(dctx->ddict); + trace.dictionaryIsCold = dctx->ddictIsCold; + } + trace.uncompressedSize = (size_t)uncompressedSize; + trace.compressedSize = (size_t)compressedSize; + trace.dctx = dctx; + ZSTD_trace_decompress_end(dctx->traceCtx, &trace); + } +#else + (void)dctx; + (void)uncompressedSize; + (void)compressedSize; + (void)streaming; +#endif +} + + +/*! ZSTD_decompressFrame() : + * @dctx must be properly initialized + * will update *srcPtr and *srcSizePtr, + * to make *srcPtr progress by one frame. */ +static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void** srcPtr, size_t *srcSizePtr) +{ + const BYTE* const istart = (const BYTE*)(*srcPtr); + const BYTE* ip = istart; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dstCapacity != 0 ? ostart + dstCapacity : ostart; + BYTE* op = ostart; + size_t remainingSrcSize = *srcSizePtr; + + DEBUGLOG(4, "ZSTD_decompressFrame (srcSize:%i)", (int)*srcSizePtr); + + /* check */ + RETURN_ERROR_IF( + remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN(dctx->format)+ZSTD_blockHeaderSize, + srcSize_wrong, ""); + + /* Frame Header */ + { size_t const frameHeaderSize = ZSTD_frameHeaderSize_internal( + ip, ZSTD_FRAMEHEADERSIZE_PREFIX(dctx->format), dctx->format); + if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize; + RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize, + srcSize_wrong, ""); + FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) , ""); + ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize; + } + + /* Shrink the blockSizeMax if enabled */ + if (dctx->maxBlockSizeParam != 0) + dctx->fParams.blockSizeMax = MIN(dctx->fParams.blockSizeMax, (unsigned)dctx->maxBlockSizeParam); + + /* Loop on each block */ + while (1) { + BYTE* oBlockEnd = oend; + size_t decodedSize; + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) return cBlockSize; + + ip += ZSTD_blockHeaderSize; + remainingSrcSize -= ZSTD_blockHeaderSize; + RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, ""); + + if (ip >= op && ip < oBlockEnd) { + /* We are decompressing in-place. Limit the output pointer so that we + * don't overwrite the block that we are currently reading. This will + * fail decompression if the input & output pointers aren't spaced + * far enough apart. + * + * This is important to set, even when the pointers are far enough + * apart, because ZSTD_decompressBlock_internal() can decide to store + * literals in the output buffer, after the block it is decompressing. + * Since we don't want anything to overwrite our input, we have to tell + * ZSTD_decompressBlock_internal to never write past ip. + * + * See ZSTD_allocateLiteralsBuffer() for reference. + */ + oBlockEnd = op + (ip - op); + } + + switch(blockProperties.blockType) + { + case bt_compressed: + assert(dctx->isFrameDecompression == 1); + decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, not_streaming); + break; + case bt_raw : + /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */ + decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize); + break; + case bt_rle : + decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize); + break; + case bt_reserved : + default: + RETURN_ERROR(corruption_detected, "invalid block type"); + } + FORWARD_IF_ERROR(decodedSize, "Block decompression failure"); + DEBUGLOG(5, "Decompressed block of dSize = %u", (unsigned)decodedSize); + if (dctx->validateChecksum) { + XXH64_update(&dctx->xxhState, op, decodedSize); + } + if (decodedSize) /* support dst = NULL,0 */ { + op += decodedSize; + } + assert(ip != NULL); + ip += cBlockSize; + remainingSrcSize -= cBlockSize; + if (blockProperties.lastBlock) break; + } + + if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) { + RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize, + corruption_detected, ""); + } + if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */ + RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, ""); + if (!dctx->forceIgnoreChecksum) { + U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState); + U32 checkRead; + checkRead = MEM_readLE32(ip); + RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, ""); + } + ip += 4; + remainingSrcSize -= 4; + } + ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0); + /* Allow caller to get size read */ + DEBUGLOG(4, "ZSTD_decompressFrame: decompressed frame of size %i, consuming %i bytes of input", (int)(op-ostart), (int)(ip - (const BYTE*)*srcPtr)); + *srcPtr = ip; + *srcSizePtr = remainingSrcSize; + return (size_t)(op-ostart); +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + const ZSTD_DDict* ddict) +{ + void* const dststart = dst; + int moreThan1Frame = 0; + + DEBUGLOG(5, "ZSTD_decompressMultiFrame"); + assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */ + + if (ddict) { + dict = ZSTD_DDict_dictContent(ddict); + dictSize = ZSTD_DDict_dictSize(ddict); + } + + while (srcSize >= ZSTD_startingInputLength(dctx->format)) { + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (dctx->format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) { + size_t decodedSize; + size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize); + if (ZSTD_isError(frameSize)) return frameSize; + RETURN_ERROR_IF(dctx->staticSize, memory_allocation, + "legacy support is not compatible with static dctx"); + + decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize); + if (ZSTD_isError(decodedSize)) return decodedSize; + + { + unsigned long long const expectedSize = ZSTD_getFrameContentSize(src, srcSize); + RETURN_ERROR_IF(expectedSize == ZSTD_CONTENTSIZE_ERROR, corruption_detected, "Corrupted frame header!"); + if (expectedSize != ZSTD_CONTENTSIZE_UNKNOWN) { + RETURN_ERROR_IF(expectedSize != decodedSize, corruption_detected, + "Frame header size does not match decoded size!"); + } + } + + assert(decodedSize <= dstCapacity); + dst = (BYTE*)dst + decodedSize; + dstCapacity -= decodedSize; + + src = (const BYTE*)src + frameSize; + srcSize -= frameSize; + + continue; + } +#endif + + if (dctx->format == ZSTD_f_zstd1 && srcSize >= 4) { + U32 const magicNumber = MEM_readLE32(src); + DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber); + if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + /* skippable frame detected : skip it */ + size_t const skippableSize = readSkippableFrameSize(src, srcSize); + FORWARD_IF_ERROR(skippableSize, "invalid skippable frame"); + assert(skippableSize <= srcSize); + + src = (const BYTE *)src + skippableSize; + srcSize -= skippableSize; + continue; /* check next frame */ + } } + + if (ddict) { + /* we were called from ZSTD_decompress_usingDDict */ + FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict), ""); + } else { + /* this will initialize correctly with no dict if dict == NULL, so + * use this in all cases but ddict */ + FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize), ""); + } + ZSTD_checkContinuity(dctx, dst, dstCapacity); + + { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, + &src, &srcSize); + RETURN_ERROR_IF( + (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown) + && (moreThan1Frame==1), + srcSize_wrong, + "At least one frame successfully completed, " + "but following bytes are garbage: " + "it's more likely to be a srcSize error, " + "specifying more input bytes than size of frame(s). " + "Note: one could be unlucky, it might be a corruption error instead, " + "happening right at the place where we expect zstd magic bytes. " + "But this is _much_ less likely than a srcSize field error."); + if (ZSTD_isError(res)) return res; + assert(res <= dstCapacity); + if (res != 0) + dst = (BYTE*)dst + res; + dstCapacity -= res; + } + moreThan1Frame = 1; + } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ + + RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed"); + + return (size_t)((BYTE*)dst - (BYTE*)dststart); +} + +size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize) +{ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL); +} + + +static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx) +{ + switch (dctx->dictUses) { + default: + assert(0 /* Impossible */); + ZSTD_FALLTHROUGH; + case ZSTD_dont_use: + ZSTD_clearDict(dctx); + return NULL; + case ZSTD_use_indefinitely: + return dctx->ddict; + case ZSTD_use_once: + dctx->dictUses = ZSTD_dont_use; + return dctx->ddict; + } +} + +size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx)); +} + + +size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ +#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1) + size_t regenSize; + ZSTD_DCtx* const dctx = ZSTD_createDCtx_internal(ZSTD_defaultCMem); + RETURN_ERROR_IF(dctx==NULL, memory_allocation, "NULL pointer!"); + regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize); + ZSTD_freeDCtx(dctx); + return regenSize; +#else /* stack mode */ + ZSTD_DCtx dctx; + ZSTD_initDCtx_internal(&dctx); + return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize); +#endif +} + + +/*-************************************** +* Advanced Streaming Decompression API +* Bufferless and synchronous +****************************************/ +size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; } + +/** + * Similar to ZSTD_nextSrcSizeToDecompress(), but when a block input can be streamed, we + * allow taking a partial block as the input. Currently only raw uncompressed blocks can + * be streamed. + * + * For blocks that can be streamed, this allows us to reduce the latency until we produce + * output, and avoid copying the input. + * + * @param inputSize - The total amount of input that the caller currently has. + */ +static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t inputSize) { + if (!(dctx->stage == ZSTDds_decompressBlock || dctx->stage == ZSTDds_decompressLastBlock)) + return dctx->expected; + if (dctx->bType != bt_raw) + return dctx->expected; + return BOUNDED(1, inputSize, dctx->expected); +} + +ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) { + switch(dctx->stage) + { + default: /* should not happen */ + assert(0); + ZSTD_FALLTHROUGH; + case ZSTDds_getFrameHeaderSize: + ZSTD_FALLTHROUGH; + case ZSTDds_decodeFrameHeader: + return ZSTDnit_frameHeader; + case ZSTDds_decodeBlockHeader: + return ZSTDnit_blockHeader; + case ZSTDds_decompressBlock: + return ZSTDnit_block; + case ZSTDds_decompressLastBlock: + return ZSTDnit_lastBlock; + case ZSTDds_checkChecksum: + return ZSTDnit_checksum; + case ZSTDds_decodeSkippableHeader: + ZSTD_FALLTHROUGH; + case ZSTDds_skipFrame: + return ZSTDnit_skippableFrame; + } +} + +static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } + +/** ZSTD_decompressContinue() : + * srcSize : must be the exact nb of bytes expected (see ZSTD_nextSrcSizeToDecompress()) + * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity) + * or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (unsigned)srcSize); + /* Sanity check */ + RETURN_ERROR_IF(srcSize != ZSTD_nextSrcSizeToDecompressWithInputSize(dctx, srcSize), srcSize_wrong, "not allowed"); + ZSTD_checkContinuity(dctx, dst, dstCapacity); + + dctx->processedCSize += srcSize; + + switch (dctx->stage) + { + case ZSTDds_getFrameHeaderSize : + assert(src != NULL); + if (dctx->format == ZSTD_f_zstd1) { /* allows header */ + assert(srcSize >= ZSTD_FRAMEIDSIZE); /* to read skippable magic number */ + if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ + ZSTD_memcpy(dctx->headerBuffer, src, srcSize); + dctx->expected = ZSTD_SKIPPABLEHEADERSIZE - srcSize; /* remaining to load to get full skippable frame header */ + dctx->stage = ZSTDds_decodeSkippableHeader; + return 0; + } } + dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format); + if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize; + ZSTD_memcpy(dctx->headerBuffer, src, srcSize); + dctx->expected = dctx->headerSize - srcSize; + dctx->stage = ZSTDds_decodeFrameHeader; + return 0; + + case ZSTDds_decodeFrameHeader: + assert(src != NULL); + ZSTD_memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize); + FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize), ""); + dctx->expected = ZSTD_blockHeaderSize; + dctx->stage = ZSTDds_decodeBlockHeader; + return 0; + + case ZSTDds_decodeBlockHeader: + { blockProperties_t bp; + size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp); + if (ZSTD_isError(cBlockSize)) return cBlockSize; + RETURN_ERROR_IF(cBlockSize > dctx->fParams.blockSizeMax, corruption_detected, "Block Size Exceeds Maximum"); + dctx->expected = cBlockSize; + dctx->bType = bp.blockType; + dctx->rleSize = bp.origSize; + if (cBlockSize) { + dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock; + return 0; + } + /* empty block */ + if (bp.lastBlock) { + if (dctx->fParams.checksumFlag) { + dctx->expected = 4; + dctx->stage = ZSTDds_checkChecksum; + } else { + dctx->expected = 0; /* end of frame */ + dctx->stage = ZSTDds_getFrameHeaderSize; + } + } else { + dctx->expected = ZSTD_blockHeaderSize; /* jump to next header */ + dctx->stage = ZSTDds_decodeBlockHeader; + } + return 0; + } + + case ZSTDds_decompressLastBlock: + case ZSTDds_decompressBlock: + DEBUGLOG(5, "ZSTD_decompressContinue: case ZSTDds_decompressBlock"); + { size_t rSize; + switch(dctx->bType) + { + case bt_compressed: + DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed"); + assert(dctx->isFrameDecompression == 1); + rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, is_streaming); + dctx->expected = 0; /* Streaming not supported */ + break; + case bt_raw : + assert(srcSize <= dctx->expected); + rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize); + FORWARD_IF_ERROR(rSize, "ZSTD_copyRawBlock failed"); + assert(rSize == srcSize); + dctx->expected -= rSize; + break; + case bt_rle : + rSize = ZSTD_setRleBlock(dst, dstCapacity, *(const BYTE*)src, dctx->rleSize); + dctx->expected = 0; /* Streaming not supported */ + break; + case bt_reserved : /* should never happen */ + default: + RETURN_ERROR(corruption_detected, "invalid block type"); + } + FORWARD_IF_ERROR(rSize, ""); + RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, "Decompressed Block Size Exceeds Maximum"); + DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize); + dctx->decodedSize += rSize; + if (dctx->validateChecksum) XXH64_update(&dctx->xxhState, dst, rSize); + dctx->previousDstEnd = (char*)dst + rSize; + + /* Stay on the same stage until we are finished streaming the block. */ + if (dctx->expected > 0) { + return rSize; + } + + if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */ + DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (unsigned)dctx->decodedSize); + RETURN_ERROR_IF( + dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN + && dctx->decodedSize != dctx->fParams.frameContentSize, + corruption_detected, ""); + if (dctx->fParams.checksumFlag) { /* another round for frame checksum */ + dctx->expected = 4; + dctx->stage = ZSTDds_checkChecksum; + } else { + ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1); + dctx->expected = 0; /* ends here */ + dctx->stage = ZSTDds_getFrameHeaderSize; + } + } else { + dctx->stage = ZSTDds_decodeBlockHeader; + dctx->expected = ZSTD_blockHeaderSize; + } + return rSize; + } + + case ZSTDds_checkChecksum: + assert(srcSize == 4); /* guaranteed by dctx->expected */ + { + if (dctx->validateChecksum) { + U32 const h32 = (U32)XXH64_digest(&dctx->xxhState); + U32 const check32 = MEM_readLE32(src); + DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32); + RETURN_ERROR_IF(check32 != h32, checksum_wrong, ""); + } + ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1); + dctx->expected = 0; + dctx->stage = ZSTDds_getFrameHeaderSize; + return 0; + } + + case ZSTDds_decodeSkippableHeader: + assert(src != NULL); + assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE); + assert(dctx->format != ZSTD_f_zstd1_magicless); + ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */ + dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */ + dctx->stage = ZSTDds_skipFrame; + return 0; + + case ZSTDds_skipFrame: + dctx->expected = 0; + dctx->stage = ZSTDds_getFrameHeaderSize; + return 0; + + default: + assert(0); /* impossible */ + RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */ + } +} + + +static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + dctx->dictEnd = dctx->previousDstEnd; + dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); + dctx->prefixStart = dict; + dctx->previousDstEnd = (const char*)dict + dictSize; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentBeginForFuzzing = dctx->prefixStart; + dctx->dictContentEndForFuzzing = dctx->previousDstEnd; +#endif + return 0; +} + +/*! ZSTD_loadDEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * @return : size of entropy tables read */ +size_t +ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, + const void* const dict, size_t const dictSize) +{ + const BYTE* dictPtr = (const BYTE*)dict; + const BYTE* const dictEnd = dictPtr + dictSize; + + RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted, "dict is too small"); + assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */ + dictPtr += 8; /* skip header = magic + dictID */ + + ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable)); + ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable)); + ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE); + { void* const workspace = &entropy->LLTable; /* use fse tables as temporary workspace; implies fse tables are grouped together */ + size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable); +#ifdef HUF_FORCE_DECOMPRESS_X1 + /* in minimal huffman, we always use X1 variants */ + size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable, + dictPtr, dictEnd - dictPtr, + workspace, workspaceSize, /* flags */ 0); +#else + size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable, + dictPtr, (size_t)(dictEnd - dictPtr), + workspace, workspaceSize, /* flags */ 0); +#endif + RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, ""); + dictPtr += hSize; + } + + { short offcodeNCount[MaxOff+1]; + unsigned offcodeMaxValue = MaxOff, offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->OFTable, + offcodeNCount, offcodeMaxValue, + OF_base, OF_bits, + offcodeLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */0); + dictPtr += offcodeHeaderSize; + } + + { short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->MLTable, + matchlengthNCount, matchlengthMaxValue, + ML_base, ML_bits, + matchlengthLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */ 0); + dictPtr += matchlengthHeaderSize; + } + + { short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->LLTable, + litlengthNCount, litlengthMaxValue, + LL_base, LL_bits, + litlengthLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */ 0); + dictPtr += litlengthHeaderSize; + } + + RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, ""); + { int i; + size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12)); + for (i=0; i<3; i++) { + U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4; + RETURN_ERROR_IF(rep==0 || rep > dictContentSize, + dictionary_corrupted, ""); + entropy->rep[i] = rep; + } } + + return (size_t)(dictPtr - (const BYTE*)dict); +} + +static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize); + { U32 const magic = MEM_readLE32(dict); + if (magic != ZSTD_MAGIC_DICTIONARY) { + return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ + } } + dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE); + + /* load entropy tables */ + { size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize); + RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted, ""); + dict = (const char*)dict + eSize; + dictSize -= eSize; + } + dctx->litEntropy = dctx->fseEntropy = 1; + + /* reference dictionary content */ + return ZSTD_refDictContent(dctx, dict, dictSize); +} + +size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) +{ + assert(dctx != NULL); +#if ZSTD_TRACE + dctx->traceCtx = (ZSTD_trace_decompress_begin != NULL) ? ZSTD_trace_decompress_begin(dctx) : 0; +#endif + dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */ + dctx->stage = ZSTDds_getFrameHeaderSize; + dctx->processedCSize = 0; + dctx->decodedSize = 0; + dctx->previousDstEnd = NULL; + dctx->prefixStart = NULL; + dctx->virtualStart = NULL; + dctx->dictEnd = NULL; + dctx->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */ + dctx->litEntropy = dctx->fseEntropy = 0; + dctx->dictID = 0; + dctx->bType = bt_reserved; + dctx->isFrameDecompression = 1; + ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); + ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ + dctx->LLTptr = dctx->entropy.LLTable; + dctx->MLTptr = dctx->entropy.MLTable; + dctx->OFTptr = dctx->entropy.OFTable; + dctx->HUFptr = dctx->entropy.hufTable; + return 0; +} + +size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , ""); + if (dict && dictSize) + RETURN_ERROR_IF( + ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)), + dictionary_corrupted, ""); + return 0; +} + + +/* ====== ZSTD_DDict ====== */ + +size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict"); + assert(dctx != NULL); + if (ddict) { + const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict); + size_t const dictSize = ZSTD_DDict_dictSize(ddict); + const void* const dictEnd = dictStart + dictSize; + dctx->ddictIsCold = (dctx->dictEnd != dictEnd); + DEBUGLOG(4, "DDict is %s", + dctx->ddictIsCold ? "~cold~" : "hot!"); + } + FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , ""); + if (ddict) { /* NULL ddict is equivalent to no dictionary */ + ZSTD_copyDDictParameters(dctx, ddict); + } + return 0; +} + +/*! ZSTD_getDictID_fromDict() : + * Provides the dictID stored within dictionary. + * if @return == 0, the dictionary is not conformant with Zstandard specification. + * It can still be loaded, but as a content-only dictionary. */ +unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize) +{ + if (dictSize < 8) return 0; + if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0; + return MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE); +} + +/*! ZSTD_getDictID_fromFrame() : + * Provides the dictID required to decompress frame stored within `src`. + * If @return == 0, the dictID could not be decoded. + * This could for one of the following reasons : + * - The frame does not require a dictionary (most common case). + * - The frame was built with dictID intentionally removed. + * Needed dictionary is a hidden piece of information. + * Note : this use case also happens when using a non-conformant dictionary. + * - `srcSize` is too small, and as a result, frame header could not be decoded. + * Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`. + * - This is not a Zstandard frame. + * When identifying the exact failure cause, it's possible to use + * ZSTD_getFrameHeader(), which will provide a more precise error code. */ +unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize) +{ + ZSTD_FrameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0, 0, 0 }; + size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize); + if (ZSTD_isError(hError)) return 0; + return zfp.dictID; +} + + +/*! ZSTD_decompress_usingDDict() : +* Decompression using a pre-digested Dictionary +* Use dictionary without significant overhead. */ +size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_DDict* ddict) +{ + /* pass content and size in case legacy frames are encountered */ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, + NULL, 0, + ddict); +} + + +/*===================================== +* Streaming decompression +*====================================*/ + +ZSTD_DStream* ZSTD_createDStream(void) +{ + DEBUGLOG(3, "ZSTD_createDStream"); + return ZSTD_createDCtx_internal(ZSTD_defaultCMem); +} + +ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize) +{ + return ZSTD_initStaticDCtx(workspace, workspaceSize); +} + +ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem) +{ + return ZSTD_createDCtx_internal(customMem); +} + +size_t ZSTD_freeDStream(ZSTD_DStream* zds) +{ + return ZSTD_freeDCtx(zds); +} + + +/* *** Initialization *** */ + +size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; } +size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; } + +size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, ""); + ZSTD_clearDict(dctx); + if (dict && dictSize != 0) { + dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem); + RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation, "NULL pointer!"); + dctx->ddict = dctx->ddictLocal; + dctx->dictUses = ZSTD_use_indefinitely; + } + return 0; +} + +size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto); +} + +size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); +} + +size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType) +{ + FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType), ""); + dctx->dictUses = ZSTD_use_once; + return 0; +} + +size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize) +{ + return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent); +} + + +/* ZSTD_initDStream_usingDict() : + * return : expected size, aka ZSTD_startingInputLength(). + * this function cannot fail */ +size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize) +{ + DEBUGLOG(4, "ZSTD_initDStream_usingDict"); + FORWARD_IF_ERROR( ZSTD_DCtx_reset(zds, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) , ""); + return ZSTD_startingInputLength(zds->format); +} + +/* note : this variant can't fail */ +size_t ZSTD_initDStream(ZSTD_DStream* zds) +{ + DEBUGLOG(4, "ZSTD_initDStream"); + FORWARD_IF_ERROR(ZSTD_DCtx_reset(zds, ZSTD_reset_session_only), ""); + FORWARD_IF_ERROR(ZSTD_DCtx_refDDict(zds, NULL), ""); + return ZSTD_startingInputLength(zds->format); +} + +/* ZSTD_initDStream_usingDDict() : + * ddict will just be referenced, and must outlive decompression session + * this function cannot fail */ +size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict) +{ + DEBUGLOG(4, "ZSTD_initDStream_usingDDict"); + FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) , ""); + FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) , ""); + return ZSTD_startingInputLength(dctx->format); +} + +/* ZSTD_resetDStream() : + * return : expected size, aka ZSTD_startingInputLength(). + * this function cannot fail */ +size_t ZSTD_resetDStream(ZSTD_DStream* dctx) +{ + DEBUGLOG(4, "ZSTD_resetDStream"); + FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only), ""); + return ZSTD_startingInputLength(dctx->format); +} + + +size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, ""); + ZSTD_clearDict(dctx); + if (ddict) { + dctx->ddict = ddict; + dctx->dictUses = ZSTD_use_indefinitely; + if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts) { + if (dctx->ddictSet == NULL) { + dctx->ddictSet = ZSTD_createDDictHashSet(dctx->customMem); + if (!dctx->ddictSet) { + RETURN_ERROR(memory_allocation, "Failed to allocate memory for hash set!"); + } + } + assert(!dctx->staticSize); /* Impossible: ddictSet cannot have been allocated if static dctx */ + FORWARD_IF_ERROR(ZSTD_DDictHashSet_addDDict(dctx->ddictSet, ddict, dctx->customMem), ""); + } + } + return 0; +} + +/* ZSTD_DCtx_setMaxWindowSize() : + * note : no direct equivalence in ZSTD_DCtx_setParameter, + * since this version sets windowSize, and the other sets windowLog */ +size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize) +{ + ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax); + size_t const min = (size_t)1 << bounds.lowerBound; + size_t const max = (size_t)1 << bounds.upperBound; + RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, ""); + RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound, ""); + RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound, ""); + dctx->maxWindowSize = maxWindowSize; + return 0; +} + +size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format) +{ + return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, (int)format); +} + +ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam) +{ + ZSTD_bounds bounds = { 0, 0, 0 }; + switch(dParam) { + case ZSTD_d_windowLogMax: + bounds.lowerBound = ZSTD_WINDOWLOG_ABSOLUTEMIN; + bounds.upperBound = ZSTD_WINDOWLOG_MAX; + return bounds; + case ZSTD_d_format: + bounds.lowerBound = (int)ZSTD_f_zstd1; + bounds.upperBound = (int)ZSTD_f_zstd1_magicless; + ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless); + return bounds; + case ZSTD_d_stableOutBuffer: + bounds.lowerBound = (int)ZSTD_bm_buffered; + bounds.upperBound = (int)ZSTD_bm_stable; + return bounds; + case ZSTD_d_forceIgnoreChecksum: + bounds.lowerBound = (int)ZSTD_d_validateChecksum; + bounds.upperBound = (int)ZSTD_d_ignoreChecksum; + return bounds; + case ZSTD_d_refMultipleDDicts: + bounds.lowerBound = (int)ZSTD_rmd_refSingleDDict; + bounds.upperBound = (int)ZSTD_rmd_refMultipleDDicts; + return bounds; + case ZSTD_d_disableHuffmanAssembly: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + case ZSTD_d_maxBlockSize: + bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN; + bounds.upperBound = ZSTD_BLOCKSIZE_MAX; + return bounds; + + default:; + } + bounds.error = ERROR(parameter_unsupported); + return bounds; +} + +/* ZSTD_dParam_withinBounds: + * @return 1 if value is within dParam bounds, + * 0 otherwise */ +static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value) +{ + ZSTD_bounds const bounds = ZSTD_dParam_getBounds(dParam); + if (ZSTD_isError(bounds.error)) return 0; + if (value < bounds.lowerBound) return 0; + if (value > bounds.upperBound) return 0; + return 1; +} + +#define CHECK_DBOUNDS(p,v) { \ + RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound, ""); \ +} + +size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value) +{ + switch (param) { + case ZSTD_d_windowLogMax: + *value = (int)ZSTD_highbit32((U32)dctx->maxWindowSize); + return 0; + case ZSTD_d_format: + *value = (int)dctx->format; + return 0; + case ZSTD_d_stableOutBuffer: + *value = (int)dctx->outBufferMode; + return 0; + case ZSTD_d_forceIgnoreChecksum: + *value = (int)dctx->forceIgnoreChecksum; + return 0; + case ZSTD_d_refMultipleDDicts: + *value = (int)dctx->refMultipleDDicts; + return 0; + case ZSTD_d_disableHuffmanAssembly: + *value = (int)dctx->disableHufAsm; + return 0; + case ZSTD_d_maxBlockSize: + *value = dctx->maxBlockSizeParam; + return 0; + default:; + } + RETURN_ERROR(parameter_unsupported, ""); +} + +size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value) +{ + RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, ""); + switch(dParam) { + case ZSTD_d_windowLogMax: + if (value == 0) value = ZSTD_WINDOWLOG_LIMIT_DEFAULT; + CHECK_DBOUNDS(ZSTD_d_windowLogMax, value); + dctx->maxWindowSize = ((size_t)1) << value; + return 0; + case ZSTD_d_format: + CHECK_DBOUNDS(ZSTD_d_format, value); + dctx->format = (ZSTD_format_e)value; + return 0; + case ZSTD_d_stableOutBuffer: + CHECK_DBOUNDS(ZSTD_d_stableOutBuffer, value); + dctx->outBufferMode = (ZSTD_bufferMode_e)value; + return 0; + case ZSTD_d_forceIgnoreChecksum: + CHECK_DBOUNDS(ZSTD_d_forceIgnoreChecksum, value); + dctx->forceIgnoreChecksum = (ZSTD_forceIgnoreChecksum_e)value; + return 0; + case ZSTD_d_refMultipleDDicts: + CHECK_DBOUNDS(ZSTD_d_refMultipleDDicts, value); + if (dctx->staticSize != 0) { + RETURN_ERROR(parameter_unsupported, "Static dctx does not support multiple DDicts!"); + } + dctx->refMultipleDDicts = (ZSTD_refMultipleDDicts_e)value; + return 0; + case ZSTD_d_disableHuffmanAssembly: + CHECK_DBOUNDS(ZSTD_d_disableHuffmanAssembly, value); + dctx->disableHufAsm = value != 0; + return 0; + case ZSTD_d_maxBlockSize: + if (value != 0) CHECK_DBOUNDS(ZSTD_d_maxBlockSize, value); + dctx->maxBlockSizeParam = value; + return 0; + default:; + } + RETURN_ERROR(parameter_unsupported, ""); +} + +size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset) +{ + if ( (reset == ZSTD_reset_session_only) + || (reset == ZSTD_reset_session_and_parameters) ) { + dctx->streamStage = zdss_init; + dctx->noForwardProgress = 0; + dctx->isFrameDecompression = 1; + } + if ( (reset == ZSTD_reset_parameters) + || (reset == ZSTD_reset_session_and_parameters) ) { + RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, ""); + ZSTD_clearDict(dctx); + ZSTD_DCtx_resetParameters(dctx); + } + return 0; +} + + +size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx) +{ + return ZSTD_sizeof_DCtx(dctx); +} + +static size_t ZSTD_decodingBufferSize_internal(unsigned long long windowSize, unsigned long long frameContentSize, size_t blockSizeMax) +{ + size_t const blockSize = MIN((size_t)MIN(windowSize, ZSTD_BLOCKSIZE_MAX), blockSizeMax); + /* We need blockSize + WILDCOPY_OVERLENGTH worth of buffer so that if a block + * ends at windowSize + WILDCOPY_OVERLENGTH + 1 bytes, we can start writing + * the block at the beginning of the output buffer, and maintain a full window. + * + * We need another blockSize worth of buffer so that we can store split + * literals at the end of the block without overwriting the extDict window. + */ + unsigned long long const neededRBSize = windowSize + (blockSize * 2) + (WILDCOPY_OVERLENGTH * 2); + unsigned long long const neededSize = MIN(frameContentSize, neededRBSize); + size_t const minRBSize = (size_t) neededSize; + RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize, + frameParameter_windowTooLarge, ""); + return minRBSize; +} + +size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize) +{ + return ZSTD_decodingBufferSize_internal(windowSize, frameContentSize, ZSTD_BLOCKSIZE_MAX); +} + +size_t ZSTD_estimateDStreamSize(size_t windowSize) +{ + size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX); + size_t const inBuffSize = blockSize; /* no block can be larger */ + size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN); + return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize; +} + +size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize) +{ + U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable, but requires an additional parameter (or a dctx) */ + ZSTD_FrameHeader zfh; + size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize); + if (ZSTD_isError(err)) return err; + RETURN_ERROR_IF(err>0, srcSize_wrong, ""); + RETURN_ERROR_IF(zfh.windowSize > windowSizeMax, + frameParameter_windowTooLarge, ""); + return ZSTD_estimateDStreamSize((size_t)zfh.windowSize); +} + + +/* ***** Decompression ***** */ + +static int ZSTD_DCtx_isOverflow(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize) +{ + return (zds->inBuffSize + zds->outBuffSize) >= (neededInBuffSize + neededOutBuffSize) * ZSTD_WORKSPACETOOLARGE_FACTOR; +} + +static void ZSTD_DCtx_updateOversizedDuration(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize) +{ + if (ZSTD_DCtx_isOverflow(zds, neededInBuffSize, neededOutBuffSize)) + zds->oversizedDuration++; + else + zds->oversizedDuration = 0; +} + +static int ZSTD_DCtx_isOversizedTooLong(ZSTD_DStream* zds) +{ + return zds->oversizedDuration >= ZSTD_WORKSPACETOOLARGE_MAXDURATION; +} + +/* Checks that the output buffer hasn't changed if ZSTD_obm_stable is used. */ +static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const* output) +{ + ZSTD_outBuffer const expect = zds->expectedOutBuffer; + /* No requirement when ZSTD_obm_stable is not enabled. */ + if (zds->outBufferMode != ZSTD_bm_stable) + return 0; + /* Any buffer is allowed in zdss_init, this must be the same for every other call until + * the context is reset. + */ + if (zds->streamStage == zdss_init) + return 0; + /* The buffer must match our expectation exactly. */ + if (expect.dst == output->dst && expect.pos == output->pos && expect.size == output->size) + return 0; + RETURN_ERROR(dstBuffer_wrong, "ZSTD_d_stableOutBuffer enabled but output differs!"); +} + +/* Calls ZSTD_decompressContinue() with the right parameters for ZSTD_decompressStream() + * and updates the stage and the output buffer state. This call is extracted so it can be + * used both when reading directly from the ZSTD_inBuffer, and in buffered input mode. + * NOTE: You must break after calling this function since the streamStage is modified. + */ +static size_t ZSTD_decompressContinueStream( + ZSTD_DStream* zds, char** op, char* oend, + void const* src, size_t srcSize) { + int const isSkipFrame = ZSTD_isSkipFrame(zds); + if (zds->outBufferMode == ZSTD_bm_buffered) { + size_t const dstSize = isSkipFrame ? 0 : zds->outBuffSize - zds->outStart; + size_t const decodedSize = ZSTD_decompressContinue(zds, + zds->outBuff + zds->outStart, dstSize, src, srcSize); + FORWARD_IF_ERROR(decodedSize, ""); + if (!decodedSize && !isSkipFrame) { + zds->streamStage = zdss_read; + } else { + zds->outEnd = zds->outStart + decodedSize; + zds->streamStage = zdss_flush; + } + } else { + /* Write directly into the output buffer */ + size_t const dstSize = isSkipFrame ? 0 : (size_t)(oend - *op); + size_t const decodedSize = ZSTD_decompressContinue(zds, *op, dstSize, src, srcSize); + FORWARD_IF_ERROR(decodedSize, ""); + *op += decodedSize; + /* Flushing is not needed. */ + zds->streamStage = zdss_read; + assert(*op <= oend); + assert(zds->outBufferMode == ZSTD_bm_stable); + } + return 0; +} + +size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + const char* const src = (const char*)input->src; + const char* const istart = input->pos != 0 ? src + input->pos : src; + const char* const iend = input->size != 0 ? src + input->size : src; + const char* ip = istart; + char* const dst = (char*)output->dst; + char* const ostart = output->pos != 0 ? dst + output->pos : dst; + char* const oend = output->size != 0 ? dst + output->size : dst; + char* op = ostart; + U32 someMoreWork = 1; + + DEBUGLOG(5, "ZSTD_decompressStream"); + assert(zds != NULL); + RETURN_ERROR_IF( + input->pos > input->size, + srcSize_wrong, + "forbidden. in: pos: %u vs size: %u", + (U32)input->pos, (U32)input->size); + RETURN_ERROR_IF( + output->pos > output->size, + dstSize_tooSmall, + "forbidden. out: pos: %u vs size: %u", + (U32)output->pos, (U32)output->size); + DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos)); + FORWARD_IF_ERROR(ZSTD_checkOutBuffer(zds, output), ""); + + while (someMoreWork) { + switch(zds->streamStage) + { + case zdss_init : + DEBUGLOG(5, "stage zdss_init => transparent reset "); + zds->streamStage = zdss_loadHeader; + zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + zds->legacyVersion = 0; +#endif + zds->hostageByte = 0; + zds->expectedOutBuffer = *output; + ZSTD_FALLTHROUGH; + + case zdss_loadHeader : + DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip)); +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + if (zds->legacyVersion) { + RETURN_ERROR_IF(zds->staticSize, memory_allocation, + "legacy support is incompatible with static dctx"); + { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input); + if (hint==0) zds->streamStage = zdss_init; + return hint; + } } +#endif + { size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format); + if (zds->refMultipleDDicts && zds->ddictSet) { + ZSTD_DCtx_selectFrameDDict(zds); + } + if (ZSTD_isError(hSize)) { +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart); + if (legacyVersion) { + ZSTD_DDict const* const ddict = ZSTD_getDDict(zds); + const void* const dict = ddict ? ZSTD_DDict_dictContent(ddict) : NULL; + size_t const dictSize = ddict ? ZSTD_DDict_dictSize(ddict) : 0; + DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion); + RETURN_ERROR_IF(zds->staticSize, memory_allocation, + "legacy support is incompatible with static dctx"); + FORWARD_IF_ERROR(ZSTD_initLegacyStream(&zds->legacyContext, + zds->previousLegacyVersion, legacyVersion, + dict, dictSize), ""); + zds->legacyVersion = zds->previousLegacyVersion = legacyVersion; + { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input); + if (hint==0) zds->streamStage = zdss_init; /* or stay in stage zdss_loadHeader */ + return hint; + } } +#endif + return hSize; /* error */ + } + if (hSize != 0) { /* need more input */ + size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */ + size_t const remainingInput = (size_t)(iend-ip); + assert(iend >= ip); + if (toLoad > remainingInput) { /* not enough input to load full header */ + if (remainingInput > 0) { + ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput); + zds->lhSize += remainingInput; + } + input->pos = input->size; + /* check first few bytes */ + FORWARD_IF_ERROR( + ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format), + "First few bytes detected incorrect" ); + /* return hint input size */ + return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ + } + assert(ip != NULL); + ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad; + break; + } } + + /* check for single-pass mode opportunity */ + if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN + && zds->fParams.frameType != ZSTD_skippableFrame + && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) { + size_t const cSize = ZSTD_findFrameCompressedSize_advanced(istart, (size_t)(iend-istart), zds->format); + if (cSize <= (size_t)(iend-istart)) { + /* shortcut : using single-pass mode */ + size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds)); + if (ZSTD_isError(decompressedSize)) return decompressedSize; + DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()"); + assert(istart != NULL); + ip = istart + cSize; + op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */ + zds->expected = 0; + zds->streamStage = zdss_init; + someMoreWork = 0; + break; + } } + + /* Check output buffer is large enough for ZSTD_odm_stable. */ + if (zds->outBufferMode == ZSTD_bm_stable + && zds->fParams.frameType != ZSTD_skippableFrame + && zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN + && (U64)(size_t)(oend-op) < zds->fParams.frameContentSize) { + RETURN_ERROR(dstSize_tooSmall, "ZSTD_obm_stable passed but ZSTD_outBuffer is too small"); + } + + /* Consume header (see ZSTDds_decodeFrameHeader) */ + DEBUGLOG(4, "Consume header"); + FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)), ""); + + if (zds->format == ZSTD_f_zstd1 + && (MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ + zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE); + zds->stage = ZSTDds_skipFrame; + } else { + FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize), ""); + zds->expected = ZSTD_blockHeaderSize; + zds->stage = ZSTDds_decodeBlockHeader; + } + + /* control buffer memory usage */ + DEBUGLOG(4, "Control max memory usage (%u KB <= max %u KB)", + (U32)(zds->fParams.windowSize >>10), + (U32)(zds->maxWindowSize >> 10) ); + zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); + RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize, + frameParameter_windowTooLarge, ""); + if (zds->maxBlockSizeParam != 0) + zds->fParams.blockSizeMax = MIN(zds->fParams.blockSizeMax, (unsigned)zds->maxBlockSizeParam); + + /* Adapt buffer sizes to frame header instructions */ + { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */); + size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered + ? ZSTD_decodingBufferSize_internal(zds->fParams.windowSize, zds->fParams.frameContentSize, zds->fParams.blockSizeMax) + : 0; + + ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize); + + { int const tooSmall = (zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize); + int const tooLarge = ZSTD_DCtx_isOversizedTooLong(zds); + + if (tooSmall || tooLarge) { + size_t const bufferSize = neededInBuffSize + neededOutBuffSize; + DEBUGLOG(4, "inBuff : from %u to %u", + (U32)zds->inBuffSize, (U32)neededInBuffSize); + DEBUGLOG(4, "outBuff : from %u to %u", + (U32)zds->outBuffSize, (U32)neededOutBuffSize); + if (zds->staticSize) { /* static DCtx */ + DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize); + assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */ + RETURN_ERROR_IF( + bufferSize > zds->staticSize - sizeof(ZSTD_DCtx), + memory_allocation, ""); + } else { + ZSTD_customFree(zds->inBuff, zds->customMem); + zds->inBuffSize = 0; + zds->outBuffSize = 0; + zds->inBuff = (char*)ZSTD_customMalloc(bufferSize, zds->customMem); + RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation, ""); + } + zds->inBuffSize = neededInBuffSize; + zds->outBuff = zds->inBuff + zds->inBuffSize; + zds->outBuffSize = neededOutBuffSize; + } } } + zds->streamStage = zdss_read; + ZSTD_FALLTHROUGH; + + case zdss_read: + DEBUGLOG(5, "stage zdss_read"); + { size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip)); + DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize); + if (neededInSize==0) { /* end of frame */ + zds->streamStage = zdss_init; + someMoreWork = 0; + break; + } + if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */ + FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), ""); + assert(ip != NULL); + ip += neededInSize; + /* Function modifies the stage so we must break */ + break; + } } + if (ip==iend) { someMoreWork = 0; break; } /* no more input */ + zds->streamStage = zdss_load; + ZSTD_FALLTHROUGH; + + case zdss_load: + { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); + size_t const toLoad = neededInSize - zds->inPos; + int const isSkipFrame = ZSTD_isSkipFrame(zds); + size_t loadedSize; + /* At this point we shouldn't be decompressing a block that we can stream. */ + assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip))); + if (isSkipFrame) { + loadedSize = MIN(toLoad, (size_t)(iend-ip)); + } else { + RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos, + corruption_detected, + "should never happen"); + loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip)); + } + if (loadedSize != 0) { + /* ip may be NULL */ + ip += loadedSize; + zds->inPos += loadedSize; + } + if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */ + + /* decode loaded input */ + zds->inPos = 0; /* input is consumed */ + FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, zds->inBuff, neededInSize), ""); + /* Function modifies the stage so we must break */ + break; + } + case zdss_flush: + { + size_t const toFlushSize = zds->outEnd - zds->outStart; + size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize); + + op = op ? op + flushedSize : op; + + zds->outStart += flushedSize; + if (flushedSize == toFlushSize) { /* flush completed */ + zds->streamStage = zdss_read; + if ( (zds->outBuffSize < zds->fParams.frameContentSize) + && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) { + DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)", + (int)(zds->outBuffSize - zds->outStart), + (U32)zds->fParams.blockSizeMax); + zds->outStart = zds->outEnd = 0; + } + break; + } } + /* cannot complete flush */ + someMoreWork = 0; + break; + + default: + assert(0); /* impossible */ + RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */ + } } + + /* result */ + input->pos = (size_t)(ip - (const char*)(input->src)); + output->pos = (size_t)(op - (char*)(output->dst)); + + /* Update the expected output buffer for ZSTD_obm_stable. */ + zds->expectedOutBuffer = *output; + + if ((ip==istart) && (op==ostart)) { /* no forward progress */ + zds->noForwardProgress ++; + if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) { + RETURN_ERROR_IF(op==oend, noForwardProgress_destFull, ""); + RETURN_ERROR_IF(ip==iend, noForwardProgress_inputEmpty, ""); + assert(0); + } + } else { + zds->noForwardProgress = 0; + } + { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds); + if (!nextSrcSizeHint) { /* frame fully decoded */ + if (zds->outEnd == zds->outStart) { /* output fully flushed */ + if (zds->hostageByte) { + if (input->pos >= input->size) { + /* can't release hostage (not present) */ + zds->streamStage = zdss_read; + return 1; + } + input->pos++; /* release hostage */ + } /* zds->hostageByte */ + return 0; + } /* zds->outEnd == zds->outStart */ + if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */ + input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */ + zds->hostageByte=1; + } + return 1; + } /* nextSrcSizeHint==0 */ + nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block); /* preload header of next block */ + assert(zds->inPos <= nextSrcSizeHint); + nextSrcSizeHint -= zds->inPos; /* part already loaded*/ + return nextSrcSizeHint; + } +} + +size_t ZSTD_decompressStream_simpleArgs ( + ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, size_t* dstPos, + const void* src, size_t srcSize, size_t* srcPos) +{ + ZSTD_outBuffer output; + ZSTD_inBuffer input; + output.dst = dst; + output.size = dstCapacity; + output.pos = *dstPos; + input.src = src; + input.size = srcSize; + input.pos = *srcPos; + { size_t const cErr = ZSTD_decompressStream(dctx, &output, &input); + *dstPos = output.pos; + *srcPos = input.pos; + return cErr; + } +} diff --git a/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_block.c b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_block.c new file mode 100644 index 000000000..862785a49 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_block.c @@ -0,0 +1,2209 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* zstd_decompress_block : + * this module takes care of decompressing _compressed_ block */ + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/compiler.h" /* prefetch */ +#include "../common/cpu.h" /* bmi2 */ +#include "../common/mem.h" /* low level memory routines */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include "../common/zstd_internal.h" +#include "zstd_decompress_internal.h" /* ZSTD_DCtx */ +#include "zstd_ddict.h" /* ZSTD_DDictDictContent */ +#include "zstd_decompress_block.h" +#include "../common/bits.h" /* ZSTD_highbit32 */ + +/*_******************************************************* +* Macros +**********************************************************/ + +/* These two optional macros force the use one way or another of the two + * ZSTD_decompressSequences implementations. You can't force in both directions + * at the same time. + */ +#if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) +#error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!" +#endif + + +/*_******************************************************* +* Memory operations +**********************************************************/ +static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); } + + +/*-************************************************************* + * Block decoding + ***************************************************************/ + +static size_t ZSTD_blockSizeMax(ZSTD_DCtx const* dctx) +{ + size_t const blockSizeMax = dctx->isFrameDecompression ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX; + assert(blockSizeMax <= ZSTD_BLOCKSIZE_MAX); + return blockSizeMax; +} + +/*! ZSTD_getcBlockSize() : + * Provides the size of compressed block from block header `src` */ +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, + blockProperties_t* bpPtr) +{ + RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong, ""); + + { U32 const cBlockHeader = MEM_readLE24(src); + U32 const cSize = cBlockHeader >> 3; + bpPtr->lastBlock = cBlockHeader & 1; + bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3); + bpPtr->origSize = cSize; /* only useful for RLE */ + if (bpPtr->blockType == bt_rle) return 1; + RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected, ""); + return cSize; + } +} + +/* Allocate buffer for literals, either overlapping current dst, or split between dst and litExtraBuffer, or stored entirely within litExtraBuffer */ +static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize, + const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately) +{ + size_t const blockSizeMax = ZSTD_blockSizeMax(dctx); + assert(litSize <= blockSizeMax); + assert(dctx->isFrameDecompression || streaming == not_streaming); + assert(expectedWriteSize <= blockSizeMax); + if (streaming == not_streaming && dstCapacity > blockSizeMax + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) { + /* If we aren't streaming, we can just put the literals after the output + * of the current block. We don't need to worry about overwriting the + * extDict of our window, because it doesn't exist. + * So if we have space after the end of the block, just put it there. + */ + dctx->litBuffer = (BYTE*)dst + blockSizeMax + WILDCOPY_OVERLENGTH; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_in_dst; + } else if (litSize <= ZSTD_LITBUFFEREXTRASIZE) { + /* Literals fit entirely within the extra buffer, put them there to avoid + * having to split the literals. + */ + dctx->litBuffer = dctx->litExtraBuffer; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; + } else { + assert(blockSizeMax > ZSTD_LITBUFFEREXTRASIZE); + /* Literals must be split between the output block and the extra lit + * buffer. We fill the extra lit buffer with the tail of the literals, + * and put the rest of the literals at the end of the block, with + * WILDCOPY_OVERLENGTH of buffer room to allow for overreads. + * This MUST not write more than our maxBlockSize beyond dst, because in + * streaming mode, that could overwrite part of our extDict window. + */ + if (splitImmediately) { + /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */ + dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; + dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE; + } else { + /* initially this will be stored entirely in dst during huffman decoding, it will partially be shifted to litExtraBuffer after */ + dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize; + dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize; + } + dctx->litBufferLocation = ZSTD_split; + assert(dctx->litBufferEnd <= (BYTE*)dst + expectedWriteSize); + } +} + +/*! ZSTD_decodeLiteralsBlock() : + * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored + * in the dstBuffer. If there is room to do so, it will be stored in full in the excess dst space after where the current + * block will be output. Otherwise it will be stored at the end of the current dst blockspace, with a small portion being + * stored in dctx->litExtraBuffer to help keep it "ahead" of the current output write. + * + * @return : nb of bytes read from src (< srcSize ) + * note : symbol not declared but exposed for fullbench */ +static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */ + void* dst, size_t dstCapacity, const streaming_operation streaming) +{ + DEBUGLOG(5, "ZSTD_decodeLiteralsBlock"); + RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, ""); + + { const BYTE* const istart = (const BYTE*) src; + SymbolEncodingType_e const litEncType = (SymbolEncodingType_e)(istart[0] & 3); + size_t const blockSizeMax = ZSTD_blockSizeMax(dctx); + + switch(litEncType) + { + case set_repeat: + DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block"); + RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, ""); + ZSTD_FALLTHROUGH; + + case set_compressed: + RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need up to 5 for case 3"); + { size_t lhSize, litSize, litCSize; + U32 singleStream=0; + U32 const lhlCode = (istart[0] >> 2) & 3; + U32 const lhc = MEM_readLE32(istart); + size_t hufSuccess; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + int const flags = 0 + | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0) + | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0); + switch(lhlCode) + { + case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */ + /* 2 - 2 - 10 - 10 */ + singleStream = !lhlCode; + lhSize = 3; + litSize = (lhc >> 4) & 0x3FF; + litCSize = (lhc >> 14) & 0x3FF; + break; + case 2: + /* 2 - 2 - 14 - 14 */ + lhSize = 4; + litSize = (lhc >> 4) & 0x3FFF; + litCSize = lhc >> 18; + break; + case 3: + /* 2 - 2 - 18 - 18 */ + lhSize = 5; + litSize = (lhc >> 4) & 0x3FFFF; + litCSize = (lhc >> 22) + ((size_t)istart[4] << 10); + break; + } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + if (!singleStream) + RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong, + "Not enough literals (%zu) for the 4-streams mode (min %u)", + litSize, MIN_LITERALS_FOR_4_STREAMS); + RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0); + + /* prefetch huffman table if cold */ + if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) { + PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable)); + } + + if (litEncType==set_repeat) { + if (singleStream) { + hufSuccess = HUF_decompress1X_usingDTable( + dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->HUFptr, flags); + } else { + assert(litSize >= MIN_LITERALS_FOR_4_STREAMS); + hufSuccess = HUF_decompress4X_usingDTable( + dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->HUFptr, flags); + } + } else { + if (singleStream) { +#if defined(HUF_FORCE_DECOMPRESS_X2) + hufSuccess = HUF_decompress1X_DCtx_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); +#else + hufSuccess = HUF_decompress1X1_DCtx_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); +#endif + } else { + hufSuccess = HUF_decompress4X_hufOnly_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); + } + } + if (dctx->litBufferLocation == ZSTD_split) + { + assert(litSize > ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE); + dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; + dctx->litBufferEnd -= WILDCOPY_OVERLENGTH; + assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax); + } + + RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, ""); + + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + dctx->litEntropy = 1; + if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable; + return litCSize + lhSize; + } + + case set_basic: + { size_t litSize, lhSize; + U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + switch(lhlCode) + { + case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + litSize = MEM_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize = 3"); + litSize = MEM_readLE24(istart) >> 4; + break; + } + + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); + if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ + RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, ""); + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize - ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memcpy(dctx->litExtraBuffer, istart + lhSize + litSize - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); + } + else + { + ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize); + } + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + return lhSize+litSize; + } + /* direct reference into compressed stream */ + dctx->litPtr = istart+lhSize; + dctx->litSize = litSize; + dctx->litBufferEnd = dctx->litPtr + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; + return lhSize+litSize; + } + + case set_rle: + { U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t litSize, lhSize; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + switch(lhlCode) + { + case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 3"); + litSize = MEM_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 4"); + litSize = MEM_readLE24(istart) >> 4; + break; + } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize - ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memset(dctx->litExtraBuffer, istart[lhSize], ZSTD_LITBUFFEREXTRASIZE); + } + else + { + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize); + } + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + return lhSize+1; + } + default: + RETURN_ERROR(corruption_detected, "impossible"); + } + } +} + +/* Hidden declaration for fullbench */ +size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity); +size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity) +{ + dctx->isFrameDecompression = 0; + return ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, not_streaming); +} + +/* Default FSE distribution tables. + * These are pre-calculated FSE decoding tables using default distributions as defined in specification : + * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions + * They were generated programmatically with following method : + * - start from default distributions, present in /lib/common/zstd_internal.h + * - generate tables normally, using ZSTD_buildFSETable() + * - printout the content of tables + * - prettify output, report below, test with fuzzer to ensure it's correct */ + +/* Default FSE distribution table for Literal Lengths */ +static const ZSTD_seqSymbol LL_defaultDTable[(1<tableLog = 0; + DTableH->fastMode = 0; + + cell->nbBits = 0; + cell->nextState = 0; + assert(nbAddBits < 255); + cell->nbAdditionalBits = nbAddBits; + cell->baseValue = baseValue; +} + + +/* ZSTD_buildFSETable() : + * generate FSE decoding table for one symbol (ll, ml or off) + * cannot fail if input is valid => + * all inputs are presumed validated at this stage */ +FORCE_INLINE_TEMPLATE +void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U8* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize) +{ + ZSTD_seqSymbol* const tableDecode = dt+1; + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + + U16* symbolNext = (U16*)wksp; + BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1); + U32 highThreshold = tableSize - 1; + + + /* Sanity Checks */ + assert(maxSymbolValue <= MaxSeq); + assert(tableLog <= MaxFSELog); + assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE); + (void)wkspSize; + /* Init, lay down lowprob symbols */ + { ZSTD_seqSymbol_header DTableH; + DTableH.tableLog = tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + assert(normalizedCounter[s]>=0); + symbolNext[s] = (U16)normalizedCounter[s]; + } } } + ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + assert(tableSize <= 512); + /* Specialized symbol spreading for the case when there are + * no low probability (-1 count) symbols. When compressing + * small blocks we avoid low probability symbols to hit this + * case, since header decoding speed matters more. + */ + if (highThreshold == tableSize - 1) { + size_t const tableMask = tableSize-1; + size_t const step = FSE_TABLESTEP(tableSize); + /* First lay down the symbols in order. + * We use a uint64_t to lay down 8 bytes at a time. This reduces branch + * misses since small blocks generally have small table logs, so nearly + * all symbols have counts <= 8. We ensure we have 8 bytes at the end of + * our buffer to handle the over-write. + */ + { + U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s=0); + pos += (size_t)n; + } + } + /* Now we spread those positions across the table. + * The benefit of doing it in two stages is that we avoid the + * variable size inner loop, which caused lots of branch misses. + * Now we can run through all the positions without any branch misses. + * We unroll the loop twice, since that is what empirically worked best. + */ + { + size_t position = 0; + size_t s; + size_t const unroll = 2; + assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ + for (s = 0; s < (size_t)tableSize; s += unroll) { + size_t u; + for (u = 0; u < unroll; ++u) { + size_t const uPosition = (position + (u * step)) & tableMask; + tableDecode[uPosition].baseValue = spread[s + u]; + } + position = (position + (unroll * step)) & tableMask; + } + assert(position == 0); + } + } else { + U32 const tableMask = tableSize-1; + U32 const step = FSE_TABLESTEP(tableSize); + U32 s, position = 0; + for (s=0; s highThreshold)) position = (position + step) & tableMask; /* lowprob area */ + } } + assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { + U32 u; + for (u=0; u max, corruption_detected, ""); + { U32 const symbol = *(const BYTE*)src; + U32 const baseline = baseValue[symbol]; + U8 const nbBits = nbAdditionalBits[symbol]; + ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits); + } + *DTablePtr = DTableSpace; + return 1; + case set_basic : + *DTablePtr = defaultTable; + return 0; + case set_repeat: + RETURN_ERROR_IF(!flagRepeatTable, corruption_detected, ""); + /* prefetch FSE table if used */ + if (ddictIsCold && (nbSeq > 24 /* heuristic */)) { + const void* const pStart = *DTablePtr; + size_t const pSize = sizeof(ZSTD_seqSymbol) * (SEQSYMBOL_TABLE_SIZE(maxLog)); + PREFETCH_AREA(pStart, pSize); + } + return 0; + case set_compressed : + { unsigned tableLog; + S16 norm[MaxSeq+1]; + size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); + RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected, ""); + RETURN_ERROR_IF(tableLog > maxLog, corruption_detected, ""); + ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog, wksp, wkspSize, bmi2); + *DTablePtr = DTableSpace; + return headerSize; + } + default : + assert(0); + RETURN_ERROR(GENERIC, "impossible"); + } +} + +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, + const void* src, size_t srcSize) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* const iend = istart + srcSize; + const BYTE* ip = istart; + int nbSeq; + DEBUGLOG(5, "ZSTD_decodeSeqHeaders"); + + /* check */ + RETURN_ERROR_IF(srcSize < MIN_SEQUENCES_SIZE, srcSize_wrong, ""); + + /* SeqHead */ + nbSeq = *ip++; + if (nbSeq > 0x7F) { + if (nbSeq == 0xFF) { + RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, ""); + nbSeq = MEM_readLE16(ip) + LONGNBSEQ; + ip+=2; + } else { + RETURN_ERROR_IF(ip >= iend, srcSize_wrong, ""); + nbSeq = ((nbSeq-0x80)<<8) + *ip++; + } + } + *nbSeqPtr = nbSeq; + + if (nbSeq == 0) { + /* No sequence : section ends immediately */ + RETURN_ERROR_IF(ip != iend, corruption_detected, + "extraneous data present in the Sequences section"); + return (size_t)(ip - istart); + } + + /* FSE table descriptors */ + RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */ + RETURN_ERROR_IF(*ip & 3, corruption_detected, ""); /* The last field, Reserved, must be all-zeroes. */ + { SymbolEncodingType_e const LLtype = (SymbolEncodingType_e)(*ip >> 6); + SymbolEncodingType_e const OFtype = (SymbolEncodingType_e)((*ip >> 4) & 3); + SymbolEncodingType_e const MLtype = (SymbolEncodingType_e)((*ip >> 2) & 3); + ip++; + + /* Build DTables */ + { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, + LLtype, MaxLL, LLFSELog, + ip, iend-ip, + LL_base, LL_bits, + LL_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += llhSize; + } + + { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, + OFtype, MaxOff, OffFSELog, + ip, iend-ip, + OF_base, OF_bits, + OF_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += ofhSize; + } + + { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, + MLtype, MaxML, MLFSELog, + ip, iend-ip, + ML_base, ML_bits, + ML_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += mlhSize; + } + } + + return ip-istart; +} + + +typedef struct { + size_t litLength; + size_t matchLength; + size_t offset; +} seq_t; + +typedef struct { + size_t state; + const ZSTD_seqSymbol* table; +} ZSTD_fseState; + +typedef struct { + BIT_DStream_t DStream; + ZSTD_fseState stateLL; + ZSTD_fseState stateOffb; + ZSTD_fseState stateML; + size_t prevOffset[ZSTD_REP_NUM]; +} seqState_t; + +/*! ZSTD_overlapCopy8() : + * Copies 8 bytes from ip to op and updates op and ip where ip <= op. + * If the offset is < 8 then the offset is spread to at least 8 bytes. + * + * Precondition: *ip <= *op + * Postcondition: *op - *op >= 8 + */ +HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) { + assert(*ip <= *op); + if (offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ + static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ + int const sub2 = dec64table[offset]; + (*op)[0] = (*ip)[0]; + (*op)[1] = (*ip)[1]; + (*op)[2] = (*ip)[2]; + (*op)[3] = (*ip)[3]; + *ip += dec32table[offset]; + ZSTD_copy4(*op+4, *ip); + *ip -= sub2; + } else { + ZSTD_copy8(*op, *ip); + } + *ip += 8; + *op += 8; + assert(*op - *ip >= 8); +} + +/*! ZSTD_safecopy() : + * Specialized version of memcpy() that is allowed to READ up to WILDCOPY_OVERLENGTH past the input buffer + * and write up to 16 bytes past oend_w (op >= oend_w is allowed). + * This function is only called in the uncommon case where the sequence is near the end of the block. It + * should be fast for a single long sequence, but can be slow for several short sequences. + * + * @param ovtype controls the overlap detection + * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart. + * - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart. + * The src buffer must be before the dst buffer. + */ +static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) { + ptrdiff_t const diff = op - ip; + BYTE* const oend = op + length; + + assert((ovtype == ZSTD_no_overlap && (diff <= -8 || diff >= 8 || op >= oend_w)) || + (ovtype == ZSTD_overlap_src_before_dst && diff >= 0)); + + if (length < 8) { + /* Handle short lengths. */ + while (op < oend) *op++ = *ip++; + return; + } + if (ovtype == ZSTD_overlap_src_before_dst) { + /* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */ + assert(length >= 8); + ZSTD_overlapCopy8(&op, &ip, diff); + length -= 8; + assert(op - ip >= 8); + assert(op <= oend); + } + + if (oend <= oend_w) { + /* No risk of overwrite. */ + ZSTD_wildcopy(op, ip, length, ovtype); + return; + } + if (op <= oend_w) { + /* Wildcopy until we get close to the end. */ + assert(oend > oend_w); + ZSTD_wildcopy(op, ip, oend_w - op, ovtype); + ip += oend_w - op; + op += oend_w - op; + } + /* Handle the leftovers. */ + while (op < oend) *op++ = *ip++; +} + +/* ZSTD_safecopyDstBeforeSrc(): + * This version allows overlap with dst before src, or handles the non-overlap case with dst after src + * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */ +static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length) { + ptrdiff_t const diff = op - ip; + BYTE* const oend = op + length; + + if (length < 8 || diff > -8) { + /* Handle short lengths, close overlaps, and dst not before src. */ + while (op < oend) *op++ = *ip++; + return; + } + + if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) { + ZSTD_wildcopy(op, ip, oend - WILDCOPY_OVERLENGTH - op, ZSTD_no_overlap); + ip += oend - WILDCOPY_OVERLENGTH - op; + op += oend - WILDCOPY_OVERLENGTH - op; + } + + /* Handle the leftovers. */ + while (op < oend) *op++ = *ip++; +} + +/* ZSTD_execSequenceEnd(): + * This version handles cases that are near the end of the output buffer. It requires + * more careful checks to make sure there is no overflow. By separating out these hard + * and unlikely cases, we can speed up the common cases. + * + * NOTE: This function needs to be fast for a single long sequence, but doesn't need + * to be optimized for many small sequences, since those fall into ZSTD_execSequence(). + */ +FORCE_NOINLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceEnd(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; + + /* bounds checks : careful of address space overflow in 32-bit mode */ + RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer"); + RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer"); + assert(op < op + sequenceLength); + assert(oLitEnd < op + sequenceLength); + + /* copy literals */ + ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap); + op = oLitEnd; + *litPtr = iLitEnd; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix */ + RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); + match = dictEnd - (prefixStart - match); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst); + return sequenceLength; +} + +/* ZSTD_execSequenceEndSplitLitBuffer(): + * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case. + */ +FORCE_NOINLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op, + BYTE* const oend, const BYTE* const oend_w, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + + /* bounds checks : careful of address space overflow in 32-bit mode */ + RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer"); + RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer"); + assert(op < op + sequenceLength); + assert(oLitEnd < op + sequenceLength); + + /* copy literals */ + RETURN_ERROR_IF(op > *litPtr && op < *litPtr + sequence.litLength, dstSize_tooSmall, "output should not catch up to and overwrite literal buffer"); + ZSTD_safecopyDstBeforeSrc(op, *litPtr, sequence.litLength); + op = oLitEnd; + *litPtr = iLitEnd; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix */ + RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); + match = dictEnd - (prefixStart - match); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst); + return sequenceLength; +} + +HINT_INLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequence(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; /* risk : address space underflow on oend=NULL */ + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + assert(op != NULL /* Precondition */); + assert(oend_w < oend /* No underflow */); + +#if defined(__aarch64__) + /* prefetch sequence starting from match that will be used for copy later */ + PREFETCH_L1(match); +#endif + /* Handle edge cases in a slow path: + * - Read beyond end of literals + * - Match end is within WILDCOPY_OVERLIMIT of oend + * - 32-bit mode and the match length overflows + */ + if (UNLIKELY( + iLitEnd > litLimit || + oMatchEnd > oend_w || + (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) + return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + + /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ + assert(op <= oLitEnd /* No overflow */); + assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */); + assert(oMatchEnd <= oend /* No underflow */); + assert(iLitEnd <= litLimit /* Literal length is in bounds */); + assert(oLitEnd <= oend_w /* Can wildcopy literals */); + assert(oMatchEnd <= oend_w /* Can wildcopy matches */); + + /* Copy Literals: + * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9. + * We likely don't need the full 32-byte wildcopy. + */ + assert(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(op, (*litPtr)); + if (UNLIKELY(sequence.litLength > 16)) { + ZSTD_wildcopy(op + 16, (*litPtr) + 16, sequence.litLength - 16, ZSTD_no_overlap); + } + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* Copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix -> go into extDict */ + RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); + match = dictEnd + (match - prefixStart); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + /* Match within prefix of 1 or more bytes */ + assert(op <= oMatchEnd); + assert(oMatchEnd <= oend_w); + assert(match >= prefixStart); + assert(sequence.matchLength >= 1); + + /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy + * without overlap checking. + */ + if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) { + /* We bet on a full wildcopy for matches, since we expect matches to be + * longer than literals (in general). In silesia, ~10% of matches are longer + * than 16 bytes. + */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap); + return sequenceLength; + } + assert(sequence.offset < WILDCOPY_VECLEN); + + /* Copy 8 bytes and spread the offset to be >= 8. */ + ZSTD_overlapCopy8(&op, &match, sequence.offset); + + /* If the match length is > 8 bytes, then continue with the wildcopy. */ + if (sequence.matchLength > 8) { + assert(op < oMatchEnd); + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8, ZSTD_overlap_src_before_dst); + } + return sequenceLength; +} + +HINT_INLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op, + BYTE* const oend, const BYTE* const oend_w, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + assert(op != NULL /* Precondition */); + assert(oend_w < oend /* No underflow */); + /* Handle edge cases in a slow path: + * - Read beyond end of literals + * - Match end is within WILDCOPY_OVERLIMIT of oend + * - 32-bit mode and the match length overflows + */ + if (UNLIKELY( + iLitEnd > litLimit || + oMatchEnd > oend_w || + (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) + return ZSTD_execSequenceEndSplitLitBuffer(op, oend, oend_w, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + + /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ + assert(op <= oLitEnd /* No overflow */); + assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */); + assert(oMatchEnd <= oend /* No underflow */); + assert(iLitEnd <= litLimit /* Literal length is in bounds */); + assert(oLitEnd <= oend_w /* Can wildcopy literals */); + assert(oMatchEnd <= oend_w /* Can wildcopy matches */); + + /* Copy Literals: + * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9. + * We likely don't need the full 32-byte wildcopy. + */ + assert(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(op, (*litPtr)); + if (UNLIKELY(sequence.litLength > 16)) { + ZSTD_wildcopy(op+16, (*litPtr)+16, sequence.litLength-16, ZSTD_no_overlap); + } + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* Copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix -> go into extDict */ + RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); + match = dictEnd + (match - prefixStart); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } } + /* Match within prefix of 1 or more bytes */ + assert(op <= oMatchEnd); + assert(oMatchEnd <= oend_w); + assert(match >= prefixStart); + assert(sequence.matchLength >= 1); + + /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy + * without overlap checking. + */ + if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) { + /* We bet on a full wildcopy for matches, since we expect matches to be + * longer than literals (in general). In silesia, ~10% of matches are longer + * than 16 bytes. + */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap); + return sequenceLength; + } + assert(sequence.offset < WILDCOPY_VECLEN); + + /* Copy 8 bytes and spread the offset to be >= 8. */ + ZSTD_overlapCopy8(&op, &match, sequence.offset); + + /* If the match length is > 8 bytes, then continue with the wildcopy. */ + if (sequence.matchLength > 8) { + assert(op < oMatchEnd); + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst); + } + return sequenceLength; +} + + +static void +ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt) +{ + const void* ptr = dt; + const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits", + (U32)DStatePtr->state, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +FORCE_INLINE_TEMPLATE void +ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 nextState, U32 nbBits) +{ + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = nextState + lowBits; +} + +/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum + * offset bits. But we can only read at most STREAM_ACCUMULATOR_MIN_32 + * bits before reloading. This value is the maximum number of bytes we read + * after reloading when we are decoding long offsets. + */ +#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \ + (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \ + ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \ + : 0) + +typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; + +/** + * ZSTD_decodeSequence(): + * @p longOffsets : tells the decoder to reload more bit while decoding large offsets + * only used in 32-bit mode + * @return : Sequence (litL + matchL + offset) + */ +FORCE_INLINE_TEMPLATE seq_t +ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq) +{ + seq_t seq; + /* + * ZSTD_seqSymbol is a 64 bits wide structure. + * It can be loaded in one operation + * and its fields extracted by simply shifting or bit-extracting on aarch64. + * GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh + * operations that cause performance drop. This can be avoided by using this + * ZSTD_memcpy hack. + */ +#if defined(__aarch64__) && (defined(__GNUC__) && !defined(__clang__)) + ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS; + ZSTD_seqSymbol* const llDInfo = &llDInfoS; + ZSTD_seqSymbol* const mlDInfo = &mlDInfoS; + ZSTD_seqSymbol* const ofDInfo = &ofDInfoS; + ZSTD_memcpy(llDInfo, seqState->stateLL.table + seqState->stateLL.state, sizeof(ZSTD_seqSymbol)); + ZSTD_memcpy(mlDInfo, seqState->stateML.table + seqState->stateML.state, sizeof(ZSTD_seqSymbol)); + ZSTD_memcpy(ofDInfo, seqState->stateOffb.table + seqState->stateOffb.state, sizeof(ZSTD_seqSymbol)); +#else + const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state; + const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state; + const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state; +#endif + seq.matchLength = mlDInfo->baseValue; + seq.litLength = llDInfo->baseValue; + { U32 const ofBase = ofDInfo->baseValue; + BYTE const llBits = llDInfo->nbAdditionalBits; + BYTE const mlBits = mlDInfo->nbAdditionalBits; + BYTE const ofBits = ofDInfo->nbAdditionalBits; + BYTE const totalBits = llBits+mlBits+ofBits; + + U16 const llNext = llDInfo->nextState; + U16 const mlNext = mlDInfo->nextState; + U16 const ofNext = ofDInfo->nextState; + U32 const llnbBits = llDInfo->nbBits; + U32 const mlnbBits = mlDInfo->nbBits; + U32 const ofnbBits = ofDInfo->nbBits; + + assert(llBits <= MaxLLBits); + assert(mlBits <= MaxMLBits); + assert(ofBits <= MaxOff); + /* + * As gcc has better branch and block analyzers, sometimes it is only + * valuable to mark likeliness for clang, it gives around 3-4% of + * performance. + */ + + /* sequence */ + { size_t offset; + if (ofBits > 1) { + ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); + ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); + ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 > LONG_OFFSETS_MAX_EXTRA_BITS_32); + ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 - LONG_OFFSETS_MAX_EXTRA_BITS_32 >= MaxMLBits); + if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) { + /* Always read extra bits, this keeps the logic simple, + * avoids branches, and avoids accidentally reading 0 bits. + */ + U32 const extraBits = LONG_OFFSETS_MAX_EXTRA_BITS_32; + offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); + BIT_reloadDStream(&seqState->DStream); + offset += BIT_readBitsFast(&seqState->DStream, extraBits); + } else { + offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); + } + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } else { + U32 const ll0 = (llDInfo->baseValue == 0); + if (LIKELY((ofBits == 0))) { + offset = seqState->prevOffset[ll0]; + seqState->prevOffset[1] = seqState->prevOffset[!ll0]; + seqState->prevOffset[0] = offset; + } else { + offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1); + { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp -= !temp; /* 0 is not valid: input corrupted => force offset to -1 => corruption detected at execSequence */ + if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } } } + seq.offset = offset; + } + + if (mlBits > 0) + seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/); + + if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) + BIT_reloadDStream(&seqState->DStream); + if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) + BIT_reloadDStream(&seqState->DStream); + /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ + ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); + + if (llBits > 0) + seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/); + + if (MEM_32bits()) + BIT_reloadDStream(&seqState->DStream); + + DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + + if (!isLastSeq) { + /* don't update FSE state for last Sequence */ + ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */ + BIT_reloadDStream(&seqState->DStream); + } + } + + return seq; +} + +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) +#if DEBUGLEVEL >= 1 +static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd) +{ + size_t const windowSize = dctx->fParams.windowSize; + /* No dictionary used. */ + if (dctx->dictContentEndForFuzzing == NULL) return 0; + /* Dictionary is our prefix. */ + if (prefixStart == dctx->dictContentBeginForFuzzing) return 1; + /* Dictionary is not our ext-dict. */ + if (dctx->dictEnd != dctx->dictContentEndForFuzzing) return 0; + /* Dictionary is not within our window size. */ + if ((size_t)(oLitEnd - prefixStart) >= windowSize) return 0; + /* Dictionary is active. */ + return 1; +} +#endif + +static void ZSTD_assertValidSequence( + ZSTD_DCtx const* dctx, + BYTE const* op, BYTE const* oend, + seq_t const seq, + BYTE const* prefixStart, BYTE const* virtualStart) +{ +#if DEBUGLEVEL >= 1 + if (dctx->isFrameDecompression) { + size_t const windowSize = dctx->fParams.windowSize; + size_t const sequenceSize = seq.litLength + seq.matchLength; + BYTE const* const oLitEnd = op + seq.litLength; + DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + assert(op <= oend); + assert((size_t)(oend - op) >= sequenceSize); + assert(sequenceSize <= ZSTD_blockSizeMax(dctx)); + if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) { + size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing); + /* Offset must be within the dictionary. */ + assert(seq.offset <= (size_t)(oLitEnd - virtualStart)); + assert(seq.offset <= windowSize + dictSize); + } else { + /* Offset must be within our window. */ + assert(seq.offset <= windowSize); + } + } +#else + (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart; +#endif +} +#endif + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG + + +FORCE_INLINE_TEMPLATE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize); + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* litBufferEnd = dctx->litBufferEnd; + const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); + const BYTE* const vBase = (const BYTE*) (dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer (%i seqs)", nbSeq); + + /* Literals are split between internal buffer & output buffer */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i=0; ientropy.rep[i]; } + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + assert(dst != NULL); + + ZSTD_STATIC_ASSERT( + BIT_DStream_unfinished < BIT_DStream_completed && + BIT_DStream_endOfBuffer < BIT_DStream_completed && + BIT_DStream_completed < BIT_DStream_overflow); + + /* decompress without overrunning litPtr begins */ + { seq_t sequence = {0,0,0}; /* some static analyzer believe that @sequence is not initialized (it necessarily is, since for(;;) loop as at least one iteration) */ + /* Align the decompression loop to 32 + 16 bytes. + * + * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression + * speed swings based on the alignment of the decompression loop. This + * performance swing is caused by parts of the decompression loop falling + * out of the DSB. The entire decompression loop should fit in the DSB, + * when it can't we get much worse performance. You can measure if you've + * hit the good case or the bad case with this perf command for some + * compressed file test.zst: + * + * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \ + * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst + * + * If you see most cycles served out of the MITE you've hit the bad case. + * If you see most cycles served out of the DSB you've hit the good case. + * If it is pretty even then you may be in an okay case. + * + * This issue has been reproduced on the following CPUs: + * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9 + * Use Instruments->Counters to get DSB/MITE cycles. + * I never got performance swings, but I was able to + * go from the good case of mostly DSB to half of the + * cycles served from MITE. + * - Coffeelake: Intel i9-9900k + * - Coffeelake: Intel i7-9700k + * + * I haven't been able to reproduce the instability or DSB misses on any + * of the following CPUS: + * - Haswell + * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH + * - Skylake + * + * Alignment is done for each of the three major decompression loops: + * - ZSTD_decompressSequences_bodySplitLitBuffer - presplit section of the literal buffer + * - ZSTD_decompressSequences_bodySplitLitBuffer - postsplit section of the literal buffer + * - ZSTD_decompressSequences_body + * Alignment choices are made to minimize large swings on bad cases and influence on performance + * from changes external to this code, rather than to overoptimize on the current commit. + * + * If you are seeing performance stability this script can help test. + * It tests on 4 commits in zstd where I saw performance change. + * + * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4 + */ +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); +# if __GNUC__ >= 7 + /* good for gcc-7, gcc-9, and gcc-11 */ + __asm__("nop"); + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 4"); +# if __GNUC__ == 8 || __GNUC__ == 10 + /* good for gcc-8 and gcc-10 */ + __asm__("nop"); + __asm__(".p2align 3"); +# endif +# endif +#endif + + /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */ + for ( ; nbSeq; nbSeq--) { + sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + if (litPtr + sequence.litLength > dctx->litBufferEnd) break; + { size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } } + DEBUGLOG(6, "reached: (litPtr + sequence.litLength > dctx->litBufferEnd)"); + + /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */ + if (nbSeq > 0) { + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength); + if (leftoverLit) { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequence.litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + nbSeq--; + } + } + + if (nbSeq > 0) { + /* there is remaining lit from extra buffer */ + +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); + __asm__("nop"); +# if __GNUC__ != 7 + /* worse for gcc-7 better for gcc-8, gcc-9, and gcc-10 and clang */ + __asm__(".p2align 4"); + __asm__("nop"); + __asm__(".p2align 3"); +# elif __GNUC__ >= 11 + __asm__(".p2align 3"); +# else + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 3"); +# endif +#endif + + for ( ; nbSeq ; nbSeq--) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + } + + /* check if reached exact end */ + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq); + RETURN_ERROR_IF(nbSeq, corruption_detected, ""); + DEBUGLOG(5, "bitStream : start=%p, ptr=%p, bitsConsumed=%u", seqState.DStream.start, seqState.DStream.ptr, seqState.DStream.bitsConsumed); + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + if (dctx->litBufferLocation == ZSTD_split) { + /* split hasn't been reached yet, first get dst then copy litExtraBuffer */ + size_t const lastLLSize = (size_t)(litBufferEnd - litPtr); + DEBUGLOG(6, "copy last literals from segment : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + } + /* copy last literals from internal buffer */ + { size_t const lastLLSize = (size_t)(litBufferEnd - litPtr); + DEBUGLOG(6, "copy last literals from internal buffer : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } } + + DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart)); + return (size_t)(op - ostart); +} + +FORCE_INLINE_TEMPLATE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ZSTD_maybeNullPtrAdd(ostart, maxDstSize) : dctx->litBuffer; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart); + const BYTE* const vBase = (const BYTE*)(dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd); + DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq); + + /* Regen sequences */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; } + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + assert(dst != NULL); + +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); + __asm__("nop"); +# if __GNUC__ >= 7 + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 3"); +# else + __asm__(".p2align 4"); + __asm__("nop"); + __asm__(".p2align 3"); +# endif +#endif + + for ( ; nbSeq ; nbSeq--) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + + /* check if reached exact end */ + assert(nbSeq == 0); + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + { size_t const lastLLSize = (size_t)(litEnd - litPtr); + DEBUGLOG(6, "copy last literals : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } } + + DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart)); + return (size_t)(op - ostart); +} + +static size_t +ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + +static size_t +ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT + +FORCE_INLINE_TEMPLATE + +size_t ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence, + const BYTE* const prefixStart, const BYTE* const dictEnd) +{ + prefetchPos += sequence.litLength; + { const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart; + /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. + * No consequence though : memory address is only used for prefetching, not for dereferencing */ + const BYTE* const match = ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, prefetchPos), sequence.offset); + PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */ + } + return prefetchPos + sequence.matchLength; +} + +/* This decoding function employs prefetching + * to reduce latency impact of cache misses. + * It's generally employed when block contains a significant portion of long-distance matches + * or when coupled with a "cold" dictionary */ +FORCE_INLINE_TEMPLATE size_t +ZSTD_decompressSequencesLong_body( + ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ZSTD_maybeNullPtrAdd(ostart, maxDstSize); + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* litBufferEnd = dctx->litBufferEnd; + const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); + const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + + /* Regen sequences */ + if (nbSeq) { +#define STORED_SEQS 8 +#define STORED_SEQS_MASK (STORED_SEQS-1) +#define ADVANCED_SEQS STORED_SEQS + seq_t sequences[STORED_SEQS]; + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); + seqState_t seqState; + int seqNb; + size_t prefetchPos = (size_t)(op-prefixStart); /* track position relative to prefixStart */ + + dctx->fseEntropy = 1; + { int i; for (i=0; ientropy.rep[i]; } + assert(dst != NULL); + assert(iend >= ip); + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + /* prepare in advance */ + for (seqNb=0; seqNblitBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) { + /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */ + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) + { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } } + else + { + /* lit buffer is either wholly contained in first or second split, or not split at all*/ + size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : + ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } + } + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + + /* finish queue */ + seqNb -= seqAdvance; + for ( ; seqNblitBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) { + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequence->litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } + } + else + { + size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence->litLength - WILDCOPY_OVERLENGTH, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : + ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } + } + + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */ + size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + } + { size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + } + + return (size_t)(op - ostart); +} + +static size_t +ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + + + +#if DYNAMIC_BMI2 + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG +static BMI2_TARGET_ATTRIBUTE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +static BMI2_TARGET_ATTRIBUTE size_t +DONT_VECTORIZE +ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT +static BMI2_TARGET_ATTRIBUTE size_t +ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + +#endif /* DYNAMIC_BMI2 */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG +static size_t +ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequences"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +static size_t +ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT +/* ZSTD_decompressSequencesLong() : + * decompression function triggered when a minimum share of offsets is considered "long", + * aka out of cache. + * note : "long" definition seems overloaded here, sometimes meaning "wider than bitstream register", and sometimes meaning "farther than memory cache distance". + * This function will try to mitigate main memory latency through the use of prefetching */ +static size_t +ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequencesLong"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + + +/** + * @returns The total size of the history referenceable by zstd, including + * both the prefix and the extDict. At @p op any offset larger than this + * is invalid. + */ +static size_t ZSTD_totalHistorySize(BYTE* op, BYTE const* virtualStart) +{ + return (size_t)(op - virtualStart); +} + +typedef struct { + unsigned longOffsetShare; + unsigned maxNbAdditionalBits; +} ZSTD_OffsetInfo; + +/* ZSTD_getOffsetInfo() : + * condition : offTable must be valid + * @return : "share" of long offsets (arbitrarily defined as > (1<<23)) + * compared to maximum possible of (1< 22) info.longOffsetShare += 1; + } + + assert(tableLog <= OffFSELog); + info.longOffsetShare <<= (OffFSELog - tableLog); /* scale to OffFSELog */ + } + + return info; +} + +/** + * @returns The maximum offset we can decode in one read of our bitstream, without + * reloading more bits in the middle of the offset bits read. Any offsets larger + * than this must use the long offset decoder. + */ +static size_t ZSTD_maxShortOffset(void) +{ + if (MEM_64bits()) { + /* We can decode any offset without reloading bits. + * This might change if the max window size grows. + */ + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); + return (size_t)-1; + } else { + /* The maximum offBase is (1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1. + * This offBase would require STREAM_ACCUMULATOR_MIN extra bits. + * Then we have to subtract ZSTD_REP_NUM to get the maximum possible offset. + */ + size_t const maxOffbase = ((size_t)1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1; + size_t const maxOffset = maxOffbase - ZSTD_REP_NUM; + assert(ZSTD_highbit32((U32)maxOffbase) == STREAM_ACCUMULATOR_MIN); + return maxOffset; + } +} + +size_t +ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, const streaming_operation streaming) +{ /* blockType == blockCompressed */ + const BYTE* ip = (const BYTE*)src; + DEBUGLOG(5, "ZSTD_decompressBlock_internal (cSize : %u)", (unsigned)srcSize); + + /* Note : the wording of the specification + * allows compressed block to be sized exactly ZSTD_blockSizeMax(dctx). + * This generally does not happen, as it makes little sense, + * since an uncompressed block would feature same size and have no decompression cost. + * Also, note that decoder from reference libzstd before < v1.5.4 + * would consider this edge case as an error. + * As a consequence, avoid generating compressed blocks of size ZSTD_blockSizeMax(dctx) + * for broader compatibility with the deployed ecosystem of zstd decoders */ + RETURN_ERROR_IF(srcSize > ZSTD_blockSizeMax(dctx), srcSize_wrong, ""); + + /* Decode literals section */ + { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming); + DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : cSize=%u, nbLiterals=%zu", (U32)litCSize, dctx->litSize); + if (ZSTD_isError(litCSize)) return litCSize; + ip += litCSize; + srcSize -= litCSize; + } + + /* Build Decoding Tables */ + { + /* Compute the maximum block size, which must also work when !frame and fParams are unset. + * Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t. + */ + size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx)); + size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart); + /* isLongOffset must be true if there are long offsets. + * Offsets are long if they are larger than ZSTD_maxShortOffset(). + * We don't expect that to be the case in 64-bit mode. + * + * We check here to see if our history is large enough to allow long offsets. + * If it isn't, then we can't possible have (valid) long offsets. If the offset + * is invalid, then it is okay to read it incorrectly. + * + * If isLongOffsets is true, then we will later check our decoding table to see + * if it is even possible to generate long offsets. + */ + ZSTD_longOffset_e isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (totalHistorySize > ZSTD_maxShortOffset())); + /* These macros control at build-time which decompressor implementation + * we use. If neither is defined, we do some inspection and dispatch at + * runtime. + */ +#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) + int usePrefetchDecoder = dctx->ddictIsCold; +#else + /* Set to 1 to avoid computing offset info if we don't need to. + * Otherwise this value is ignored. + */ + int usePrefetchDecoder = 1; +#endif + int nbSeq; + size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize); + if (ZSTD_isError(seqHSize)) return seqHSize; + ip += seqHSize; + srcSize -= seqHSize; + + RETURN_ERROR_IF((dst == NULL || dstCapacity == 0) && nbSeq > 0, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(MEM_64bits() && sizeof(size_t) == sizeof(void*) && (size_t)(-1) - (size_t)dst < (size_t)(1 << 20), dstSize_tooSmall, + "invalid dst"); + + /* If we could potentially have long offsets, or we might want to use the prefetch decoder, + * compute information about the share of long offsets, and the maximum nbAdditionalBits. + * NOTE: could probably use a larger nbSeq limit + */ + if (isLongOffset || (!usePrefetchDecoder && (totalHistorySize > (1u << 24)) && (nbSeq > 8))) { + ZSTD_OffsetInfo const info = ZSTD_getOffsetInfo(dctx->OFTptr, nbSeq); + if (isLongOffset && info.maxNbAdditionalBits <= STREAM_ACCUMULATOR_MIN) { + /* If isLongOffset, but the maximum number of additional bits that we see in our table is small + * enough, then we know it is impossible to have too long an offset in this block, so we can + * use the regular offset decoder. + */ + isLongOffset = ZSTD_lo_isRegularOffset; + } + if (!usePrefetchDecoder) { + U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */ + usePrefetchDecoder = (info.longOffsetShare >= minShare); + } + } + + dctx->ddictIsCold = 0; + +#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) + if (usePrefetchDecoder) { +#else + (void)usePrefetchDecoder; + { +#endif +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT + return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); +#endif + } + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG + /* else */ + if (dctx->litBufferLocation == ZSTD_split) + return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); + else + return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); +#endif + } +} + + +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize) +{ + if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */ + dctx->dictEnd = dctx->previousDstEnd; + dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); + dctx->prefixStart = dst; + dctx->previousDstEnd = dst; + } +} + + +size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + size_t dSize; + dctx->isFrameDecompression = 0; + ZSTD_checkContinuity(dctx, dst, dstCapacity); + dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, not_streaming); + FORWARD_IF_ERROR(dSize, ""); + dctx->previousDstEnd = (char*)dst + dSize; + return dSize; +} + + +/* NOTE: Must just wrap ZSTD_decompressBlock_deprecated() */ +size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_decompressBlock_deprecated(dctx, dst, dstCapacity, src, srcSize); +} diff --git a/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_block.h b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_block.h new file mode 100644 index 000000000..ab152404b --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_block.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#ifndef ZSTD_DEC_BLOCK_H +#define ZSTD_DEC_BLOCK_H + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/zstd_deps.h" /* size_t */ +#include "../zstd.h" /* DCtx, and some public functions */ +#include "../common/zstd_internal.h" /* blockProperties_t, and some public functions */ +#include "zstd_decompress_internal.h" /* ZSTD_seqSymbol */ + + +/* === Prototypes === */ + +/* note: prototypes already published within `zstd.h` : + * ZSTD_decompressBlock() + */ + +/* note: prototypes already published within `zstd_internal.h` : + * ZSTD_getcBlockSize() + * ZSTD_decodeSeqHeaders() + */ + + + /* Streaming state is used to inform allocation of the literal buffer */ +typedef enum { + not_streaming = 0, + is_streaming = 1 +} streaming_operation; + +/* ZSTD_decompressBlock_internal() : + * decompress block, starting at `src`, + * into destination buffer `dst`. + * @return : decompressed block size, + * or an error code (which can be tested using ZSTD_isError()) + */ +size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, const streaming_operation streaming); + +/* ZSTD_buildFSETable() : + * generate FSE decoding table for one symbol (ll, ml or off) + * this function must be called with valid parameters only + * (dt is large enough, normalizedCounter distribution total is a power of 2, max is within range, etc.) + * in which case it cannot fail. + * The workspace must be 4-byte aligned and at least ZSTD_BUILD_FSE_TABLE_WKSP_SIZE bytes, which is + * defined in zstd_decompress_internal.h. + * Internal use only. + */ +void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U8* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize, + int bmi2); + +/* Internal definition of ZSTD_decompressBlock() to avoid deprecation warnings. */ +size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + + +#endif /* ZSTD_DEC_BLOCK_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_internal.h b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_internal.h new file mode 100644 index 000000000..e4bffdbc6 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/decompress/zstd_decompress_internal.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* zstd_decompress_internal: + * objects and definitions shared within lib/decompress modules */ + + #ifndef ZSTD_DECOMPRESS_INTERNAL_H + #define ZSTD_DECOMPRESS_INTERNAL_H + + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/mem.h" /* BYTE, U16, U32 */ +#include "../common/zstd_internal.h" /* constants : MaxLL, MaxML, MaxOff, LLFSELog, etc. */ + + + +/*-******************************************************* + * Constants + *********************************************************/ +static UNUSED_ATTR const U32 LL_base[MaxLL+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 28, 32, 40, + 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, + 0x2000, 0x4000, 0x8000, 0x10000 }; + +static UNUSED_ATTR const U32 OF_base[MaxOff+1] = { + 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, + 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, + 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, + 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD }; + +static UNUSED_ATTR const U8 OF_bits[MaxOff+1] = { + 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 }; + +static UNUSED_ATTR const U32 ML_base[MaxML+1] = { + 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, 37, 39, 41, 43, 47, 51, 59, + 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, + 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; + + +/*-******************************************************* + * Decompression types + *********************************************************/ + typedef struct { + U32 fastMode; + U32 tableLog; + } ZSTD_seqSymbol_header; + + typedef struct { + U16 nextState; + BYTE nbAdditionalBits; + BYTE nbBits; + U32 baseValue; + } ZSTD_seqSymbol; + + #define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log))) + +#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE (sizeof(S16) * (MaxSeq + 1) + (1u << MaxFSELog) + sizeof(U64)) +#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32 ((ZSTD_BUILD_FSE_TABLE_WKSP_SIZE + sizeof(U32) - 1) / sizeof(U32)) +#define ZSTD_HUFFDTABLE_CAPACITY_LOG 12 + +typedef struct { + ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */ + ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */ + ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */ + HUF_DTable hufTable[HUF_DTABLE_SIZE(ZSTD_HUFFDTABLE_CAPACITY_LOG)]; /* can accommodate HUF_decompress4X */ + U32 rep[ZSTD_REP_NUM]; + U32 workspace[ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32]; +} ZSTD_entropyDTables_t; + +typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, + ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock, + ZSTDds_decompressLastBlock, ZSTDds_checkChecksum, + ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage; + +typedef enum { zdss_init=0, zdss_loadHeader, + zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage; + +typedef enum { + ZSTD_use_indefinitely = -1, /* Use the dictionary indefinitely */ + ZSTD_dont_use = 0, /* Do not use the dictionary (if one exists free it) */ + ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */ +} ZSTD_dictUses_e; + +/* Hashset for storing references to multiple ZSTD_DDict within ZSTD_DCtx */ +typedef struct { + const ZSTD_DDict** ddictPtrTable; + size_t ddictPtrTableSize; + size_t ddictPtrCount; +} ZSTD_DDictHashSet; + +#ifndef ZSTD_DECODER_INTERNAL_BUFFER +# define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16) +#endif + +#define ZSTD_LBMIN 64 +#define ZSTD_LBMAX (128 << 10) + +/* extra buffer, compensates when dst is not large enough to store litBuffer */ +#define ZSTD_LITBUFFEREXTRASIZE BOUNDED(ZSTD_LBMIN, ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX) + +typedef enum { + ZSTD_not_in_dst = 0, /* Stored entirely within litExtraBuffer */ + ZSTD_in_dst = 1, /* Stored entirely within dst (in memory after current output write) */ + ZSTD_split = 2 /* Split between litExtraBuffer and dst */ +} ZSTD_litLocation_e; + +struct ZSTD_DCtx_s +{ + const ZSTD_seqSymbol* LLTptr; + const ZSTD_seqSymbol* MLTptr; + const ZSTD_seqSymbol* OFTptr; + const HUF_DTable* HUFptr; + ZSTD_entropyDTables_t entropy; + U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; /* space needed when building huffman tables */ + const void* previousDstEnd; /* detect continuity */ + const void* prefixStart; /* start of current segment */ + const void* virtualStart; /* virtual start of previous segment if it was just before current one */ + const void* dictEnd; /* end of previous segment */ + size_t expected; + ZSTD_FrameHeader fParams; + U64 processedCSize; + U64 decodedSize; + blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */ + ZSTD_dStage stage; + U32 litEntropy; + U32 fseEntropy; + XXH64_state_t xxhState; + size_t headerSize; + ZSTD_format_e format; + ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum; /* User specified: if == 1, will ignore checksums in compressed frame. Default == 0 */ + U32 validateChecksum; /* if == 1, will validate checksum. Is == 1 if (fParams.checksumFlag == 1) and (forceIgnoreChecksum == 0). */ + const BYTE* litPtr; + ZSTD_customMem customMem; + size_t litSize; + size_t rleSize; + size_t staticSize; + int isFrameDecompression; +#if DYNAMIC_BMI2 + int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ +#endif + + /* dictionary */ + ZSTD_DDict* ddictLocal; + const ZSTD_DDict* ddict; /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */ + U32 dictID; + int ddictIsCold; /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */ + ZSTD_dictUses_e dictUses; + ZSTD_DDictHashSet* ddictSet; /* Hash set for multiple ddicts */ + ZSTD_refMultipleDDicts_e refMultipleDDicts; /* User specified: if == 1, will allow references to multiple DDicts. Default == 0 (disabled) */ + int disableHufAsm; + int maxBlockSizeParam; + + /* streaming */ + ZSTD_dStreamStage streamStage; + char* inBuff; + size_t inBuffSize; + size_t inPos; + size_t maxWindowSize; + char* outBuff; + size_t outBuffSize; + size_t outStart; + size_t outEnd; + size_t lhSize; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + void* legacyContext; + U32 previousLegacyVersion; + U32 legacyVersion; +#endif + U32 hostageByte; + int noForwardProgress; + ZSTD_bufferMode_e outBufferMode; + ZSTD_outBuffer expectedOutBuffer; + + /* workspace */ + BYTE* litBuffer; + const BYTE* litBufferEnd; + ZSTD_litLocation_e litBufferLocation; + BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE + WILDCOPY_OVERLENGTH]; /* literal buffer can be split between storage within dst and within this scratch buffer */ + BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; + + size_t oversizedDuration; + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + void const* dictContentBeginForFuzzing; + void const* dictContentEndForFuzzing; +#endif + + /* Tracing */ +#if ZSTD_TRACE + ZSTD_TraceCtx traceCtx; +#endif +}; /* typedef'd to ZSTD_DCtx within "zstd.h" */ + +MEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx) { +#if DYNAMIC_BMI2 + return dctx->bmi2; +#else + (void)dctx; + return 0; +#endif +} + +/*-******************************************************* + * Shared internal functions + *********************************************************/ + +/*! ZSTD_loadDEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * @return : size of dictionary header (size of magic number + dict ID + entropy tables) */ +size_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, + const void* const dict, size_t const dictSize); + +/*! ZSTD_checkContinuity() : + * check if next `dst` follows previous position, where decompression ended. + * If yes, do nothing (continue on current segment). + * If not, classify previous segment as "external dictionary", and start a new segment. + * This function cannot fail. */ +void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize); + + +#endif /* ZSTD_DECOMPRESS_INTERNAL_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff.h b/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff.h new file mode 100644 index 000000000..a968245b3 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff.h @@ -0,0 +1,214 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* *************************************************************** +* NOTES/WARNINGS +******************************************************************/ +/* The streaming API defined here is deprecated. + * Consider migrating towards ZSTD_compressStream() API in `zstd.h` + * See 'lib/README.md'. + *****************************************************************/ + + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef ZSTD_BUFFERED_H_23987 +#define ZSTD_BUFFERED_H_23987 + +/* ************************************* +* Dependencies +***************************************/ +#include /* size_t */ +#include "../zstd.h" /* ZSTD_CStream, ZSTD_DStream, ZSTDLIB_API */ + + +/* *************************************************************** +* Compiler specifics +*****************************************************************/ +/* Deprecation warnings */ +/* Should these warnings be a problem, + * it is generally possible to disable them, + * typically with -Wno-deprecated-declarations for gcc + * or _CRT_SECURE_NO_WARNINGS in Visual. + * Otherwise, it's also possible to define ZBUFF_DISABLE_DEPRECATE_WARNINGS + */ +#ifdef ZBUFF_DISABLE_DEPRECATE_WARNINGS +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API /* disable deprecation warnings */ +#else +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define ZBUFF_DEPRECATED(message) [[deprecated(message)]] ZSTDLIB_API +# elif (defined(GNUC) && (GNUC > 4 || (GNUC == 4 && GNUC_MINOR >= 5))) || defined(__clang__) +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated(message))) +# elif defined(__GNUC__) && (__GNUC__ >= 3) +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API __declspec(deprecated(message)) +# else +# pragma message("WARNING: You need to implement ZBUFF_DEPRECATED for this compiler") +# define ZBUFF_DEPRECATED(message) ZSTDLIB_API +# endif +#endif /* ZBUFF_DISABLE_DEPRECATE_WARNINGS */ + + +/* ************************************* +* Streaming functions +***************************************/ +/* This is the easier "buffered" streaming API, +* using an internal buffer to lift all restrictions on user-provided buffers +* which can be any size, any place, for both input and output. +* ZBUFF and ZSTD are 100% interoperable, +* frames created by one can be decoded by the other one */ + +typedef ZSTD_CStream ZBUFF_CCtx; +ZBUFF_DEPRECATED("use ZSTD_createCStream") ZBUFF_CCtx* ZBUFF_createCCtx(void); +ZBUFF_DEPRECATED("use ZSTD_freeCStream") size_t ZBUFF_freeCCtx(ZBUFF_CCtx* cctx); + +ZBUFF_DEPRECATED("use ZSTD_initCStream") size_t ZBUFF_compressInit(ZBUFF_CCtx* cctx, int compressionLevel); +ZBUFF_DEPRECATED("use ZSTD_initCStream_usingDict") size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); + +ZBUFF_DEPRECATED("use ZSTD_compressStream") size_t ZBUFF_compressContinue(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr, const void* src, size_t* srcSizePtr); +ZBUFF_DEPRECATED("use ZSTD_flushStream") size_t ZBUFF_compressFlush(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr); +ZBUFF_DEPRECATED("use ZSTD_endStream") size_t ZBUFF_compressEnd(ZBUFF_CCtx* cctx, void* dst, size_t* dstCapacityPtr); + +/*-************************************************* +* Streaming compression - howto +* +* A ZBUFF_CCtx object is required to track streaming operation. +* Use ZBUFF_createCCtx() and ZBUFF_freeCCtx() to create/release resources. +* ZBUFF_CCtx objects can be reused multiple times. +* +* Start by initializing ZBUF_CCtx. +* Use ZBUFF_compressInit() to start a new compression operation. +* Use ZBUFF_compressInitDictionary() for a compression which requires a dictionary. +* +* Use ZBUFF_compressContinue() repetitively to consume input stream. +* *srcSizePtr and *dstCapacityPtr can be any size. +* The function will report how many bytes were read or written within *srcSizePtr and *dstCapacityPtr. +* Note that it may not consume the entire input, in which case it's up to the caller to present again remaining data. +* The content of `dst` will be overwritten (up to *dstCapacityPtr) at each call, so save its content if it matters or change @dst . +* @return : a hint to preferred nb of bytes to use as input for next function call (it's just a hint, to improve latency) +* or an error code, which can be tested using ZBUFF_isError(). +* +* At any moment, it's possible to flush whatever data remains within buffer, using ZBUFF_compressFlush(). +* The nb of bytes written into `dst` will be reported into *dstCapacityPtr. +* Note that the function cannot output more than *dstCapacityPtr, +* therefore, some content might still be left into internal buffer if *dstCapacityPtr is too small. +* @return : nb of bytes still present into internal buffer (0 if it's empty) +* or an error code, which can be tested using ZBUFF_isError(). +* +* ZBUFF_compressEnd() instructs to finish a frame. +* It will perform a flush and write frame epilogue. +* The epilogue is required for decoders to consider a frame completed. +* Similar to ZBUFF_compressFlush(), it may not be able to output the entire internal buffer content if *dstCapacityPtr is too small. +* In which case, call again ZBUFF_compressFlush() to complete the flush. +* @return : nb of bytes still present into internal buffer (0 if it's empty) +* or an error code, which can be tested using ZBUFF_isError(). +* +* Hint : _recommended buffer_ sizes (not compulsory) : ZBUFF_recommendedCInSize() / ZBUFF_recommendedCOutSize() +* input : ZBUFF_recommendedCInSize==128 KB block size is the internal unit, use this value to reduce intermediate stages (better latency) +* output : ZBUFF_recommendedCOutSize==ZSTD_compressBound(128 KB) + 3 + 3 : ensures it's always possible to write/flush/end a full block. Skip some buffering. +* By using both, it ensures that input will be entirely consumed, and output will always contain the result, reducing intermediate buffering. +* **************************************************/ + + +typedef ZSTD_DStream ZBUFF_DCtx; +ZBUFF_DEPRECATED("use ZSTD_createDStream") ZBUFF_DCtx* ZBUFF_createDCtx(void); +ZBUFF_DEPRECATED("use ZSTD_freeDStream") size_t ZBUFF_freeDCtx(ZBUFF_DCtx* dctx); + +ZBUFF_DEPRECATED("use ZSTD_initDStream") size_t ZBUFF_decompressInit(ZBUFF_DCtx* dctx); +ZBUFF_DEPRECATED("use ZSTD_initDStream_usingDict") size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* dctx, const void* dict, size_t dictSize); + +ZBUFF_DEPRECATED("use ZSTD_decompressStream") size_t ZBUFF_decompressContinue(ZBUFF_DCtx* dctx, + void* dst, size_t* dstCapacityPtr, + const void* src, size_t* srcSizePtr); + +/*-*************************************************************************** +* Streaming decompression howto +* +* A ZBUFF_DCtx object is required to track streaming operations. +* Use ZBUFF_createDCtx() and ZBUFF_freeDCtx() to create/release resources. +* Use ZBUFF_decompressInit() to start a new decompression operation, +* or ZBUFF_decompressInitDictionary() if decompression requires a dictionary. +* Note that ZBUFF_DCtx objects can be re-init multiple times. +* +* Use ZBUFF_decompressContinue() repetitively to consume your input. +* *srcSizePtr and *dstCapacityPtr can be any size. +* The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr. +* Note that it may not consume the entire input, in which case it's up to the caller to present remaining input again. +* The content of `dst` will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters, or change `dst`. +* @return : 0 when a frame is completely decoded and fully flushed, +* 1 when there is still some data left within internal buffer to flush, +* >1 when more data is expected, with value being a suggested next input size (it's just a hint, which helps latency), +* or an error code, which can be tested using ZBUFF_isError(). +* +* Hint : recommended buffer sizes (not compulsory) : ZBUFF_recommendedDInSize() and ZBUFF_recommendedDOutSize() +* output : ZBUFF_recommendedDOutSize== 128 KB block size is the internal unit, it ensures it's always possible to write a full block when decoded. +* input : ZBUFF_recommendedDInSize == 128KB + 3; +* just follow indications from ZBUFF_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 . +* *******************************************************************************/ + + +/* ************************************* +* Tool functions +***************************************/ +ZBUFF_DEPRECATED("use ZSTD_isError") unsigned ZBUFF_isError(size_t errorCode); +ZBUFF_DEPRECATED("use ZSTD_getErrorName") const char* ZBUFF_getErrorName(size_t errorCode); + +/** Functions below provide recommended buffer sizes for Compression or Decompression operations. +* These sizes are just hints, they tend to offer better latency */ +ZBUFF_DEPRECATED("use ZSTD_CStreamInSize") size_t ZBUFF_recommendedCInSize(void); +ZBUFF_DEPRECATED("use ZSTD_CStreamOutSize") size_t ZBUFF_recommendedCOutSize(void); +ZBUFF_DEPRECATED("use ZSTD_DStreamInSize") size_t ZBUFF_recommendedDInSize(void); +ZBUFF_DEPRECATED("use ZSTD_DStreamOutSize") size_t ZBUFF_recommendedDOutSize(void); + +#endif /* ZSTD_BUFFERED_H_23987 */ + + +#ifdef ZBUFF_STATIC_LINKING_ONLY +#ifndef ZBUFF_STATIC_H_30298098432 +#define ZBUFF_STATIC_H_30298098432 + +/* ==================================================================================== + * The definitions in this section are considered experimental. + * They should never be used in association with a dynamic library, as they may change in the future. + * They are provided for advanced usages. + * Use them only in association with static linking. + * ==================================================================================== */ + +/*--- Dependency ---*/ +#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters, ZSTD_customMem */ +#include "../zstd.h" + + +/*--- Custom memory allocator ---*/ +/*! ZBUFF_createCCtx_advanced() : + * Create a ZBUFF compression context using external alloc and free functions */ +ZBUFF_DEPRECATED("use ZSTD_createCStream_advanced") ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem); + +/*! ZBUFF_createDCtx_advanced() : + * Create a ZBUFF decompression context using external alloc and free functions */ +ZBUFF_DEPRECATED("use ZSTD_createDStream_advanced") ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem); + + +/*--- Advanced Streaming Initialization ---*/ +ZBUFF_DEPRECATED("use ZSTD_initDStream_usingDict") size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, + const void* dict, size_t dictSize, + ZSTD_parameters params, unsigned long long pledgedSrcSize); + + +#endif /* ZBUFF_STATIC_H_30298098432 */ +#endif /* ZBUFF_STATIC_LINKING_ONLY */ + + +#if defined (__cplusplus) +} +#endif diff --git a/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_common.c b/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_common.c new file mode 100644 index 000000000..5a2f2db35 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_common.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/error_private.h" +#include "zbuff.h" + +/*-**************************************** +* ZBUFF Error Management (deprecated) +******************************************/ + +/*! ZBUFF_isError() : +* tells if a return value is an error code */ +unsigned ZBUFF_isError(size_t errorCode) { return ERR_isError(errorCode); } +/*! ZBUFF_getErrorName() : +* provides error code string from function result (useful for debugging) */ +const char* ZBUFF_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); } diff --git a/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_compress.c b/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_compress.c new file mode 100644 index 000000000..1d8682150 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_compress.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + + +/* ************************************* +* Dependencies +***************************************/ +#define ZBUFF_STATIC_LINKING_ONLY +#include "zbuff.h" +#include "../common/error_private.h" + + +/*-*********************************************************** +* Streaming compression +* +* A ZBUFF_CCtx object is required to track streaming operation. +* Use ZBUFF_createCCtx() and ZBUFF_freeCCtx() to create/release resources. +* Use ZBUFF_compressInit() to start a new compression operation. +* ZBUFF_CCtx objects can be reused multiple times. +* +* Use ZBUFF_compressContinue() repetitively to consume your input. +* *srcSizePtr and *dstCapacityPtr can be any size. +* The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr. +* Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input. +* The content of dst will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters or change dst . +* @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to improve latency) +* or an error code, which can be tested using ZBUFF_isError(). +* +* ZBUFF_compressFlush() can be used to instruct ZBUFF to compress and output whatever remains within its buffer. +* Note that it will not output more than *dstCapacityPtr. +* Therefore, some content might still be left into its internal buffer if dst buffer is too small. +* @return : nb of bytes still present into internal buffer (0 if it's empty) +* or an error code, which can be tested using ZBUFF_isError(). +* +* ZBUFF_compressEnd() instructs to finish a frame. +* It will perform a flush and write frame epilogue. +* Similar to ZBUFF_compressFlush(), it may not be able to output the entire internal buffer content if *dstCapacityPtr is too small. +* @return : nb of bytes still present into internal buffer (0 if it's empty) +* or an error code, which can be tested using ZBUFF_isError(). +* +* Hint : recommended buffer sizes (not compulsory) +* input : ZSTD_BLOCKSIZE_MAX (128 KB), internal unit size, it improves latency to use this value. +* output : ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize : ensures it's always possible to write/flush/end a full block at best speed. +* ***********************************************************/ + +ZBUFF_CCtx* ZBUFF_createCCtx(void) +{ + return ZSTD_createCStream(); +} + +ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem) +{ + return ZSTD_createCStream_advanced(customMem); +} + +size_t ZBUFF_freeCCtx(ZBUFF_CCtx* zbc) +{ + return ZSTD_freeCStream(zbc); +} + + +/* ====== Initialization ====== */ + +size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, + const void* dict, size_t dictSize, + ZSTD_parameters params, unsigned long long pledgedSrcSize) +{ + if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* preserve "0 == unknown" behavior */ + FORWARD_IF_ERROR(ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setPledgedSrcSize(zbc, pledgedSrcSize), ""); + + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_windowLog, params.cParams.windowLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_hashLog, params.cParams.hashLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_chainLog, params.cParams.chainLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_searchLog, params.cParams.searchLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_minMatch, params.cParams.minMatch), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_targetLength, params.cParams.targetLength), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_strategy, params.cParams.strategy), ""); + + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_contentSizeFlag, params.fParams.contentSizeFlag), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_checksumFlag, params.fParams.checksumFlag), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_dictIDFlag, params.fParams.noDictIDFlag), ""); + + FORWARD_IF_ERROR(ZSTD_CCtx_loadDictionary(zbc, dict, dictSize), ""); + return 0; +} + +size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, int compressionLevel) +{ + FORWARD_IF_ERROR(ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_compressionLevel, compressionLevel), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_loadDictionary(zbc, dict, dictSize), ""); + return 0; +} + +size_t ZBUFF_compressInit(ZBUFF_CCtx* zbc, int compressionLevel) +{ + return ZSTD_initCStream(zbc, compressionLevel); +} + +/* ====== Compression ====== */ + + +size_t ZBUFF_compressContinue(ZBUFF_CCtx* zbc, + void* dst, size_t* dstCapacityPtr, + const void* src, size_t* srcSizePtr) +{ + size_t result; + ZSTD_outBuffer outBuff; + ZSTD_inBuffer inBuff; + outBuff.dst = dst; + outBuff.pos = 0; + outBuff.size = *dstCapacityPtr; + inBuff.src = src; + inBuff.pos = 0; + inBuff.size = *srcSizePtr; + result = ZSTD_compressStream(zbc, &outBuff, &inBuff); + *dstCapacityPtr = outBuff.pos; + *srcSizePtr = inBuff.pos; + return result; +} + + + +/* ====== Finalize ====== */ + +size_t ZBUFF_compressFlush(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr) +{ + size_t result; + ZSTD_outBuffer outBuff; + outBuff.dst = dst; + outBuff.pos = 0; + outBuff.size = *dstCapacityPtr; + result = ZSTD_flushStream(zbc, &outBuff); + *dstCapacityPtr = outBuff.pos; + return result; +} + + +size_t ZBUFF_compressEnd(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr) +{ + size_t result; + ZSTD_outBuffer outBuff; + outBuff.dst = dst; + outBuff.pos = 0; + outBuff.size = *dstCapacityPtr; + result = ZSTD_endStream(zbc, &outBuff); + *dstCapacityPtr = outBuff.pos; + return result; +} + + + +/* ************************************* +* Tool functions +***************************************/ +size_t ZBUFF_recommendedCInSize(void) { return ZSTD_CStreamInSize(); } +size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_CStreamOutSize(); } diff --git a/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_decompress.c b/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_decompress.c new file mode 100644 index 000000000..12a66af74 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/deprecated/zbuff_decompress.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + + +/* ************************************* +* Dependencies +***************************************/ +#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* suppress warning on ZSTD_initDStream_usingDict */ +#include "../zstd.h" /* ZSTD_CStream, ZSTD_DStream, ZSTDLIB_API */ +#define ZBUFF_STATIC_LINKING_ONLY +#include "zbuff.h" + + +ZBUFF_DCtx* ZBUFF_createDCtx(void) +{ + return ZSTD_createDStream(); +} + +ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem) +{ + return ZSTD_createDStream_advanced(customMem); +} + +size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbd) +{ + return ZSTD_freeDStream(zbd); +} + + +/* *** Initialization *** */ + +size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* zbd, const void* dict, size_t dictSize) +{ + return ZSTD_initDStream_usingDict(zbd, dict, dictSize); +} + +size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbd) +{ + return ZSTD_initDStream(zbd); +} + + +/* *** Decompression *** */ + +size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd, + void* dst, size_t* dstCapacityPtr, + const void* src, size_t* srcSizePtr) +{ + ZSTD_outBuffer outBuff; + ZSTD_inBuffer inBuff; + size_t result; + outBuff.dst = dst; + outBuff.pos = 0; + outBuff.size = *dstCapacityPtr; + inBuff.src = src; + inBuff.pos = 0; + inBuff.size = *srcSizePtr; + result = ZSTD_decompressStream(zbd, &outBuff, &inBuff); + *dstCapacityPtr = outBuff.pos; + *srcSizePtr = inBuff.pos; + return result; +} + + +/* ************************************* +* Tool functions +***************************************/ +size_t ZBUFF_recommendedDInSize(void) { return ZSTD_DStreamInSize(); } +size_t ZBUFF_recommendedDOutSize(void) { return ZSTD_DStreamOutSize(); } diff --git a/cpp/third_party/zstd-1.5.7/lib/dictBuilder/cover.c b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/cover.c new file mode 100644 index 000000000..2ef33c73e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/cover.c @@ -0,0 +1,1302 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* ***************************************************************************** + * Constructs a dictionary using a heuristic based on the following paper: + * + * Liao, Petri, Moffat, Wirth + * Effective Construction of Relative Lempel-Ziv Dictionaries + * Published in WWW 2016. + * + * Adapted from code originally written by @ot (Giuseppe Ottaviano). + ******************************************************************************/ + +/*-************************************* +* Dependencies +***************************************/ +/* qsort_r is an extension. */ +#if defined(__linux) || defined(__linux__) || defined(linux) || defined(__gnu_linux__) || \ + defined(__CYGWIN__) || defined(__MSYS__) +#if !defined(_GNU_SOURCE) && !defined(__ANDROID__) /* NDK doesn't ship qsort_r(). */ +#define _GNU_SOURCE +#endif +#endif + +#include /* fprintf */ +#include /* malloc, free, qsort_r */ + +#include /* memset */ +#include /* clock */ + +#ifndef ZDICT_STATIC_LINKING_ONLY +# define ZDICT_STATIC_LINKING_ONLY +#endif + +#include "../common/mem.h" /* read */ +#include "../common/pool.h" /* POOL_ctx */ +#include "../common/threading.h" /* ZSTD_pthread_mutex_t */ +#include "../common/zstd_internal.h" /* includes zstd.h */ +#include "../common/bits.h" /* ZSTD_highbit32 */ +#include "../zdict.h" +#include "cover.h" + +/*-************************************* +* Constants +***************************************/ +/** +* There are 32bit indexes used to ref samples, so limit samples size to 4GB +* on 64bit builds. +* For 32bit builds we choose 1 GB. +* Most 32bit platforms have 2GB user-mode addressable space and we allocate a large +* contiguous buffer, so 1GB is already a high limit. +*/ +#define COVER_MAX_SAMPLES_SIZE (sizeof(size_t) == 8 ? ((unsigned)-1) : ((unsigned)1 GB)) +#define COVER_DEFAULT_SPLITPOINT 1.0 + +/*-************************************* +* Console display +***************************************/ +#ifndef LOCALDISPLAYLEVEL +static int g_displayLevel = 0; +#endif +#undef DISPLAY +#define DISPLAY(...) \ + { \ + fprintf(stderr, __VA_ARGS__); \ + fflush(stderr); \ + } +#undef LOCALDISPLAYLEVEL +#define LOCALDISPLAYLEVEL(displayLevel, l, ...) \ + if (displayLevel >= l) { \ + DISPLAY(__VA_ARGS__); \ + } /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */ +#undef DISPLAYLEVEL +#define DISPLAYLEVEL(l, ...) LOCALDISPLAYLEVEL(g_displayLevel, l, __VA_ARGS__) + +#ifndef LOCALDISPLAYUPDATE +static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100; +static clock_t g_time = 0; +#endif +#undef LOCALDISPLAYUPDATE +#define LOCALDISPLAYUPDATE(displayLevel, l, ...) \ + if (displayLevel >= l) { \ + if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \ + g_time = clock(); \ + DISPLAY(__VA_ARGS__); \ + } \ + } +#undef DISPLAYUPDATE +#define DISPLAYUPDATE(l, ...) LOCALDISPLAYUPDATE(g_displayLevel, l, __VA_ARGS__) + +/*-************************************* +* Hash table +*************************************** +* A small specialized hash map for storing activeDmers. +* The map does not resize, so if it becomes full it will loop forever. +* Thus, the map must be large enough to store every value. +* The map implements linear probing and keeps its load less than 0.5. +*/ + +#define MAP_EMPTY_VALUE ((U32)-1) +typedef struct COVER_map_pair_t_s { + U32 key; + U32 value; +} COVER_map_pair_t; + +typedef struct COVER_map_s { + COVER_map_pair_t *data; + U32 sizeLog; + U32 size; + U32 sizeMask; +} COVER_map_t; + +/** + * Clear the map. + */ +static void COVER_map_clear(COVER_map_t *map) { + memset(map->data, MAP_EMPTY_VALUE, map->size * sizeof(COVER_map_pair_t)); +} + +/** + * Initializes a map of the given size. + * Returns 1 on success and 0 on failure. + * The map must be destroyed with COVER_map_destroy(). + * The map is only guaranteed to be large enough to hold size elements. + */ +static int COVER_map_init(COVER_map_t *map, U32 size) { + map->sizeLog = ZSTD_highbit32(size) + 2; + map->size = (U32)1 << map->sizeLog; + map->sizeMask = map->size - 1; + map->data = (COVER_map_pair_t *)malloc(map->size * sizeof(COVER_map_pair_t)); + if (!map->data) { + map->sizeLog = 0; + map->size = 0; + return 0; + } + COVER_map_clear(map); + return 1; +} + +/** + * Internal hash function + */ +static const U32 COVER_prime4bytes = 2654435761U; +static U32 COVER_map_hash(COVER_map_t *map, U32 key) { + return (key * COVER_prime4bytes) >> (32 - map->sizeLog); +} + +/** + * Helper function that returns the index that a key should be placed into. + */ +static U32 COVER_map_index(COVER_map_t *map, U32 key) { + const U32 hash = COVER_map_hash(map, key); + U32 i; + for (i = hash;; i = (i + 1) & map->sizeMask) { + COVER_map_pair_t *pos = &map->data[i]; + if (pos->value == MAP_EMPTY_VALUE) { + return i; + } + if (pos->key == key) { + return i; + } + } +} + +/** + * Returns the pointer to the value for key. + * If key is not in the map, it is inserted and the value is set to 0. + * The map must not be full. + */ +static U32 *COVER_map_at(COVER_map_t *map, U32 key) { + COVER_map_pair_t *pos = &map->data[COVER_map_index(map, key)]; + if (pos->value == MAP_EMPTY_VALUE) { + pos->key = key; + pos->value = 0; + } + return &pos->value; +} + +/** + * Deletes key from the map if present. + */ +static void COVER_map_remove(COVER_map_t *map, U32 key) { + U32 i = COVER_map_index(map, key); + COVER_map_pair_t *del = &map->data[i]; + U32 shift = 1; + if (del->value == MAP_EMPTY_VALUE) { + return; + } + for (i = (i + 1) & map->sizeMask;; i = (i + 1) & map->sizeMask) { + COVER_map_pair_t *const pos = &map->data[i]; + /* If the position is empty we are done */ + if (pos->value == MAP_EMPTY_VALUE) { + del->value = MAP_EMPTY_VALUE; + return; + } + /* If pos can be moved to del do so */ + if (((i - COVER_map_hash(map, pos->key)) & map->sizeMask) >= shift) { + del->key = pos->key; + del->value = pos->value; + del = pos; + shift = 1; + } else { + ++shift; + } + } +} + +/** + * Destroys a map that is inited with COVER_map_init(). + */ +static void COVER_map_destroy(COVER_map_t *map) { + if (map->data) { + free(map->data); + } + map->data = NULL; + map->size = 0; +} + +/*-************************************* +* Context +***************************************/ + +typedef struct { + const BYTE *samples; + size_t *offsets; + const size_t *samplesSizes; + size_t nbSamples; + size_t nbTrainSamples; + size_t nbTestSamples; + U32 *suffix; + size_t suffixSize; + U32 *freqs; + U32 *dmerAt; + unsigned d; +} COVER_ctx_t; + +#if !defined(_GNU_SOURCE) && !defined(__APPLE__) && !defined(_MSC_VER) +/* C90 only offers qsort() that needs a global context. */ +static COVER_ctx_t *g_coverCtx = NULL; +#endif + +/*-************************************* +* Helper functions +***************************************/ + +/** + * Returns the sum of the sample sizes. + */ +size_t COVER_sum(const size_t *samplesSizes, unsigned nbSamples) { + size_t sum = 0; + unsigned i; + for (i = 0; i < nbSamples; ++i) { + sum += samplesSizes[i]; + } + return sum; +} + +/** + * Returns -1 if the dmer at lp is less than the dmer at rp. + * Return 0 if the dmers at lp and rp are equal. + * Returns 1 if the dmer at lp is greater than the dmer at rp. + */ +static int COVER_cmp(COVER_ctx_t *ctx, const void *lp, const void *rp) { + U32 const lhs = *(U32 const *)lp; + U32 const rhs = *(U32 const *)rp; + return memcmp(ctx->samples + lhs, ctx->samples + rhs, ctx->d); +} +/** + * Faster version for d <= 8. + */ +static int COVER_cmp8(COVER_ctx_t *ctx, const void *lp, const void *rp) { + U64 const mask = (ctx->d == 8) ? (U64)-1 : (((U64)1 << (8 * ctx->d)) - 1); + U64 const lhs = MEM_readLE64(ctx->samples + *(U32 const *)lp) & mask; + U64 const rhs = MEM_readLE64(ctx->samples + *(U32 const *)rp) & mask; + if (lhs < rhs) { + return -1; + } + return (lhs > rhs); +} + +/** + * Same as COVER_cmp() except ties are broken by pointer value + */ +#if (defined(_WIN32) && defined(_MSC_VER)) || defined(__APPLE__) +static int WIN_CDECL COVER_strict_cmp(void* g_coverCtx, const void* lp, const void* rp) { +#elif defined(_GNU_SOURCE) +static int COVER_strict_cmp(const void *lp, const void *rp, void *g_coverCtx) { +#else /* C90 fallback.*/ +static int COVER_strict_cmp(const void *lp, const void *rp) { +#endif + int result = COVER_cmp((COVER_ctx_t*)g_coverCtx, lp, rp); + if (result == 0) { + result = lp < rp ? -1 : 1; + } + return result; +} +/** + * Faster version for d <= 8. + */ +#if (defined(_WIN32) && defined(_MSC_VER)) || defined(__APPLE__) +static int WIN_CDECL COVER_strict_cmp8(void* g_coverCtx, const void* lp, const void* rp) { +#elif defined(_GNU_SOURCE) +static int COVER_strict_cmp8(const void *lp, const void *rp, void *g_coverCtx) { +#else /* C90 fallback.*/ +static int COVER_strict_cmp8(const void *lp, const void *rp) { +#endif + int result = COVER_cmp8((COVER_ctx_t*)g_coverCtx, lp, rp); + if (result == 0) { + result = lp < rp ? -1 : 1; + } + return result; +} + +/** + * Abstract away divergence of qsort_r() parameters. + * Hopefully when C11 become the norm, we will be able + * to clean it up. + */ +static void stableSort(COVER_ctx_t *ctx) { +#if defined(__APPLE__) + qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32), + ctx, + (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); +#elif defined(_GNU_SOURCE) + qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32), + (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp), + ctx); +#elif defined(_WIN32) && defined(_MSC_VER) + qsort_s(ctx->suffix, ctx->suffixSize, sizeof(U32), + (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp), + ctx); +#elif defined(__OpenBSD__) + g_coverCtx = ctx; + mergesort(ctx->suffix, ctx->suffixSize, sizeof(U32), + (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); +#else /* C90 fallback.*/ + g_coverCtx = ctx; + /* TODO(cavalcanti): implement a reentrant qsort() when is not available. */ + qsort(ctx->suffix, ctx->suffixSize, sizeof(U32), + (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); +#endif +} + +/** + * Returns the first pointer in [first, last) whose element does not compare + * less than value. If no such element exists it returns last. + */ +static const size_t *COVER_lower_bound(const size_t* first, const size_t* last, + size_t value) { + size_t count = (size_t)(last - first); + assert(last >= first); + while (count != 0) { + size_t step = count / 2; + const size_t *ptr = first; + ptr += step; + if (*ptr < value) { + first = ++ptr; + count -= step + 1; + } else { + count = step; + } + } + return first; +} + +/** + * Generic groupBy function. + * Groups an array sorted by cmp into groups with equivalent values. + * Calls grp for each group. + */ +static void +COVER_groupBy(const void *data, size_t count, size_t size, COVER_ctx_t *ctx, + int (*cmp)(COVER_ctx_t *, const void *, const void *), + void (*grp)(COVER_ctx_t *, const void *, const void *)) { + const BYTE *ptr = (const BYTE *)data; + size_t num = 0; + while (num < count) { + const BYTE *grpEnd = ptr + size; + ++num; + while (num < count && cmp(ctx, ptr, grpEnd) == 0) { + grpEnd += size; + ++num; + } + grp(ctx, ptr, grpEnd); + ptr = grpEnd; + } +} + +/*-************************************* +* Cover functions +***************************************/ + +/** + * Called on each group of positions with the same dmer. + * Counts the frequency of each dmer and saves it in the suffix array. + * Fills `ctx->dmerAt`. + */ +static void COVER_group(COVER_ctx_t *ctx, const void *group, + const void *groupEnd) { + /* The group consists of all the positions with the same first d bytes. */ + const U32 *grpPtr = (const U32 *)group; + const U32 *grpEnd = (const U32 *)groupEnd; + /* The dmerId is how we will reference this dmer. + * This allows us to map the whole dmer space to a much smaller space, the + * size of the suffix array. + */ + const U32 dmerId = (U32)(grpPtr - ctx->suffix); + /* Count the number of samples this dmer shows up in */ + U32 freq = 0; + /* Details */ + const size_t *curOffsetPtr = ctx->offsets; + const size_t *offsetsEnd = ctx->offsets + ctx->nbSamples; + /* Once *grpPtr >= curSampleEnd this occurrence of the dmer is in a + * different sample than the last. + */ + size_t curSampleEnd = ctx->offsets[0]; + for (; grpPtr != grpEnd; ++grpPtr) { + /* Save the dmerId for this position so we can get back to it. */ + ctx->dmerAt[*grpPtr] = dmerId; + /* Dictionaries only help for the first reference to the dmer. + * After that zstd can reference the match from the previous reference. + * So only count each dmer once for each sample it is in. + */ + if (*grpPtr < curSampleEnd) { + continue; + } + freq += 1; + /* Binary search to find the end of the sample *grpPtr is in. + * In the common case that grpPtr + 1 == grpEnd we can skip the binary + * search because the loop is over. + */ + if (grpPtr + 1 != grpEnd) { + const size_t *sampleEndPtr = + COVER_lower_bound(curOffsetPtr, offsetsEnd, *grpPtr); + curSampleEnd = *sampleEndPtr; + curOffsetPtr = sampleEndPtr + 1; + } + } + /* At this point we are never going to look at this segment of the suffix + * array again. We take advantage of this fact to save memory. + * We store the frequency of the dmer in the first position of the group, + * which is dmerId. + */ + ctx->suffix[dmerId] = freq; +} + + +/** + * Selects the best segment in an epoch. + * Segments of are scored according to the function: + * + * Let F(d) be the frequency of dmer d. + * Let S_i be the dmer at position i of segment S which has length k. + * + * Score(S) = F(S_1) + F(S_2) + ... + F(S_{k-d+1}) + * + * Once the dmer d is in the dictionary we set F(d) = 0. + */ +static COVER_segment_t COVER_selectSegment(const COVER_ctx_t *ctx, U32 *freqs, + COVER_map_t *activeDmers, U32 begin, + U32 end, + ZDICT_cover_params_t parameters) { + /* Constants */ + const U32 k = parameters.k; + const U32 d = parameters.d; + const U32 dmersInK = k - d + 1; + /* Try each segment (activeSegment) and save the best (bestSegment) */ + COVER_segment_t bestSegment = {0, 0, 0}; + COVER_segment_t activeSegment; + /* Reset the activeDmers in the segment */ + COVER_map_clear(activeDmers); + /* The activeSegment starts at the beginning of the epoch. */ + activeSegment.begin = begin; + activeSegment.end = begin; + activeSegment.score = 0; + /* Slide the activeSegment through the whole epoch. + * Save the best segment in bestSegment. + */ + while (activeSegment.end < end) { + /* The dmerId for the dmer at the next position */ + U32 newDmer = ctx->dmerAt[activeSegment.end]; + /* The entry in activeDmers for this dmerId */ + U32 *newDmerOcc = COVER_map_at(activeDmers, newDmer); + /* If the dmer isn't already present in the segment add its score. */ + if (*newDmerOcc == 0) { + /* The paper suggest using the L-0.5 norm, but experiments show that it + * doesn't help. + */ + activeSegment.score += freqs[newDmer]; + } + /* Add the dmer to the segment */ + activeSegment.end += 1; + *newDmerOcc += 1; + + /* If the window is now too large, drop the first position */ + if (activeSegment.end - activeSegment.begin == dmersInK + 1) { + U32 delDmer = ctx->dmerAt[activeSegment.begin]; + U32 *delDmerOcc = COVER_map_at(activeDmers, delDmer); + activeSegment.begin += 1; + *delDmerOcc -= 1; + /* If this is the last occurrence of the dmer, subtract its score */ + if (*delDmerOcc == 0) { + COVER_map_remove(activeDmers, delDmer); + activeSegment.score -= freqs[delDmer]; + } + } + + /* If this segment is the best so far save it */ + if (activeSegment.score > bestSegment.score) { + bestSegment = activeSegment; + } + } + { + /* Trim off the zero frequency head and tail from the segment. */ + U32 newBegin = bestSegment.end; + U32 newEnd = bestSegment.begin; + U32 pos; + for (pos = bestSegment.begin; pos != bestSegment.end; ++pos) { + U32 freq = freqs[ctx->dmerAt[pos]]; + if (freq != 0) { + newBegin = MIN(newBegin, pos); + newEnd = pos + 1; + } + } + bestSegment.begin = newBegin; + bestSegment.end = newEnd; + } + { + /* Zero out the frequency of each dmer covered by the chosen segment. */ + U32 pos; + for (pos = bestSegment.begin; pos != bestSegment.end; ++pos) { + freqs[ctx->dmerAt[pos]] = 0; + } + } + return bestSegment; +} + +/** + * Check the validity of the parameters. + * Returns non-zero if the parameters are valid and 0 otherwise. + */ +static int COVER_checkParameters(ZDICT_cover_params_t parameters, + size_t maxDictSize) { + /* k and d are required parameters */ + if (parameters.d == 0 || parameters.k == 0) { + return 0; + } + /* k <= maxDictSize */ + if (parameters.k > maxDictSize) { + return 0; + } + /* d <= k */ + if (parameters.d > parameters.k) { + return 0; + } + /* 0 < splitPoint <= 1 */ + if (parameters.splitPoint <= 0 || parameters.splitPoint > 1){ + return 0; + } + return 1; +} + +/** + * Clean up a context initialized with `COVER_ctx_init()`. + */ +static void COVER_ctx_destroy(COVER_ctx_t *ctx) { + if (!ctx) { + return; + } + if (ctx->suffix) { + free(ctx->suffix); + ctx->suffix = NULL; + } + if (ctx->freqs) { + free(ctx->freqs); + ctx->freqs = NULL; + } + if (ctx->dmerAt) { + free(ctx->dmerAt); + ctx->dmerAt = NULL; + } + if (ctx->offsets) { + free(ctx->offsets); + ctx->offsets = NULL; + } +} + +/** + * Prepare a context for dictionary building. + * The context is only dependent on the parameter `d` and can be used multiple + * times. + * Returns 0 on success or error code on error. + * The context must be destroyed with `COVER_ctx_destroy()`. + */ +static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer, + const size_t *samplesSizes, unsigned nbSamples, + unsigned d, double splitPoint) +{ + const BYTE *const samples = (const BYTE *)samplesBuffer; + const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples); + /* Split samples into testing and training sets */ + const unsigned nbTrainSamples = splitPoint < 1.0 ? (unsigned)((double)nbSamples * splitPoint) : nbSamples; + const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples; + const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize; + const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize; + /* Checks */ + if (totalSamplesSize < MAX(d, sizeof(U64)) || + totalSamplesSize >= (size_t)COVER_MAX_SAMPLES_SIZE) { + DISPLAYLEVEL(1, "Total samples size is too large (%u MB), maximum size is %u MB\n", + (unsigned)(totalSamplesSize>>20), (COVER_MAX_SAMPLES_SIZE >> 20)); + return ERROR(srcSize_wrong); + } + /* Check if there are at least 5 training samples */ + if (nbTrainSamples < 5) { + DISPLAYLEVEL(1, "Total number of training samples is %u and is invalid.", nbTrainSamples); + return ERROR(srcSize_wrong); + } + /* Check if there's testing sample */ + if (nbTestSamples < 1) { + DISPLAYLEVEL(1, "Total number of testing samples is %u and is invalid.", nbTestSamples); + return ERROR(srcSize_wrong); + } + /* Zero the context */ + memset(ctx, 0, sizeof(*ctx)); + DISPLAYLEVEL(2, "Training on %u samples of total size %u\n", nbTrainSamples, + (unsigned)trainingSamplesSize); + DISPLAYLEVEL(2, "Testing on %u samples of total size %u\n", nbTestSamples, + (unsigned)testSamplesSize); + ctx->samples = samples; + ctx->samplesSizes = samplesSizes; + ctx->nbSamples = nbSamples; + ctx->nbTrainSamples = nbTrainSamples; + ctx->nbTestSamples = nbTestSamples; + /* Partial suffix array */ + ctx->suffixSize = trainingSamplesSize - MAX(d, sizeof(U64)) + 1; + ctx->suffix = (U32 *)malloc(ctx->suffixSize * sizeof(U32)); + /* Maps index to the dmerID */ + ctx->dmerAt = (U32 *)malloc(ctx->suffixSize * sizeof(U32)); + /* The offsets of each file */ + ctx->offsets = (size_t *)malloc((nbSamples + 1) * sizeof(size_t)); + if (!ctx->suffix || !ctx->dmerAt || !ctx->offsets) { + DISPLAYLEVEL(1, "Failed to allocate scratch buffers\n"); + COVER_ctx_destroy(ctx); + return ERROR(memory_allocation); + } + ctx->freqs = NULL; + ctx->d = d; + + /* Fill offsets from the samplesSizes */ + { + U32 i; + ctx->offsets[0] = 0; + for (i = 1; i <= nbSamples; ++i) { + ctx->offsets[i] = ctx->offsets[i - 1] + samplesSizes[i - 1]; + } + } + DISPLAYLEVEL(2, "Constructing partial suffix array\n"); + { + /* suffix is a partial suffix array. + * It only sorts suffixes by their first parameters.d bytes. + * The sort is stable, so each dmer group is sorted by position in input. + */ + U32 i; + for (i = 0; i < ctx->suffixSize; ++i) { + ctx->suffix[i] = i; + } + stableSort(ctx); + } + DISPLAYLEVEL(2, "Computing frequencies\n"); + /* For each dmer group (group of positions with the same first d bytes): + * 1. For each position we set dmerAt[position] = dmerID. The dmerID is + * (groupBeginPtr - suffix). This allows us to go from position to + * dmerID so we can look up values in freq. + * 2. We calculate how many samples the dmer occurs in and save it in + * freqs[dmerId]. + */ + COVER_groupBy(ctx->suffix, ctx->suffixSize, sizeof(U32), ctx, + (ctx->d <= 8 ? &COVER_cmp8 : &COVER_cmp), &COVER_group); + ctx->freqs = ctx->suffix; + ctx->suffix = NULL; + return 0; +} + +void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLevel) +{ + const double ratio = (double)nbDmers / (double)maxDictSize; + if (ratio >= 10) { + return; + } + LOCALDISPLAYLEVEL(displayLevel, 1, + "WARNING: The maximum dictionary size %u is too large " + "compared to the source size %u! " + "size(source)/size(dictionary) = %f, but it should be >= " + "10! This may lead to a subpar dictionary! We recommend " + "training on sources at least 10x, and preferably 100x " + "the size of the dictionary! \n", (U32)maxDictSize, + (U32)nbDmers, ratio); +} + +COVER_epoch_info_t COVER_computeEpochs(U32 maxDictSize, + U32 nbDmers, U32 k, U32 passes) +{ + const U32 minEpochSize = k * 10; + COVER_epoch_info_t epochs; + epochs.num = MAX(1, maxDictSize / k / passes); + epochs.size = nbDmers / epochs.num; + if (epochs.size >= minEpochSize) { + assert(epochs.size * epochs.num <= nbDmers); + return epochs; + } + epochs.size = MIN(minEpochSize, nbDmers); + epochs.num = nbDmers / epochs.size; + assert(epochs.size * epochs.num <= nbDmers); + return epochs; +} + +/** + * Given the prepared context build the dictionary. + */ +static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs, + COVER_map_t *activeDmers, void *dictBuffer, + size_t dictBufferCapacity, + ZDICT_cover_params_t parameters) { + BYTE *const dict = (BYTE *)dictBuffer; + size_t tail = dictBufferCapacity; + /* Divide the data into epochs. We will select one segment from each epoch. */ + const COVER_epoch_info_t epochs = COVER_computeEpochs( + (U32)dictBufferCapacity, (U32)ctx->suffixSize, parameters.k, 4); + const size_t maxZeroScoreRun = MAX(10, MIN(100, epochs.num >> 3)); + size_t zeroScoreRun = 0; + size_t epoch; + DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n", + (U32)epochs.num, (U32)epochs.size); + /* Loop through the epochs until there are no more segments or the dictionary + * is full. + */ + for (epoch = 0; tail > 0; epoch = (epoch + 1) % epochs.num) { + const U32 epochBegin = (U32)(epoch * epochs.size); + const U32 epochEnd = epochBegin + epochs.size; + size_t segmentSize; + /* Select a segment */ + COVER_segment_t segment = COVER_selectSegment( + ctx, freqs, activeDmers, epochBegin, epochEnd, parameters); + /* If the segment covers no dmers, then we are out of content. + * There may be new content in other epochs, for continue for some time. + */ + if (segment.score == 0) { + if (++zeroScoreRun >= maxZeroScoreRun) { + break; + } + continue; + } + zeroScoreRun = 0; + /* Trim the segment if necessary and if it is too small then we are done */ + segmentSize = MIN(segment.end - segment.begin + parameters.d - 1, tail); + if (segmentSize < parameters.d) { + break; + } + /* We fill the dictionary from the back to allow the best segments to be + * referenced with the smallest offsets. + */ + tail -= segmentSize; + memcpy(dict + tail, ctx->samples + segment.begin, segmentSize); + DISPLAYUPDATE( + 2, "\r%u%% ", + (unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity)); + } + DISPLAYLEVEL(2, "\r%79s\r", ""); + return tail; +} + +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover( + void *dictBuffer, size_t dictBufferCapacity, + const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, + ZDICT_cover_params_t parameters) +{ + BYTE* const dict = (BYTE*)dictBuffer; + COVER_ctx_t ctx; + COVER_map_t activeDmers; + parameters.splitPoint = 1.0; + /* Initialize global data */ + g_displayLevel = (int)parameters.zParams.notificationLevel; + /* Checks */ + if (!COVER_checkParameters(parameters, dictBufferCapacity)) { + DISPLAYLEVEL(1, "Cover parameters incorrect\n"); + return ERROR(parameter_outOfBound); + } + if (nbSamples == 0) { + DISPLAYLEVEL(1, "Cover must have at least one input file\n"); + return ERROR(srcSize_wrong); + } + if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) { + DISPLAYLEVEL(1, "dictBufferCapacity must be at least %u\n", + ZDICT_DICTSIZE_MIN); + return ERROR(dstSize_tooSmall); + } + /* Initialize context and activeDmers */ + { + size_t const initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, + parameters.d, parameters.splitPoint); + if (ZSTD_isError(initVal)) { + return initVal; + } + } + COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.suffixSize, g_displayLevel); + if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) { + DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n"); + COVER_ctx_destroy(&ctx); + return ERROR(memory_allocation); + } + + DISPLAYLEVEL(2, "Building dictionary\n"); + { + const size_t tail = + COVER_buildDictionary(&ctx, ctx.freqs, &activeDmers, dictBuffer, + dictBufferCapacity, parameters); + const size_t dictionarySize = ZDICT_finalizeDictionary( + dict, dictBufferCapacity, dict + tail, dictBufferCapacity - tail, + samplesBuffer, samplesSizes, nbSamples, parameters.zParams); + if (!ZSTD_isError(dictionarySize)) { + DISPLAYLEVEL(2, "Constructed dictionary of size %u\n", + (unsigned)dictionarySize); + } + COVER_ctx_destroy(&ctx); + COVER_map_destroy(&activeDmers); + return dictionarySize; + } +} + + + +size_t COVER_checkTotalCompressedSize(const ZDICT_cover_params_t parameters, + const size_t *samplesSizes, const BYTE *samples, + size_t *offsets, + size_t nbTrainSamples, size_t nbSamples, + BYTE *const dict, size_t dictBufferCapacity) { + size_t totalCompressedSize = ERROR(GENERIC); + /* Pointers */ + ZSTD_CCtx *cctx; + ZSTD_CDict *cdict; + void *dst; + /* Local variables */ + size_t dstCapacity; + size_t i; + /* Allocate dst with enough space to compress the maximum sized sample */ + { + size_t maxSampleSize = 0; + i = parameters.splitPoint < 1.0 ? nbTrainSamples : 0; + for (; i < nbSamples; ++i) { + maxSampleSize = MAX(samplesSizes[i], maxSampleSize); + } + dstCapacity = ZSTD_compressBound(maxSampleSize); + dst = malloc(dstCapacity); + } + /* Create the cctx and cdict */ + cctx = ZSTD_createCCtx(); + cdict = ZSTD_createCDict(dict, dictBufferCapacity, + parameters.zParams.compressionLevel); + if (!dst || !cctx || !cdict) { + goto _compressCleanup; + } + /* Compress each sample and sum their sizes (or error) */ + totalCompressedSize = dictBufferCapacity; + i = parameters.splitPoint < 1.0 ? nbTrainSamples : 0; + for (; i < nbSamples; ++i) { + const size_t size = ZSTD_compress_usingCDict( + cctx, dst, dstCapacity, samples + offsets[i], + samplesSizes[i], cdict); + if (ZSTD_isError(size)) { + totalCompressedSize = size; + goto _compressCleanup; + } + totalCompressedSize += size; + } +_compressCleanup: + ZSTD_freeCCtx(cctx); + ZSTD_freeCDict(cdict); + if (dst) { + free(dst); + } + return totalCompressedSize; +} + + +/** + * Initialize the `COVER_best_t`. + */ +void COVER_best_init(COVER_best_t *best) { + if (best==NULL) return; /* compatible with init on NULL */ + (void)ZSTD_pthread_mutex_init(&best->mutex, NULL); + (void)ZSTD_pthread_cond_init(&best->cond, NULL); + best->liveJobs = 0; + best->dict = NULL; + best->dictSize = 0; + best->compressedSize = (size_t)-1; + memset(&best->parameters, 0, sizeof(best->parameters)); +} + +/** + * Wait until liveJobs == 0. + */ +void COVER_best_wait(COVER_best_t *best) { + if (!best) { + return; + } + ZSTD_pthread_mutex_lock(&best->mutex); + while (best->liveJobs != 0) { + ZSTD_pthread_cond_wait(&best->cond, &best->mutex); + } + ZSTD_pthread_mutex_unlock(&best->mutex); +} + +/** + * Call COVER_best_wait() and then destroy the COVER_best_t. + */ +void COVER_best_destroy(COVER_best_t *best) { + if (!best) { + return; + } + COVER_best_wait(best); + if (best->dict) { + free(best->dict); + } + ZSTD_pthread_mutex_destroy(&best->mutex); + ZSTD_pthread_cond_destroy(&best->cond); +} + +/** + * Called when a thread is about to be launched. + * Increments liveJobs. + */ +void COVER_best_start(COVER_best_t *best) { + if (!best) { + return; + } + ZSTD_pthread_mutex_lock(&best->mutex); + ++best->liveJobs; + ZSTD_pthread_mutex_unlock(&best->mutex); +} + +/** + * Called when a thread finishes executing, both on error or success. + * Decrements liveJobs and signals any waiting threads if liveJobs == 0. + * If this dictionary is the best so far save it and its parameters. + */ +void COVER_best_finish(COVER_best_t* best, + ZDICT_cover_params_t parameters, + COVER_dictSelection_t selection) +{ + void* dict = selection.dictContent; + size_t compressedSize = selection.totalCompressedSize; + size_t dictSize = selection.dictSize; + if (!best) { + return; + } + { + size_t liveJobs; + ZSTD_pthread_mutex_lock(&best->mutex); + --best->liveJobs; + liveJobs = best->liveJobs; + /* If the new dictionary is better */ + if (compressedSize < best->compressedSize) { + /* Allocate space if necessary */ + if (!best->dict || best->dictSize < dictSize) { + if (best->dict) { + free(best->dict); + } + best->dict = malloc(dictSize); + if (!best->dict) { + best->compressedSize = ERROR(GENERIC); + best->dictSize = 0; + ZSTD_pthread_cond_signal(&best->cond); + ZSTD_pthread_mutex_unlock(&best->mutex); + return; + } + } + /* Save the dictionary, parameters, and size */ + if (dict) { + memcpy(best->dict, dict, dictSize); + best->dictSize = dictSize; + best->parameters = parameters; + best->compressedSize = compressedSize; + } + } + if (liveJobs == 0) { + ZSTD_pthread_cond_broadcast(&best->cond); + } + ZSTD_pthread_mutex_unlock(&best->mutex); + } +} + +static COVER_dictSelection_t setDictSelection(BYTE* buf, size_t s, size_t csz) +{ + COVER_dictSelection_t ds; + ds.dictContent = buf; + ds.dictSize = s; + ds.totalCompressedSize = csz; + return ds; +} + +COVER_dictSelection_t COVER_dictSelectionError(size_t error) { + return setDictSelection(NULL, 0, error); +} + +unsigned COVER_dictSelectionIsError(COVER_dictSelection_t selection) { + return (ZSTD_isError(selection.totalCompressedSize) || !selection.dictContent); +} + +void COVER_dictSelectionFree(COVER_dictSelection_t selection){ + free(selection.dictContent); +} + +COVER_dictSelection_t COVER_selectDict(BYTE* customDictContent, size_t dictBufferCapacity, + size_t dictContentSize, const BYTE* samplesBuffer, const size_t* samplesSizes, unsigned nbFinalizeSamples, + size_t nbCheckSamples, size_t nbSamples, ZDICT_cover_params_t params, size_t* offsets, size_t totalCompressedSize) { + + size_t largestDict = 0; + size_t largestCompressed = 0; + BYTE* customDictContentEnd = customDictContent + dictContentSize; + + BYTE* largestDictbuffer = (BYTE*)malloc(dictBufferCapacity); + BYTE* candidateDictBuffer = (BYTE*)malloc(dictBufferCapacity); + double regressionTolerance = ((double)params.shrinkDictMaxRegression / 100.0) + 1.00; + + if (!largestDictbuffer || !candidateDictBuffer) { + free(largestDictbuffer); + free(candidateDictBuffer); + return COVER_dictSelectionError(dictContentSize); + } + + /* Initial dictionary size and compressed size */ + memcpy(largestDictbuffer, customDictContent, dictContentSize); + dictContentSize = ZDICT_finalizeDictionary( + largestDictbuffer, dictBufferCapacity, customDictContent, dictContentSize, + samplesBuffer, samplesSizes, nbFinalizeSamples, params.zParams); + + if (ZDICT_isError(dictContentSize)) { + free(largestDictbuffer); + free(candidateDictBuffer); + return COVER_dictSelectionError(dictContentSize); + } + + totalCompressedSize = COVER_checkTotalCompressedSize(params, samplesSizes, + samplesBuffer, offsets, + nbCheckSamples, nbSamples, + largestDictbuffer, dictContentSize); + + if (ZSTD_isError(totalCompressedSize)) { + free(largestDictbuffer); + free(candidateDictBuffer); + return COVER_dictSelectionError(totalCompressedSize); + } + + if (params.shrinkDict == 0) { + free(candidateDictBuffer); + return setDictSelection(largestDictbuffer, dictContentSize, totalCompressedSize); + } + + largestDict = dictContentSize; + largestCompressed = totalCompressedSize; + dictContentSize = ZDICT_DICTSIZE_MIN; + + /* Largest dict is initially at least ZDICT_DICTSIZE_MIN */ + while (dictContentSize < largestDict) { + memcpy(candidateDictBuffer, largestDictbuffer, largestDict); + dictContentSize = ZDICT_finalizeDictionary( + candidateDictBuffer, dictBufferCapacity, customDictContentEnd - dictContentSize, dictContentSize, + samplesBuffer, samplesSizes, nbFinalizeSamples, params.zParams); + + if (ZDICT_isError(dictContentSize)) { + free(largestDictbuffer); + free(candidateDictBuffer); + return COVER_dictSelectionError(dictContentSize); + + } + + totalCompressedSize = COVER_checkTotalCompressedSize(params, samplesSizes, + samplesBuffer, offsets, + nbCheckSamples, nbSamples, + candidateDictBuffer, dictContentSize); + + if (ZSTD_isError(totalCompressedSize)) { + free(largestDictbuffer); + free(candidateDictBuffer); + return COVER_dictSelectionError(totalCompressedSize); + } + + if ((double)totalCompressedSize <= (double)largestCompressed * regressionTolerance) { + free(largestDictbuffer); + return setDictSelection( candidateDictBuffer, dictContentSize, totalCompressedSize ); + } + dictContentSize *= 2; + } + dictContentSize = largestDict; + totalCompressedSize = largestCompressed; + free(candidateDictBuffer); + return setDictSelection( largestDictbuffer, dictContentSize, totalCompressedSize ); +} + +/** + * Parameters for COVER_tryParameters(). + */ +typedef struct COVER_tryParameters_data_s { + const COVER_ctx_t *ctx; + COVER_best_t *best; + size_t dictBufferCapacity; + ZDICT_cover_params_t parameters; +} COVER_tryParameters_data_t; + +/** + * Tries a set of parameters and updates the COVER_best_t with the results. + * This function is thread safe if zstd is compiled with multithreaded support. + * It takes its parameters as an *OWNING* opaque pointer to support threading. + */ +static void COVER_tryParameters(void *opaque) +{ + /* Save parameters as local variables */ + COVER_tryParameters_data_t *const data = (COVER_tryParameters_data_t*)opaque; + const COVER_ctx_t *const ctx = data->ctx; + const ZDICT_cover_params_t parameters = data->parameters; + size_t dictBufferCapacity = data->dictBufferCapacity; + size_t totalCompressedSize = ERROR(GENERIC); + /* Allocate space for hash table, dict, and freqs */ + COVER_map_t activeDmers; + BYTE* const dict = (BYTE*)malloc(dictBufferCapacity); + COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC)); + U32* const freqs = (U32*)malloc(ctx->suffixSize * sizeof(U32)); + if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) { + DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n"); + goto _cleanup; + } + if (!dict || !freqs) { + DISPLAYLEVEL(1, "Failed to allocate buffers: out of memory\n"); + goto _cleanup; + } + /* Copy the frequencies because we need to modify them */ + memcpy(freqs, ctx->freqs, ctx->suffixSize * sizeof(U32)); + /* Build the dictionary */ + { + const size_t tail = COVER_buildDictionary(ctx, freqs, &activeDmers, dict, + dictBufferCapacity, parameters); + selection = COVER_selectDict(dict + tail, dictBufferCapacity, dictBufferCapacity - tail, + ctx->samples, ctx->samplesSizes, (unsigned)ctx->nbTrainSamples, ctx->nbTrainSamples, ctx->nbSamples, parameters, ctx->offsets, + totalCompressedSize); + + if (COVER_dictSelectionIsError(selection)) { + DISPLAYLEVEL(1, "Failed to select dictionary\n"); + goto _cleanup; + } + } +_cleanup: + free(dict); + COVER_best_finish(data->best, parameters, selection); + free(data); + COVER_map_destroy(&activeDmers); + COVER_dictSelectionFree(selection); + free(freqs); +} + +ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover( + void* dictBuffer, size_t dictBufferCapacity, const void* samplesBuffer, + const size_t* samplesSizes, unsigned nbSamples, + ZDICT_cover_params_t* parameters) +{ + /* constants */ + const unsigned nbThreads = parameters->nbThreads; + const double splitPoint = + parameters->splitPoint <= 0.0 ? COVER_DEFAULT_SPLITPOINT : parameters->splitPoint; + const unsigned kMinD = parameters->d == 0 ? 6 : parameters->d; + const unsigned kMaxD = parameters->d == 0 ? 8 : parameters->d; + const unsigned kMinK = parameters->k == 0 ? 50 : parameters->k; + const unsigned kMaxK = parameters->k == 0 ? 2000 : parameters->k; + const unsigned kSteps = parameters->steps == 0 ? 40 : parameters->steps; + const unsigned kStepSize = MAX((kMaxK - kMinK) / kSteps, 1); + const unsigned kIterations = + (1 + (kMaxD - kMinD) / 2) * (1 + (kMaxK - kMinK) / kStepSize); + const unsigned shrinkDict = 0; + /* Local variables */ + const int displayLevel = parameters->zParams.notificationLevel; + unsigned iteration = 1; + unsigned d; + unsigned k; + COVER_best_t best; + POOL_ctx *pool = NULL; + int warned = 0; + + /* Checks */ + if (splitPoint <= 0 || splitPoint > 1) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect parameters\n"); + return ERROR(parameter_outOfBound); + } + if (kMinK < kMaxD || kMaxK < kMinK) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect parameters\n"); + return ERROR(parameter_outOfBound); + } + if (nbSamples == 0) { + DISPLAYLEVEL(1, "Cover must have at least one input file\n"); + return ERROR(srcSize_wrong); + } + if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) { + DISPLAYLEVEL(1, "dictBufferCapacity must be at least %u\n", + ZDICT_DICTSIZE_MIN); + return ERROR(dstSize_tooSmall); + } + if (nbThreads > 1) { + pool = POOL_create(nbThreads, 1); + if (!pool) { + return ERROR(memory_allocation); + } + } + /* Initialization */ + COVER_best_init(&best); + /* Turn down global display level to clean up display at level 2 and below */ + g_displayLevel = displayLevel == 0 ? 0 : displayLevel - 1; + /* Loop through d first because each new value needs a new context */ + LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n", + kIterations); + for (d = kMinD; d <= kMaxD; d += 2) { + /* Initialize the context for this value of d */ + COVER_ctx_t ctx; + LOCALDISPLAYLEVEL(displayLevel, 3, "d=%u\n", d); + { + const size_t initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, d, splitPoint); + if (ZSTD_isError(initVal)) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to initialize context\n"); + COVER_best_destroy(&best); + POOL_free(pool); + return initVal; + } + } + if (!warned) { + COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.suffixSize, displayLevel); + warned = 1; + } + /* Loop through k reusing the same context */ + for (k = kMinK; k <= kMaxK; k += kStepSize) { + /* Prepare the arguments */ + COVER_tryParameters_data_t *data = (COVER_tryParameters_data_t *)malloc( + sizeof(COVER_tryParameters_data_t)); + LOCALDISPLAYLEVEL(displayLevel, 3, "k=%u\n", k); + if (!data) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to allocate parameters\n"); + COVER_best_destroy(&best); + COVER_ctx_destroy(&ctx); + POOL_free(pool); + return ERROR(memory_allocation); + } + data->ctx = &ctx; + data->best = &best; + data->dictBufferCapacity = dictBufferCapacity; + data->parameters = *parameters; + data->parameters.k = k; + data->parameters.d = d; + data->parameters.splitPoint = splitPoint; + data->parameters.steps = kSteps; + data->parameters.shrinkDict = shrinkDict; + data->parameters.zParams.notificationLevel = g_displayLevel; + /* Check the parameters */ + if (!COVER_checkParameters(data->parameters, dictBufferCapacity)) { + DISPLAYLEVEL(1, "Cover parameters incorrect\n"); + free(data); + continue; + } + /* Call the function and pass ownership of data to it */ + COVER_best_start(&best); + if (pool) { + POOL_add(pool, &COVER_tryParameters, data); + } else { + COVER_tryParameters(data); + } + /* Print status */ + LOCALDISPLAYUPDATE(displayLevel, 2, "\r%u%% ", + (unsigned)((iteration * 100) / kIterations)); + ++iteration; + } + COVER_best_wait(&best); + COVER_ctx_destroy(&ctx); + } + LOCALDISPLAYLEVEL(displayLevel, 2, "\r%79s\r", ""); + /* Fill the output buffer and parameters with output of the best parameters */ + { + const size_t dictSize = best.dictSize; + if (ZSTD_isError(best.compressedSize)) { + const size_t compressedSize = best.compressedSize; + COVER_best_destroy(&best); + POOL_free(pool); + return compressedSize; + } + *parameters = best.parameters; + memcpy(dictBuffer, best.dict, dictSize); + COVER_best_destroy(&best); + POOL_free(pool); + return dictSize; + } +} diff --git a/cpp/third_party/zstd-1.5.7/lib/dictBuilder/cover.h b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/cover.h new file mode 100644 index 000000000..a5d7506ef --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/cover.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZDICT_STATIC_LINKING_ONLY +# define ZDICT_STATIC_LINKING_ONLY +#endif + +#include "../common/threading.h" /* ZSTD_pthread_mutex_t */ +#include "../common/mem.h" /* U32, BYTE */ +#include "../zdict.h" + +/** + * COVER_best_t is used for two purposes: + * 1. Synchronizing threads. + * 2. Saving the best parameters and dictionary. + * + * All of the methods except COVER_best_init() are thread safe if zstd is + * compiled with multithreaded support. + */ +typedef struct COVER_best_s { + ZSTD_pthread_mutex_t mutex; + ZSTD_pthread_cond_t cond; + size_t liveJobs; + void *dict; + size_t dictSize; + ZDICT_cover_params_t parameters; + size_t compressedSize; +} COVER_best_t; + +/** + * A segment is a range in the source as well as the score of the segment. + */ +typedef struct { + U32 begin; + U32 end; + U32 score; +} COVER_segment_t; + +/** + *Number of epochs and size of each epoch. + */ +typedef struct { + U32 num; + U32 size; +} COVER_epoch_info_t; + +/** + * Struct used for the dictionary selection function. + */ +typedef struct COVER_dictSelection { + BYTE* dictContent; + size_t dictSize; + size_t totalCompressedSize; +} COVER_dictSelection_t; + +/** + * Computes the number of epochs and the size of each epoch. + * We will make sure that each epoch gets at least 10 * k bytes. + * + * The COVER algorithms divide the data up into epochs of equal size and + * select one segment from each epoch. + * + * @param maxDictSize The maximum allowed dictionary size. + * @param nbDmers The number of dmers we are training on. + * @param k The parameter k (segment size). + * @param passes The target number of passes over the dmer corpus. + * More passes means a better dictionary. + */ +COVER_epoch_info_t COVER_computeEpochs(U32 maxDictSize, U32 nbDmers, + U32 k, U32 passes); + +/** + * Warns the user when their corpus is too small. + */ +void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLevel); + +/** + * Checks total compressed size of a dictionary + */ +size_t COVER_checkTotalCompressedSize(const ZDICT_cover_params_t parameters, + const size_t *samplesSizes, const BYTE *samples, + size_t *offsets, + size_t nbTrainSamples, size_t nbSamples, + BYTE *const dict, size_t dictBufferCapacity); + +/** + * Returns the sum of the sample sizes. + */ +size_t COVER_sum(const size_t *samplesSizes, unsigned nbSamples) ; + +/** + * Initialize the `COVER_best_t`. + */ +void COVER_best_init(COVER_best_t *best); + +/** + * Wait until liveJobs == 0. + */ +void COVER_best_wait(COVER_best_t *best); + +/** + * Call COVER_best_wait() and then destroy the COVER_best_t. + */ +void COVER_best_destroy(COVER_best_t *best); + +/** + * Called when a thread is about to be launched. + * Increments liveJobs. + */ +void COVER_best_start(COVER_best_t *best); + +/** + * Called when a thread finishes executing, both on error or success. + * Decrements liveJobs and signals any waiting threads if liveJobs == 0. + * If this dictionary is the best so far save it and its parameters. + */ +void COVER_best_finish(COVER_best_t *best, ZDICT_cover_params_t parameters, + COVER_dictSelection_t selection); +/** + * Error function for COVER_selectDict function. Checks if the return + * value is an error. + */ +unsigned COVER_dictSelectionIsError(COVER_dictSelection_t selection); + + /** + * Error function for COVER_selectDict function. Returns a struct where + * return.totalCompressedSize is a ZSTD error. + */ +COVER_dictSelection_t COVER_dictSelectionError(size_t error); + +/** + * Always call after selectDict is called to free up used memory from + * newly created dictionary. + */ +void COVER_dictSelectionFree(COVER_dictSelection_t selection); + +/** + * Called to finalize the dictionary and select one based on whether or not + * the shrink-dict flag was enabled. If enabled the dictionary used is the + * smallest dictionary within a specified regression of the compressed size + * from the largest dictionary. + */ + COVER_dictSelection_t COVER_selectDict(BYTE* customDictContent, size_t dictBufferCapacity, + size_t dictContentSize, const BYTE* samplesBuffer, const size_t* samplesSizes, unsigned nbFinalizeSamples, + size_t nbCheckSamples, size_t nbSamples, ZDICT_cover_params_t params, size_t* offsets, size_t totalCompressedSize); diff --git a/cpp/third_party/zstd-1.5.7/lib/dictBuilder/divsufsort.c b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/divsufsort.c new file mode 100644 index 000000000..a2870fb3b --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/divsufsort.c @@ -0,0 +1,1913 @@ +/* + * divsufsort.c for libdivsufsort-lite + * Copyright (c) 2003-2008 Yuta Mori All Rights Reserved. + * + * 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. + */ + +/*- Compiler specifics -*/ +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wshorten-64-to-32" +#endif + +#if defined(_MSC_VER) +# pragma warning(disable : 4244) +# pragma warning(disable : 4127) /* C4127 : Condition expression is constant */ +#endif + + +/*- Dependencies -*/ +#include +#include +#include + +#include "divsufsort.h" + +/*- Constants -*/ +#if defined(INLINE) +# undef INLINE +#endif +#if !defined(INLINE) +# define INLINE __inline +#endif +#if defined(ALPHABET_SIZE) && (ALPHABET_SIZE < 1) +# undef ALPHABET_SIZE +#endif +#if !defined(ALPHABET_SIZE) +# define ALPHABET_SIZE (256) +#endif +#define BUCKET_A_SIZE (ALPHABET_SIZE) +#define BUCKET_B_SIZE (ALPHABET_SIZE * ALPHABET_SIZE) +#if defined(SS_INSERTIONSORT_THRESHOLD) +# if SS_INSERTIONSORT_THRESHOLD < 1 +# undef SS_INSERTIONSORT_THRESHOLD +# define SS_INSERTIONSORT_THRESHOLD (1) +# endif +#else +# define SS_INSERTIONSORT_THRESHOLD (8) +#endif +#if defined(SS_BLOCKSIZE) +# if SS_BLOCKSIZE < 0 +# undef SS_BLOCKSIZE +# define SS_BLOCKSIZE (0) +# elif 32768 <= SS_BLOCKSIZE +# undef SS_BLOCKSIZE +# define SS_BLOCKSIZE (32767) +# endif +#else +# define SS_BLOCKSIZE (1024) +#endif +/* minstacksize = log(SS_BLOCKSIZE) / log(3) * 2 */ +#if SS_BLOCKSIZE == 0 +# define SS_MISORT_STACKSIZE (96) +#elif SS_BLOCKSIZE <= 4096 +# define SS_MISORT_STACKSIZE (16) +#else +# define SS_MISORT_STACKSIZE (24) +#endif +#define SS_SMERGE_STACKSIZE (32) +#define TR_INSERTIONSORT_THRESHOLD (8) +#define TR_STACKSIZE (64) + + +/*- Macros -*/ +#ifndef SWAP +# define SWAP(_a, _b) do { t = (_a); (_a) = (_b); (_b) = t; } while(0) +#endif /* SWAP */ +#ifndef MIN +# define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b)) +#endif /* MIN */ +#ifndef MAX +# define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b)) +#endif /* MAX */ +#define STACK_PUSH(_a, _b, _c, _d)\ + do {\ + assert(ssize < STACK_SIZE);\ + stack[ssize].a = (_a), stack[ssize].b = (_b),\ + stack[ssize].c = (_c), stack[ssize++].d = (_d);\ + } while(0) +#define STACK_PUSH5(_a, _b, _c, _d, _e)\ + do {\ + assert(ssize < STACK_SIZE);\ + stack[ssize].a = (_a), stack[ssize].b = (_b),\ + stack[ssize].c = (_c), stack[ssize].d = (_d), stack[ssize++].e = (_e);\ + } while(0) +#define STACK_POP(_a, _b, _c, _d)\ + do {\ + assert(0 <= ssize);\ + if(ssize == 0) { return; }\ + (_a) = stack[--ssize].a, (_b) = stack[ssize].b,\ + (_c) = stack[ssize].c, (_d) = stack[ssize].d;\ + } while(0) +#define STACK_POP5(_a, _b, _c, _d, _e)\ + do {\ + assert(0 <= ssize);\ + if(ssize == 0) { return; }\ + (_a) = stack[--ssize].a, (_b) = stack[ssize].b,\ + (_c) = stack[ssize].c, (_d) = stack[ssize].d, (_e) = stack[ssize].e;\ + } while(0) +#define BUCKET_A(_c0) bucket_A[(_c0)] +#if ALPHABET_SIZE == 256 +#define BUCKET_B(_c0, _c1) (bucket_B[((_c1) << 8) | (_c0)]) +#define BUCKET_BSTAR(_c0, _c1) (bucket_B[((_c0) << 8) | (_c1)]) +#else +#define BUCKET_B(_c0, _c1) (bucket_B[(_c1) * ALPHABET_SIZE + (_c0)]) +#define BUCKET_BSTAR(_c0, _c1) (bucket_B[(_c0) * ALPHABET_SIZE + (_c1)]) +#endif + + +/*- Private Functions -*/ + +static const int lg_table[256]= { + -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +#if (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE) + +static INLINE +int +ss_ilg(int n) { +#if SS_BLOCKSIZE == 0 + return (n & 0xffff0000) ? + ((n & 0xff000000) ? + 24 + lg_table[(n >> 24) & 0xff] : + 16 + lg_table[(n >> 16) & 0xff]) : + ((n & 0x0000ff00) ? + 8 + lg_table[(n >> 8) & 0xff] : + 0 + lg_table[(n >> 0) & 0xff]); +#elif SS_BLOCKSIZE < 256 + return lg_table[n]; +#else + return (n & 0xff00) ? + 8 + lg_table[(n >> 8) & 0xff] : + 0 + lg_table[(n >> 0) & 0xff]; +#endif +} + +#endif /* (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE) */ + +#if SS_BLOCKSIZE != 0 + +static const int sqq_table[256] = { + 0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, 59, 61, + 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83, 84, 86, 87, 89, + 90, 91, 93, 94, 96, 97, 98, 99, 101, 102, 103, 104, 106, 107, 108, 109, +110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, +128, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, +143, 144, 144, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, +156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168, +169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178, 179, 180, +181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, 191, +192, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, +202, 203, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211, +212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 221, +221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, +230, 231, 231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, +239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, +247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255 +}; + +static INLINE +int +ss_isqrt(int x) { + int y, e; + + if(x >= (SS_BLOCKSIZE * SS_BLOCKSIZE)) { return SS_BLOCKSIZE; } + e = (x & 0xffff0000) ? + ((x & 0xff000000) ? + 24 + lg_table[(x >> 24) & 0xff] : + 16 + lg_table[(x >> 16) & 0xff]) : + ((x & 0x0000ff00) ? + 8 + lg_table[(x >> 8) & 0xff] : + 0 + lg_table[(x >> 0) & 0xff]); + + if(e >= 16) { + y = sqq_table[x >> ((e - 6) - (e & 1))] << ((e >> 1) - 7); + if(e >= 24) { y = (y + 1 + x / y) >> 1; } + y = (y + 1 + x / y) >> 1; + } else if(e >= 8) { + y = (sqq_table[x >> ((e - 6) - (e & 1))] >> (7 - (e >> 1))) + 1; + } else { + return sqq_table[x] >> 4; + } + + return (x < (y * y)) ? y - 1 : y; +} + +#endif /* SS_BLOCKSIZE != 0 */ + + +/*---------------------------------------------------------------------------*/ + +/* Compares two suffixes. */ +static INLINE +int +ss_compare(const unsigned char *T, + const int *p1, const int *p2, + int depth) { + const unsigned char *U1, *U2, *U1n, *U2n; + + for(U1 = T + depth + *p1, + U2 = T + depth + *p2, + U1n = T + *(p1 + 1) + 2, + U2n = T + *(p2 + 1) + 2; + (U1 < U1n) && (U2 < U2n) && (*U1 == *U2); + ++U1, ++U2) { + } + + return U1 < U1n ? + (U2 < U2n ? *U1 - *U2 : 1) : + (U2 < U2n ? -1 : 0); +} + + +/*---------------------------------------------------------------------------*/ + +#if (SS_BLOCKSIZE != 1) && (SS_INSERTIONSORT_THRESHOLD != 1) + +/* Insertionsort for small size groups */ +static +void +ss_insertionsort(const unsigned char *T, const int *PA, + int *first, int *last, int depth) { + int *i, *j; + int t; + int r; + + for(i = last - 2; first <= i; --i) { + for(t = *i, j = i + 1; 0 < (r = ss_compare(T, PA + t, PA + *j, depth));) { + do { *(j - 1) = *j; } while((++j < last) && (*j < 0)); + if(last <= j) { break; } + } + if(r == 0) { *j = ~*j; } + *(j - 1) = t; + } +} + +#endif /* (SS_BLOCKSIZE != 1) && (SS_INSERTIONSORT_THRESHOLD != 1) */ + + +/*---------------------------------------------------------------------------*/ + +#if (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE) + +static INLINE +void +ss_fixdown(const unsigned char *Td, const int *PA, + int *SA, int i, int size) { + int j, k; + int v; + int c, d, e; + + for(v = SA[i], c = Td[PA[v]]; (j = 2 * i + 1) < size; SA[i] = SA[k], i = k) { + d = Td[PA[SA[k = j++]]]; + if(d < (e = Td[PA[SA[j]]])) { k = j; d = e; } + if(d <= c) { break; } + } + SA[i] = v; +} + +/* Simple top-down heapsort. */ +static +void +ss_heapsort(const unsigned char *Td, const int *PA, int *SA, int size) { + int i, m; + int t; + + m = size; + if((size % 2) == 0) { + m--; + if(Td[PA[SA[m / 2]]] < Td[PA[SA[m]]]) { SWAP(SA[m], SA[m / 2]); } + } + + for(i = m / 2 - 1; 0 <= i; --i) { ss_fixdown(Td, PA, SA, i, m); } + if((size % 2) == 0) { SWAP(SA[0], SA[m]); ss_fixdown(Td, PA, SA, 0, m); } + for(i = m - 1; 0 < i; --i) { + t = SA[0], SA[0] = SA[i]; + ss_fixdown(Td, PA, SA, 0, i); + SA[i] = t; + } +} + + +/*---------------------------------------------------------------------------*/ + +/* Returns the median of three elements. */ +static INLINE +int * +ss_median3(const unsigned char *Td, const int *PA, + int *v1, int *v2, int *v3) { + int *t; + if(Td[PA[*v1]] > Td[PA[*v2]]) { SWAP(v1, v2); } + if(Td[PA[*v2]] > Td[PA[*v3]]) { + if(Td[PA[*v1]] > Td[PA[*v3]]) { return v1; } + else { return v3; } + } + return v2; +} + +/* Returns the median of five elements. */ +static INLINE +int * +ss_median5(const unsigned char *Td, const int *PA, + int *v1, int *v2, int *v3, int *v4, int *v5) { + int *t; + if(Td[PA[*v2]] > Td[PA[*v3]]) { SWAP(v2, v3); } + if(Td[PA[*v4]] > Td[PA[*v5]]) { SWAP(v4, v5); } + if(Td[PA[*v2]] > Td[PA[*v4]]) { SWAP(v2, v4); SWAP(v3, v5); } + if(Td[PA[*v1]] > Td[PA[*v3]]) { SWAP(v1, v3); } + if(Td[PA[*v1]] > Td[PA[*v4]]) { SWAP(v1, v4); SWAP(v3, v5); } + if(Td[PA[*v3]] > Td[PA[*v4]]) { return v4; } + return v3; +} + +/* Returns the pivot element. */ +static INLINE +int * +ss_pivot(const unsigned char *Td, const int *PA, int *first, int *last) { + int *middle; + int t; + + t = last - first; + middle = first + t / 2; + + if(t <= 512) { + if(t <= 32) { + return ss_median3(Td, PA, first, middle, last - 1); + } else { + t >>= 2; + return ss_median5(Td, PA, first, first + t, middle, last - 1 - t, last - 1); + } + } + t >>= 3; + first = ss_median3(Td, PA, first, first + t, first + (t << 1)); + middle = ss_median3(Td, PA, middle - t, middle, middle + t); + last = ss_median3(Td, PA, last - 1 - (t << 1), last - 1 - t, last - 1); + return ss_median3(Td, PA, first, middle, last); +} + + +/*---------------------------------------------------------------------------*/ + +/* Binary partition for substrings. */ +static INLINE +int * +ss_partition(const int *PA, + int *first, int *last, int depth) { + int *a, *b; + int t; + for(a = first - 1, b = last;;) { + for(; (++a < b) && ((PA[*a] + depth) >= (PA[*a + 1] + 1));) { *a = ~*a; } + for(; (a < --b) && ((PA[*b] + depth) < (PA[*b + 1] + 1));) { } + if(b <= a) { break; } + t = ~*b; + *b = *a; + *a = t; + } + if(first < a) { *first = ~*first; } + return a; +} + +/* Multikey introsort for medium size groups. */ +static +void +ss_mintrosort(const unsigned char *T, const int *PA, + int *first, int *last, + int depth) { +#define STACK_SIZE SS_MISORT_STACKSIZE + struct { int *a, *b, c; int d; } stack[STACK_SIZE]; + const unsigned char *Td; + int *a, *b, *c, *d, *e, *f; + int s, t; + int ssize; + int limit; + int v, x = 0; + + for(ssize = 0, limit = ss_ilg(last - first);;) { + + if((last - first) <= SS_INSERTIONSORT_THRESHOLD) { +#if 1 < SS_INSERTIONSORT_THRESHOLD + if(1 < (last - first)) { ss_insertionsort(T, PA, first, last, depth); } +#endif + STACK_POP(first, last, depth, limit); + continue; + } + + Td = T + depth; + if(limit-- == 0) { ss_heapsort(Td, PA, first, last - first); } + if(limit < 0) { + for(a = first + 1, v = Td[PA[*first]]; a < last; ++a) { + if((x = Td[PA[*a]]) != v) { + if(1 < (a - first)) { break; } + v = x; + first = a; + } + } + if(Td[PA[*first] - 1] < v) { + first = ss_partition(PA, first, a, depth); + } + if((a - first) <= (last - a)) { + if(1 < (a - first)) { + STACK_PUSH(a, last, depth, -1); + last = a, depth += 1, limit = ss_ilg(a - first); + } else { + first = a, limit = -1; + } + } else { + if(1 < (last - a)) { + STACK_PUSH(first, a, depth + 1, ss_ilg(a - first)); + first = a, limit = -1; + } else { + last = a, depth += 1, limit = ss_ilg(a - first); + } + } + continue; + } + + /* choose pivot */ + a = ss_pivot(Td, PA, first, last); + v = Td[PA[*a]]; + SWAP(*first, *a); + + /* partition */ + for(b = first; (++b < last) && ((x = Td[PA[*b]]) == v);) { } + if(((a = b) < last) && (x < v)) { + for(; (++b < last) && ((x = Td[PA[*b]]) <= v);) { + if(x == v) { SWAP(*b, *a); ++a; } + } + } + for(c = last; (b < --c) && ((x = Td[PA[*c]]) == v);) { } + if((b < (d = c)) && (x > v)) { + for(; (b < --c) && ((x = Td[PA[*c]]) >= v);) { + if(x == v) { SWAP(*c, *d); --d; } + } + } + for(; b < c;) { + SWAP(*b, *c); + for(; (++b < c) && ((x = Td[PA[*b]]) <= v);) { + if(x == v) { SWAP(*b, *a); ++a; } + } + for(; (b < --c) && ((x = Td[PA[*c]]) >= v);) { + if(x == v) { SWAP(*c, *d); --d; } + } + } + + if(a <= d) { + c = b - 1; + + if((s = a - first) > (t = b - a)) { s = t; } + for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); } + if((s = d - c) > (t = last - d - 1)) { s = t; } + for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); } + + a = first + (b - a), c = last - (d - c); + b = (v <= Td[PA[*a] - 1]) ? a : ss_partition(PA, a, c, depth); + + if((a - first) <= (last - c)) { + if((last - c) <= (c - b)) { + STACK_PUSH(b, c, depth + 1, ss_ilg(c - b)); + STACK_PUSH(c, last, depth, limit); + last = a; + } else if((a - first) <= (c - b)) { + STACK_PUSH(c, last, depth, limit); + STACK_PUSH(b, c, depth + 1, ss_ilg(c - b)); + last = a; + } else { + STACK_PUSH(c, last, depth, limit); + STACK_PUSH(first, a, depth, limit); + first = b, last = c, depth += 1, limit = ss_ilg(c - b); + } + } else { + if((a - first) <= (c - b)) { + STACK_PUSH(b, c, depth + 1, ss_ilg(c - b)); + STACK_PUSH(first, a, depth, limit); + first = c; + } else if((last - c) <= (c - b)) { + STACK_PUSH(first, a, depth, limit); + STACK_PUSH(b, c, depth + 1, ss_ilg(c - b)); + first = c; + } else { + STACK_PUSH(first, a, depth, limit); + STACK_PUSH(c, last, depth, limit); + first = b, last = c, depth += 1, limit = ss_ilg(c - b); + } + } + } else { + limit += 1; + if(Td[PA[*first] - 1] < v) { + first = ss_partition(PA, first, last, depth); + limit = ss_ilg(last - first); + } + depth += 1; + } + } +#undef STACK_SIZE +} + +#endif /* (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE) */ + + +/*---------------------------------------------------------------------------*/ + +#if SS_BLOCKSIZE != 0 + +static INLINE +void +ss_blockswap(int *a, int *b, int n) { + int t; + for(; 0 < n; --n, ++a, ++b) { + t = *a, *a = *b, *b = t; + } +} + +static INLINE +void +ss_rotate(int *first, int *middle, int *last) { + int *a, *b, t; + int l, r; + l = middle - first, r = last - middle; + for(; (0 < l) && (0 < r);) { + if(l == r) { ss_blockswap(first, middle, l); break; } + if(l < r) { + a = last - 1, b = middle - 1; + t = *a; + do { + *a-- = *b, *b-- = *a; + if(b < first) { + *a = t; + last = a; + if((r -= l + 1) <= l) { break; } + a -= 1, b = middle - 1; + t = *a; + } + } while(1); + } else { + a = first, b = middle; + t = *a; + do { + *a++ = *b, *b++ = *a; + if(last <= b) { + *a = t; + first = a + 1; + if((l -= r + 1) <= r) { break; } + a += 1, b = middle; + t = *a; + } + } while(1); + } + } +} + + +/*---------------------------------------------------------------------------*/ + +static +void +ss_inplacemerge(const unsigned char *T, const int *PA, + int *first, int *middle, int *last, + int depth) { + const int *p; + int *a, *b; + int len, half; + int q, r; + int x; + + for(;;) { + if(*(last - 1) < 0) { x = 1; p = PA + ~*(last - 1); } + else { x = 0; p = PA + *(last - 1); } + for(a = first, len = middle - first, half = len >> 1, r = -1; + 0 < len; + len = half, half >>= 1) { + b = a + half; + q = ss_compare(T, PA + ((0 <= *b) ? *b : ~*b), p, depth); + if(q < 0) { + a = b + 1; + half -= (len & 1) ^ 1; + } else { + r = q; + } + } + if(a < middle) { + if(r == 0) { *a = ~*a; } + ss_rotate(a, middle, last); + last -= middle - a; + middle = a; + if(first == middle) { break; } + } + --last; + if(x != 0) { while(*--last < 0) { } } + if(middle == last) { break; } + } +} + + +/*---------------------------------------------------------------------------*/ + +/* Merge-forward with internal buffer. */ +static +void +ss_mergeforward(const unsigned char *T, const int *PA, + int *first, int *middle, int *last, + int *buf, int depth) { + int *a, *b, *c, *bufend; + int t; + int r; + + bufend = buf + (middle - first) - 1; + ss_blockswap(buf, first, middle - first); + + for(t = *(a = first), b = buf, c = middle;;) { + r = ss_compare(T, PA + *b, PA + *c, depth); + if(r < 0) { + do { + *a++ = *b; + if(bufend <= b) { *bufend = t; return; } + *b++ = *a; + } while(*b < 0); + } else if(r > 0) { + do { + *a++ = *c, *c++ = *a; + if(last <= c) { + while(b < bufend) { *a++ = *b, *b++ = *a; } + *a = *b, *b = t; + return; + } + } while(*c < 0); + } else { + *c = ~*c; + do { + *a++ = *b; + if(bufend <= b) { *bufend = t; return; } + *b++ = *a; + } while(*b < 0); + + do { + *a++ = *c, *c++ = *a; + if(last <= c) { + while(b < bufend) { *a++ = *b, *b++ = *a; } + *a = *b, *b = t; + return; + } + } while(*c < 0); + } + } +} + +/* Merge-backward with internal buffer. */ +static +void +ss_mergebackward(const unsigned char *T, const int *PA, + int *first, int *middle, int *last, + int *buf, int depth) { + const int *p1, *p2; + int *a, *b, *c, *bufend; + int t; + int r; + int x; + + bufend = buf + (last - middle) - 1; + ss_blockswap(buf, middle, last - middle); + + x = 0; + if(*bufend < 0) { p1 = PA + ~*bufend; x |= 1; } + else { p1 = PA + *bufend; } + if(*(middle - 1) < 0) { p2 = PA + ~*(middle - 1); x |= 2; } + else { p2 = PA + *(middle - 1); } + for(t = *(a = last - 1), b = bufend, c = middle - 1;;) { + r = ss_compare(T, p1, p2, depth); + if(0 < r) { + if(x & 1) { do { *a-- = *b, *b-- = *a; } while(*b < 0); x ^= 1; } + *a-- = *b; + if(b <= buf) { *buf = t; break; } + *b-- = *a; + if(*b < 0) { p1 = PA + ~*b; x |= 1; } + else { p1 = PA + *b; } + } else if(r < 0) { + if(x & 2) { do { *a-- = *c, *c-- = *a; } while(*c < 0); x ^= 2; } + *a-- = *c, *c-- = *a; + if(c < first) { + while(buf < b) { *a-- = *b, *b-- = *a; } + *a = *b, *b = t; + break; + } + if(*c < 0) { p2 = PA + ~*c; x |= 2; } + else { p2 = PA + *c; } + } else { + if(x & 1) { do { *a-- = *b, *b-- = *a; } while(*b < 0); x ^= 1; } + *a-- = ~*b; + if(b <= buf) { *buf = t; break; } + *b-- = *a; + if(x & 2) { do { *a-- = *c, *c-- = *a; } while(*c < 0); x ^= 2; } + *a-- = *c, *c-- = *a; + if(c < first) { + while(buf < b) { *a-- = *b, *b-- = *a; } + *a = *b, *b = t; + break; + } + if(*b < 0) { p1 = PA + ~*b; x |= 1; } + else { p1 = PA + *b; } + if(*c < 0) { p2 = PA + ~*c; x |= 2; } + else { p2 = PA + *c; } + } + } +} + +/* D&C based merge. */ +static +void +ss_swapmerge(const unsigned char *T, const int *PA, + int *first, int *middle, int *last, + int *buf, int bufsize, int depth) { +#define STACK_SIZE SS_SMERGE_STACKSIZE +#define GETIDX(a) ((0 <= (a)) ? (a) : (~(a))) +#define MERGE_CHECK(a, b, c)\ + do {\ + if(((c) & 1) ||\ + (((c) & 2) && (ss_compare(T, PA + GETIDX(*((a) - 1)), PA + *(a), depth) == 0))) {\ + *(a) = ~*(a);\ + }\ + if(((c) & 4) && ((ss_compare(T, PA + GETIDX(*((b) - 1)), PA + *(b), depth) == 0))) {\ + *(b) = ~*(b);\ + }\ + } while(0) + struct { int *a, *b, *c; int d; } stack[STACK_SIZE]; + int *l, *r, *lm, *rm; + int m, len, half; + int ssize; + int check, next; + + for(check = 0, ssize = 0;;) { + if((last - middle) <= bufsize) { + if((first < middle) && (middle < last)) { + ss_mergebackward(T, PA, first, middle, last, buf, depth); + } + MERGE_CHECK(first, last, check); + STACK_POP(first, middle, last, check); + continue; + } + + if((middle - first) <= bufsize) { + if(first < middle) { + ss_mergeforward(T, PA, first, middle, last, buf, depth); + } + MERGE_CHECK(first, last, check); + STACK_POP(first, middle, last, check); + continue; + } + + for(m = 0, len = MIN(middle - first, last - middle), half = len >> 1; + 0 < len; + len = half, half >>= 1) { + if(ss_compare(T, PA + GETIDX(*(middle + m + half)), + PA + GETIDX(*(middle - m - half - 1)), depth) < 0) { + m += half + 1; + half -= (len & 1) ^ 1; + } + } + + if(0 < m) { + lm = middle - m, rm = middle + m; + ss_blockswap(lm, middle, m); + l = r = middle, next = 0; + if(rm < last) { + if(*rm < 0) { + *rm = ~*rm; + if(first < lm) { for(; *--l < 0;) { } next |= 4; } + next |= 1; + } else if(first < lm) { + for(; *r < 0; ++r) { } + next |= 2; + } + } + + if((l - first) <= (last - r)) { + STACK_PUSH(r, rm, last, (next & 3) | (check & 4)); + middle = lm, last = l, check = (check & 3) | (next & 4); + } else { + if((next & 2) && (r == middle)) { next ^= 6; } + STACK_PUSH(first, lm, l, (check & 3) | (next & 4)); + first = r, middle = rm, check = (next & 3) | (check & 4); + } + } else { + if(ss_compare(T, PA + GETIDX(*(middle - 1)), PA + *middle, depth) == 0) { + *middle = ~*middle; + } + MERGE_CHECK(first, last, check); + STACK_POP(first, middle, last, check); + } + } +#undef STACK_SIZE +} + +#endif /* SS_BLOCKSIZE != 0 */ + + +/*---------------------------------------------------------------------------*/ + +/* Substring sort */ +static +void +sssort(const unsigned char *T, const int *PA, + int *first, int *last, + int *buf, int bufsize, + int depth, int n, int lastsuffix) { + int *a; +#if SS_BLOCKSIZE != 0 + int *b, *middle, *curbuf; + int j, k, curbufsize, limit; +#endif + int i; + + if(lastsuffix != 0) { ++first; } + +#if SS_BLOCKSIZE == 0 + ss_mintrosort(T, PA, first, last, depth); +#else + if((bufsize < SS_BLOCKSIZE) && + (bufsize < (last - first)) && + (bufsize < (limit = ss_isqrt(last - first)))) { + if(SS_BLOCKSIZE < limit) { limit = SS_BLOCKSIZE; } + buf = middle = last - limit, bufsize = limit; + } else { + middle = last, limit = 0; + } + for(a = first, i = 0; SS_BLOCKSIZE < (middle - a); a += SS_BLOCKSIZE, ++i) { +#if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE + ss_mintrosort(T, PA, a, a + SS_BLOCKSIZE, depth); +#elif 1 < SS_BLOCKSIZE + ss_insertionsort(T, PA, a, a + SS_BLOCKSIZE, depth); +#endif + curbufsize = last - (a + SS_BLOCKSIZE); + curbuf = a + SS_BLOCKSIZE; + if(curbufsize <= bufsize) { curbufsize = bufsize, curbuf = buf; } + for(b = a, k = SS_BLOCKSIZE, j = i; j & 1; b -= k, k <<= 1, j >>= 1) { + ss_swapmerge(T, PA, b - k, b, b + k, curbuf, curbufsize, depth); + } + } +#if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE + ss_mintrosort(T, PA, a, middle, depth); +#elif 1 < SS_BLOCKSIZE + ss_insertionsort(T, PA, a, middle, depth); +#endif + for(k = SS_BLOCKSIZE; i != 0; k <<= 1, i >>= 1) { + if(i & 1) { + ss_swapmerge(T, PA, a - k, a, middle, buf, bufsize, depth); + a -= k; + } + } + if(limit != 0) { +#if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE + ss_mintrosort(T, PA, middle, last, depth); +#elif 1 < SS_BLOCKSIZE + ss_insertionsort(T, PA, middle, last, depth); +#endif + ss_inplacemerge(T, PA, first, middle, last, depth); + } +#endif + + if(lastsuffix != 0) { + /* Insert last type B* suffix. */ + int PAi[2]; PAi[0] = PA[*(first - 1)], PAi[1] = n - 2; + for(a = first, i = *(first - 1); + (a < last) && ((*a < 0) || (0 < ss_compare(T, &(PAi[0]), PA + *a, depth))); + ++a) { + *(a - 1) = *a; + } + *(a - 1) = i; + } +} + + +/*---------------------------------------------------------------------------*/ + +static INLINE +int +tr_ilg(int n) { + return (n & 0xffff0000) ? + ((n & 0xff000000) ? + 24 + lg_table[(n >> 24) & 0xff] : + 16 + lg_table[(n >> 16) & 0xff]) : + ((n & 0x0000ff00) ? + 8 + lg_table[(n >> 8) & 0xff] : + 0 + lg_table[(n >> 0) & 0xff]); +} + + +/*---------------------------------------------------------------------------*/ + +/* Simple insertionsort for small size groups. */ +static +void +tr_insertionsort(const int *ISAd, int *first, int *last) { + int *a, *b; + int t, r; + + for(a = first + 1; a < last; ++a) { + for(t = *a, b = a - 1; 0 > (r = ISAd[t] - ISAd[*b]);) { + do { *(b + 1) = *b; } while((first <= --b) && (*b < 0)); + if(b < first) { break; } + } + if(r == 0) { *b = ~*b; } + *(b + 1) = t; + } +} + + +/*---------------------------------------------------------------------------*/ + +static INLINE +void +tr_fixdown(const int *ISAd, int *SA, int i, int size) { + int j, k; + int v; + int c, d, e; + + for(v = SA[i], c = ISAd[v]; (j = 2 * i + 1) < size; SA[i] = SA[k], i = k) { + d = ISAd[SA[k = j++]]; + if(d < (e = ISAd[SA[j]])) { k = j; d = e; } + if(d <= c) { break; } + } + SA[i] = v; +} + +/* Simple top-down heapsort. */ +static +void +tr_heapsort(const int *ISAd, int *SA, int size) { + int i, m; + int t; + + m = size; + if((size % 2) == 0) { + m--; + if(ISAd[SA[m / 2]] < ISAd[SA[m]]) { SWAP(SA[m], SA[m / 2]); } + } + + for(i = m / 2 - 1; 0 <= i; --i) { tr_fixdown(ISAd, SA, i, m); } + if((size % 2) == 0) { SWAP(SA[0], SA[m]); tr_fixdown(ISAd, SA, 0, m); } + for(i = m - 1; 0 < i; --i) { + t = SA[0], SA[0] = SA[i]; + tr_fixdown(ISAd, SA, 0, i); + SA[i] = t; + } +} + + +/*---------------------------------------------------------------------------*/ + +/* Returns the median of three elements. */ +static INLINE +int * +tr_median3(const int *ISAd, int *v1, int *v2, int *v3) { + int *t; + if(ISAd[*v1] > ISAd[*v2]) { SWAP(v1, v2); } + if(ISAd[*v2] > ISAd[*v3]) { + if(ISAd[*v1] > ISAd[*v3]) { return v1; } + else { return v3; } + } + return v2; +} + +/* Returns the median of five elements. */ +static INLINE +int * +tr_median5(const int *ISAd, + int *v1, int *v2, int *v3, int *v4, int *v5) { + int *t; + if(ISAd[*v2] > ISAd[*v3]) { SWAP(v2, v3); } + if(ISAd[*v4] > ISAd[*v5]) { SWAP(v4, v5); } + if(ISAd[*v2] > ISAd[*v4]) { SWAP(v2, v4); SWAP(v3, v5); } + if(ISAd[*v1] > ISAd[*v3]) { SWAP(v1, v3); } + if(ISAd[*v1] > ISAd[*v4]) { SWAP(v1, v4); SWAP(v3, v5); } + if(ISAd[*v3] > ISAd[*v4]) { return v4; } + return v3; +} + +/* Returns the pivot element. */ +static INLINE +int * +tr_pivot(const int *ISAd, int *first, int *last) { + int *middle; + int t; + + t = last - first; + middle = first + t / 2; + + if(t <= 512) { + if(t <= 32) { + return tr_median3(ISAd, first, middle, last - 1); + } else { + t >>= 2; + return tr_median5(ISAd, first, first + t, middle, last - 1 - t, last - 1); + } + } + t >>= 3; + first = tr_median3(ISAd, first, first + t, first + (t << 1)); + middle = tr_median3(ISAd, middle - t, middle, middle + t); + last = tr_median3(ISAd, last - 1 - (t << 1), last - 1 - t, last - 1); + return tr_median3(ISAd, first, middle, last); +} + + +/*---------------------------------------------------------------------------*/ + +typedef struct _trbudget_t trbudget_t; +struct _trbudget_t { + int chance; + int remain; + int incval; + int count; +}; + +static INLINE +void +trbudget_init(trbudget_t *budget, int chance, int incval) { + budget->chance = chance; + budget->remain = budget->incval = incval; +} + +static INLINE +int +trbudget_check(trbudget_t *budget, int size) { + if(size <= budget->remain) { budget->remain -= size; return 1; } + if(budget->chance == 0) { budget->count += size; return 0; } + budget->remain += budget->incval - size; + budget->chance -= 1; + return 1; +} + + +/*---------------------------------------------------------------------------*/ + +static INLINE +void +tr_partition(const int *ISAd, + int *first, int *middle, int *last, + int **pa, int **pb, int v) { + int *a, *b, *c, *d, *e, *f; + int t, s; + int x = 0; + + for(b = middle - 1; (++b < last) && ((x = ISAd[*b]) == v);) { } + if(((a = b) < last) && (x < v)) { + for(; (++b < last) && ((x = ISAd[*b]) <= v);) { + if(x == v) { SWAP(*b, *a); ++a; } + } + } + for(c = last; (b < --c) && ((x = ISAd[*c]) == v);) { } + if((b < (d = c)) && (x > v)) { + for(; (b < --c) && ((x = ISAd[*c]) >= v);) { + if(x == v) { SWAP(*c, *d); --d; } + } + } + for(; b < c;) { + SWAP(*b, *c); + for(; (++b < c) && ((x = ISAd[*b]) <= v);) { + if(x == v) { SWAP(*b, *a); ++a; } + } + for(; (b < --c) && ((x = ISAd[*c]) >= v);) { + if(x == v) { SWAP(*c, *d); --d; } + } + } + + if(a <= d) { + c = b - 1; + if((s = a - first) > (t = b - a)) { s = t; } + for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); } + if((s = d - c) > (t = last - d - 1)) { s = t; } + for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); } + first += (b - a), last -= (d - c); + } + *pa = first, *pb = last; +} + +static +void +tr_copy(int *ISA, const int *SA, + int *first, int *a, int *b, int *last, + int depth) { + /* sort suffixes of middle partition + by using sorted order of suffixes of left and right partition. */ + int *c, *d, *e; + int s, v; + + v = b - SA - 1; + for(c = first, d = a - 1; c <= d; ++c) { + if((0 <= (s = *c - depth)) && (ISA[s] == v)) { + *++d = s; + ISA[s] = d - SA; + } + } + for(c = last - 1, e = d + 1, d = b; e < d; --c) { + if((0 <= (s = *c - depth)) && (ISA[s] == v)) { + *--d = s; + ISA[s] = d - SA; + } + } +} + +static +void +tr_partialcopy(int *ISA, const int *SA, + int *first, int *a, int *b, int *last, + int depth) { + int *c, *d, *e; + int s, v; + int rank, lastrank, newrank = -1; + + v = b - SA - 1; + lastrank = -1; + for(c = first, d = a - 1; c <= d; ++c) { + if((0 <= (s = *c - depth)) && (ISA[s] == v)) { + *++d = s; + rank = ISA[s + depth]; + if(lastrank != rank) { lastrank = rank; newrank = d - SA; } + ISA[s] = newrank; + } + } + + lastrank = -1; + for(e = d; first <= e; --e) { + rank = ISA[*e]; + if(lastrank != rank) { lastrank = rank; newrank = e - SA; } + if(newrank != rank) { ISA[*e] = newrank; } + } + + lastrank = -1; + for(c = last - 1, e = d + 1, d = b; e < d; --c) { + if((0 <= (s = *c - depth)) && (ISA[s] == v)) { + *--d = s; + rank = ISA[s + depth]; + if(lastrank != rank) { lastrank = rank; newrank = d - SA; } + ISA[s] = newrank; + } + } +} + +static +void +tr_introsort(int *ISA, const int *ISAd, + int *SA, int *first, int *last, + trbudget_t *budget) { +#define STACK_SIZE TR_STACKSIZE + struct { const int *a; int *b, *c; int d, e; }stack[STACK_SIZE]; + int *a, *b, *c; + int t; + int v, x = 0; + int incr = ISAd - ISA; + int limit, next; + int ssize, trlink = -1; + + for(ssize = 0, limit = tr_ilg(last - first);;) { + + if(limit < 0) { + if(limit == -1) { + /* tandem repeat partition */ + tr_partition(ISAd - incr, first, first, last, &a, &b, last - SA - 1); + + /* update ranks */ + if(a < last) { + for(c = first, v = a - SA - 1; c < a; ++c) { ISA[*c] = v; } + } + if(b < last) { + for(c = a, v = b - SA - 1; c < b; ++c) { ISA[*c] = v; } + } + + /* push */ + if(1 < (b - a)) { + STACK_PUSH5(NULL, a, b, 0, 0); + STACK_PUSH5(ISAd - incr, first, last, -2, trlink); + trlink = ssize - 2; + } + if((a - first) <= (last - b)) { + if(1 < (a - first)) { + STACK_PUSH5(ISAd, b, last, tr_ilg(last - b), trlink); + last = a, limit = tr_ilg(a - first); + } else if(1 < (last - b)) { + first = b, limit = tr_ilg(last - b); + } else { + STACK_POP5(ISAd, first, last, limit, trlink); + } + } else { + if(1 < (last - b)) { + STACK_PUSH5(ISAd, first, a, tr_ilg(a - first), trlink); + first = b, limit = tr_ilg(last - b); + } else if(1 < (a - first)) { + last = a, limit = tr_ilg(a - first); + } else { + STACK_POP5(ISAd, first, last, limit, trlink); + } + } + } else if(limit == -2) { + /* tandem repeat copy */ + a = stack[--ssize].b, b = stack[ssize].c; + if(stack[ssize].d == 0) { + tr_copy(ISA, SA, first, a, b, last, ISAd - ISA); + } else { + if(0 <= trlink) { stack[trlink].d = -1; } + tr_partialcopy(ISA, SA, first, a, b, last, ISAd - ISA); + } + STACK_POP5(ISAd, first, last, limit, trlink); + } else { + /* sorted partition */ + if(0 <= *first) { + a = first; + do { ISA[*a] = a - SA; } while((++a < last) && (0 <= *a)); + first = a; + } + if(first < last) { + a = first; do { *a = ~*a; } while(*++a < 0); + next = (ISA[*a] != ISAd[*a]) ? tr_ilg(a - first + 1) : -1; + if(++a < last) { for(b = first, v = a - SA - 1; b < a; ++b) { ISA[*b] = v; } } + + /* push */ + if(trbudget_check(budget, a - first)) { + if((a - first) <= (last - a)) { + STACK_PUSH5(ISAd, a, last, -3, trlink); + ISAd += incr, last = a, limit = next; + } else { + if(1 < (last - a)) { + STACK_PUSH5(ISAd + incr, first, a, next, trlink); + first = a, limit = -3; + } else { + ISAd += incr, last = a, limit = next; + } + } + } else { + if(0 <= trlink) { stack[trlink].d = -1; } + if(1 < (last - a)) { + first = a, limit = -3; + } else { + STACK_POP5(ISAd, first, last, limit, trlink); + } + } + } else { + STACK_POP5(ISAd, first, last, limit, trlink); + } + } + continue; + } + + if((last - first) <= TR_INSERTIONSORT_THRESHOLD) { + tr_insertionsort(ISAd, first, last); + limit = -3; + continue; + } + + if(limit-- == 0) { + tr_heapsort(ISAd, first, last - first); + for(a = last - 1; first < a; a = b) { + for(x = ISAd[*a], b = a - 1; (first <= b) && (ISAd[*b] == x); --b) { *b = ~*b; } + } + limit = -3; + continue; + } + + /* choose pivot */ + a = tr_pivot(ISAd, first, last); + SWAP(*first, *a); + v = ISAd[*first]; + + /* partition */ + tr_partition(ISAd, first, first + 1, last, &a, &b, v); + if((last - first) != (b - a)) { + next = (ISA[*a] != v) ? tr_ilg(b - a) : -1; + + /* update ranks */ + for(c = first, v = a - SA - 1; c < a; ++c) { ISA[*c] = v; } + if(b < last) { for(c = a, v = b - SA - 1; c < b; ++c) { ISA[*c] = v; } } + + /* push */ + if((1 < (b - a)) && (trbudget_check(budget, b - a))) { + if((a - first) <= (last - b)) { + if((last - b) <= (b - a)) { + if(1 < (a - first)) { + STACK_PUSH5(ISAd + incr, a, b, next, trlink); + STACK_PUSH5(ISAd, b, last, limit, trlink); + last = a; + } else if(1 < (last - b)) { + STACK_PUSH5(ISAd + incr, a, b, next, trlink); + first = b; + } else { + ISAd += incr, first = a, last = b, limit = next; + } + } else if((a - first) <= (b - a)) { + if(1 < (a - first)) { + STACK_PUSH5(ISAd, b, last, limit, trlink); + STACK_PUSH5(ISAd + incr, a, b, next, trlink); + last = a; + } else { + STACK_PUSH5(ISAd, b, last, limit, trlink); + ISAd += incr, first = a, last = b, limit = next; + } + } else { + STACK_PUSH5(ISAd, b, last, limit, trlink); + STACK_PUSH5(ISAd, first, a, limit, trlink); + ISAd += incr, first = a, last = b, limit = next; + } + } else { + if((a - first) <= (b - a)) { + if(1 < (last - b)) { + STACK_PUSH5(ISAd + incr, a, b, next, trlink); + STACK_PUSH5(ISAd, first, a, limit, trlink); + first = b; + } else if(1 < (a - first)) { + STACK_PUSH5(ISAd + incr, a, b, next, trlink); + last = a; + } else { + ISAd += incr, first = a, last = b, limit = next; + } + } else if((last - b) <= (b - a)) { + if(1 < (last - b)) { + STACK_PUSH5(ISAd, first, a, limit, trlink); + STACK_PUSH5(ISAd + incr, a, b, next, trlink); + first = b; + } else { + STACK_PUSH5(ISAd, first, a, limit, trlink); + ISAd += incr, first = a, last = b, limit = next; + } + } else { + STACK_PUSH5(ISAd, first, a, limit, trlink); + STACK_PUSH5(ISAd, b, last, limit, trlink); + ISAd += incr, first = a, last = b, limit = next; + } + } + } else { + if((1 < (b - a)) && (0 <= trlink)) { stack[trlink].d = -1; } + if((a - first) <= (last - b)) { + if(1 < (a - first)) { + STACK_PUSH5(ISAd, b, last, limit, trlink); + last = a; + } else if(1 < (last - b)) { + first = b; + } else { + STACK_POP5(ISAd, first, last, limit, trlink); + } + } else { + if(1 < (last - b)) { + STACK_PUSH5(ISAd, first, a, limit, trlink); + first = b; + } else if(1 < (a - first)) { + last = a; + } else { + STACK_POP5(ISAd, first, last, limit, trlink); + } + } + } + } else { + if(trbudget_check(budget, last - first)) { + limit = tr_ilg(last - first), ISAd += incr; + } else { + if(0 <= trlink) { stack[trlink].d = -1; } + STACK_POP5(ISAd, first, last, limit, trlink); + } + } + } +#undef STACK_SIZE +} + + + +/*---------------------------------------------------------------------------*/ + +/* Tandem repeat sort */ +static +void +trsort(int *ISA, int *SA, int n, int depth) { + int *ISAd; + int *first, *last; + trbudget_t budget; + int t, skip, unsorted; + + trbudget_init(&budget, tr_ilg(n) * 2 / 3, n); +/* trbudget_init(&budget, tr_ilg(n) * 3 / 4, n); */ + for(ISAd = ISA + depth; -n < *SA; ISAd += ISAd - ISA) { + first = SA; + skip = 0; + unsorted = 0; + do { + if((t = *first) < 0) { first -= t; skip += t; } + else { + if(skip != 0) { *(first + skip) = skip; skip = 0; } + last = SA + ISA[t] + 1; + if(1 < (last - first)) { + budget.count = 0; + tr_introsort(ISA, ISAd, SA, first, last, &budget); + if(budget.count != 0) { unsorted += budget.count; } + else { skip = first - last; } + } else if((last - first) == 1) { + skip = -1; + } + first = last; + } + } while(first < (SA + n)); + if(skip != 0) { *(first + skip) = skip; } + if(unsorted == 0) { break; } + } +} + + +/*---------------------------------------------------------------------------*/ + +/* Sorts suffixes of type B*. */ +static +int +sort_typeBstar(const unsigned char *T, int *SA, + int *bucket_A, int *bucket_B, + int n, int openMP) { + int *PAb, *ISAb, *buf; +#ifdef LIBBSC_OPENMP + int *curbuf; + int l; +#endif + int i, j, k, t, m, bufsize; + int c0, c1; +#ifdef LIBBSC_OPENMP + int d0, d1; +#endif + (void)openMP; + + /* Initialize bucket arrays. */ + for(i = 0; i < BUCKET_A_SIZE; ++i) { bucket_A[i] = 0; } + for(i = 0; i < BUCKET_B_SIZE; ++i) { bucket_B[i] = 0; } + + /* Count the number of occurrences of the first one or two characters of each + type A, B and B* suffix. Moreover, store the beginning position of all + type B* suffixes into the array SA. */ + for(i = n - 1, m = n, c0 = T[n - 1]; 0 <= i;) { + /* type A suffix. */ + do { ++BUCKET_A(c1 = c0); } while((0 <= --i) && ((c0 = T[i]) >= c1)); + if(0 <= i) { + /* type B* suffix. */ + ++BUCKET_BSTAR(c0, c1); + SA[--m] = i; + /* type B suffix. */ + for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) <= c1); --i, c1 = c0) { + ++BUCKET_B(c0, c1); + } + } + } + m = n - m; +/* +note: + A type B* suffix is lexicographically smaller than a type B suffix that + begins with the same first two characters. +*/ + + /* Calculate the index of start/end point of each bucket. */ + for(c0 = 0, i = 0, j = 0; c0 < ALPHABET_SIZE; ++c0) { + t = i + BUCKET_A(c0); + BUCKET_A(c0) = i + j; /* start point */ + i = t + BUCKET_B(c0, c0); + for(c1 = c0 + 1; c1 < ALPHABET_SIZE; ++c1) { + j += BUCKET_BSTAR(c0, c1); + BUCKET_BSTAR(c0, c1) = j; /* end point */ + i += BUCKET_B(c0, c1); + } + } + + if(0 < m) { + /* Sort the type B* suffixes by their first two characters. */ + PAb = SA + n - m; ISAb = SA + m; + for(i = m - 2; 0 <= i; --i) { + t = PAb[i], c0 = T[t], c1 = T[t + 1]; + SA[--BUCKET_BSTAR(c0, c1)] = i; + } + t = PAb[m - 1], c0 = T[t], c1 = T[t + 1]; + SA[--BUCKET_BSTAR(c0, c1)] = m - 1; + + /* Sort the type B* substrings using sssort. */ +#ifdef LIBBSC_OPENMP + if (openMP) + { + buf = SA + m; + c0 = ALPHABET_SIZE - 2, c1 = ALPHABET_SIZE - 1, j = m; +#pragma omp parallel default(shared) private(bufsize, curbuf, k, l, d0, d1) + { + bufsize = (n - (2 * m)) / omp_get_num_threads(); + curbuf = buf + omp_get_thread_num() * bufsize; + k = 0; + for(;;) { + #pragma omp critical(sssort_lock) + { + if(0 < (l = j)) { + d0 = c0, d1 = c1; + do { + k = BUCKET_BSTAR(d0, d1); + if(--d1 <= d0) { + d1 = ALPHABET_SIZE - 1; + if(--d0 < 0) { break; } + } + } while(((l - k) <= 1) && (0 < (l = k))); + c0 = d0, c1 = d1, j = k; + } + } + if(l == 0) { break; } + sssort(T, PAb, SA + k, SA + l, + curbuf, bufsize, 2, n, *(SA + k) == (m - 1)); + } + } + } + else + { + buf = SA + m, bufsize = n - (2 * m); + for(c0 = ALPHABET_SIZE - 2, j = m; 0 < j; --c0) { + for(c1 = ALPHABET_SIZE - 1; c0 < c1; j = i, --c1) { + i = BUCKET_BSTAR(c0, c1); + if(1 < (j - i)) { + sssort(T, PAb, SA + i, SA + j, + buf, bufsize, 2, n, *(SA + i) == (m - 1)); + } + } + } + } +#else + buf = SA + m, bufsize = n - (2 * m); + for(c0 = ALPHABET_SIZE - 2, j = m; 0 < j; --c0) { + for(c1 = ALPHABET_SIZE - 1; c0 < c1; j = i, --c1) { + i = BUCKET_BSTAR(c0, c1); + if(1 < (j - i)) { + sssort(T, PAb, SA + i, SA + j, + buf, bufsize, 2, n, *(SA + i) == (m - 1)); + } + } + } +#endif + + /* Compute ranks of type B* substrings. */ + for(i = m - 1; 0 <= i; --i) { + if(0 <= SA[i]) { + j = i; + do { ISAb[SA[i]] = i; } while((0 <= --i) && (0 <= SA[i])); + SA[i + 1] = i - j; + if(i <= 0) { break; } + } + j = i; + do { ISAb[SA[i] = ~SA[i]] = j; } while(SA[--i] < 0); + ISAb[SA[i]] = j; + } + + /* Construct the inverse suffix array of type B* suffixes using trsort. */ + trsort(ISAb, SA, m, 1); + + /* Set the sorted order of type B* suffixes. */ + for(i = n - 1, j = m, c0 = T[n - 1]; 0 <= i;) { + for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) >= c1); --i, c1 = c0) { } + if(0 <= i) { + t = i; + for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) <= c1); --i, c1 = c0) { } + SA[ISAb[--j]] = ((t == 0) || (1 < (t - i))) ? t : ~t; + } + } + + /* Calculate the index of start/end point of each bucket. */ + BUCKET_B(ALPHABET_SIZE - 1, ALPHABET_SIZE - 1) = n; /* end point */ + for(c0 = ALPHABET_SIZE - 2, k = m - 1; 0 <= c0; --c0) { + i = BUCKET_A(c0 + 1) - 1; + for(c1 = ALPHABET_SIZE - 1; c0 < c1; --c1) { + t = i - BUCKET_B(c0, c1); + BUCKET_B(c0, c1) = i; /* end point */ + + /* Move all type B* suffixes to the correct position. */ + for(i = t, j = BUCKET_BSTAR(c0, c1); + j <= k; + --i, --k) { SA[i] = SA[k]; } + } + BUCKET_BSTAR(c0, c0 + 1) = i - BUCKET_B(c0, c0) + 1; /* start point */ + BUCKET_B(c0, c0) = i; /* end point */ + } + } + + return m; +} + +/* Constructs the suffix array by using the sorted order of type B* suffixes. */ +static +void +construct_SA(const unsigned char *T, int *SA, + int *bucket_A, int *bucket_B, + int n, int m) { + int *i, *j, *k; + int s; + int c0, c1, c2; + + if(0 < m) { + /* Construct the sorted order of type B suffixes by using + the sorted order of type B* suffixes. */ + for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) { + /* Scan the suffix array from right to left. */ + for(i = SA + BUCKET_BSTAR(c1, c1 + 1), + j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1; + i <= j; + --j) { + if(0 < (s = *j)) { + assert(T[s] == c1); + assert(((s + 1) < n) && (T[s] <= T[s + 1])); + assert(T[s - 1] <= T[s]); + *j = ~s; + c0 = T[--s]; + if((0 < s) && (T[s - 1] > c0)) { s = ~s; } + if(c0 != c2) { + if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; } + k = SA + BUCKET_B(c2 = c0, c1); + } + assert(k < j); assert(k != NULL); + *k-- = s; + } else { + assert(((s == 0) && (T[s] == c1)) || (s < 0)); + *j = ~s; + } + } + } + } + + /* Construct the suffix array by using + the sorted order of type B suffixes. */ + k = SA + BUCKET_A(c2 = T[n - 1]); + *k++ = (T[n - 2] < c2) ? ~(n - 1) : (n - 1); + /* Scan the suffix array from left to right. */ + for(i = SA, j = SA + n; i < j; ++i) { + if(0 < (s = *i)) { + assert(T[s - 1] >= T[s]); + c0 = T[--s]; + if((s == 0) || (T[s - 1] < c0)) { s = ~s; } + if(c0 != c2) { + BUCKET_A(c2) = k - SA; + k = SA + BUCKET_A(c2 = c0); + } + assert(i < k); + *k++ = s; + } else { + assert(s < 0); + *i = ~s; + } + } +} + +/* Constructs the burrows-wheeler transformed string directly + by using the sorted order of type B* suffixes. */ +static +int +construct_BWT(const unsigned char *T, int *SA, + int *bucket_A, int *bucket_B, + int n, int m) { + int *i, *j, *k, *orig; + int s; + int c0, c1, c2; + + if(0 < m) { + /* Construct the sorted order of type B suffixes by using + the sorted order of type B* suffixes. */ + for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) { + /* Scan the suffix array from right to left. */ + for(i = SA + BUCKET_BSTAR(c1, c1 + 1), + j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1; + i <= j; + --j) { + if(0 < (s = *j)) { + assert(T[s] == c1); + assert(((s + 1) < n) && (T[s] <= T[s + 1])); + assert(T[s - 1] <= T[s]); + c0 = T[--s]; + *j = ~((int)c0); + if((0 < s) && (T[s - 1] > c0)) { s = ~s; } + if(c0 != c2) { + if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; } + k = SA + BUCKET_B(c2 = c0, c1); + } + assert(k < j); assert(k != NULL); + *k-- = s; + } else if(s != 0) { + *j = ~s; +#ifndef NDEBUG + } else { + assert(T[s] == c1); +#endif + } + } + } + } + + /* Construct the BWTed string by using + the sorted order of type B suffixes. */ + k = SA + BUCKET_A(c2 = T[n - 1]); + *k++ = (T[n - 2] < c2) ? ~((int)T[n - 2]) : (n - 1); + /* Scan the suffix array from left to right. */ + for(i = SA, j = SA + n, orig = SA; i < j; ++i) { + if(0 < (s = *i)) { + assert(T[s - 1] >= T[s]); + c0 = T[--s]; + *i = c0; + if((0 < s) && (T[s - 1] < c0)) { s = ~((int)T[s - 1]); } + if(c0 != c2) { + BUCKET_A(c2) = k - SA; + k = SA + BUCKET_A(c2 = c0); + } + assert(i < k); + *k++ = s; + } else if(s != 0) { + *i = ~s; + } else { + orig = i; + } + } + + return orig - SA; +} + +/* Constructs the burrows-wheeler transformed string directly + by using the sorted order of type B* suffixes. */ +static +int +construct_BWT_indexes(const unsigned char *T, int *SA, + int *bucket_A, int *bucket_B, + int n, int m, + unsigned char * num_indexes, int * indexes) { + int *i, *j, *k, *orig; + int s; + int c0, c1, c2; + + int mod = n / 8; + { + mod |= mod >> 1; mod |= mod >> 2; + mod |= mod >> 4; mod |= mod >> 8; + mod |= mod >> 16; mod >>= 1; + + *num_indexes = (unsigned char)((n - 1) / (mod + 1)); + } + + if(0 < m) { + /* Construct the sorted order of type B suffixes by using + the sorted order of type B* suffixes. */ + for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) { + /* Scan the suffix array from right to left. */ + for(i = SA + BUCKET_BSTAR(c1, c1 + 1), + j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1; + i <= j; + --j) { + if(0 < (s = *j)) { + assert(T[s] == c1); + assert(((s + 1) < n) && (T[s] <= T[s + 1])); + assert(T[s - 1] <= T[s]); + + if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = j - SA; + + c0 = T[--s]; + *j = ~((int)c0); + if((0 < s) && (T[s - 1] > c0)) { s = ~s; } + if(c0 != c2) { + if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; } + k = SA + BUCKET_B(c2 = c0, c1); + } + assert(k < j); assert(k != NULL); + *k-- = s; + } else if(s != 0) { + *j = ~s; +#ifndef NDEBUG + } else { + assert(T[s] == c1); +#endif + } + } + } + } + + /* Construct the BWTed string by using + the sorted order of type B suffixes. */ + k = SA + BUCKET_A(c2 = T[n - 1]); + if (T[n - 2] < c2) { + if (((n - 1) & mod) == 0) indexes[(n - 1) / (mod + 1) - 1] = k - SA; + *k++ = ~((int)T[n - 2]); + } + else { + *k++ = n - 1; + } + + /* Scan the suffix array from left to right. */ + for(i = SA, j = SA + n, orig = SA; i < j; ++i) { + if(0 < (s = *i)) { + assert(T[s - 1] >= T[s]); + + if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = i - SA; + + c0 = T[--s]; + *i = c0; + if(c0 != c2) { + BUCKET_A(c2) = k - SA; + k = SA + BUCKET_A(c2 = c0); + } + assert(i < k); + if((0 < s) && (T[s - 1] < c0)) { + if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = k - SA; + *k++ = ~((int)T[s - 1]); + } else + *k++ = s; + } else if(s != 0) { + *i = ~s; + } else { + orig = i; + } + } + + return orig - SA; +} + + +/*---------------------------------------------------------------------------*/ + +/*- Function -*/ + +int +divsufsort(const unsigned char *T, int *SA, int n, int openMP) { + int *bucket_A, *bucket_B; + int m; + int err = 0; + + /* Check arguments. */ + if((T == NULL) || (SA == NULL) || (n < 0)) { return -1; } + else if(n == 0) { return 0; } + else if(n == 1) { SA[0] = 0; return 0; } + else if(n == 2) { m = (T[0] < T[1]); SA[m ^ 1] = 0, SA[m] = 1; return 0; } + + bucket_A = (int *)malloc(BUCKET_A_SIZE * sizeof(int)); + bucket_B = (int *)malloc(BUCKET_B_SIZE * sizeof(int)); + + /* Suffixsort. */ + if((bucket_A != NULL) && (bucket_B != NULL)) { + m = sort_typeBstar(T, SA, bucket_A, bucket_B, n, openMP); + construct_SA(T, SA, bucket_A, bucket_B, n, m); + } else { + err = -2; + } + + free(bucket_B); + free(bucket_A); + + return err; +} + +int +divbwt(const unsigned char *T, unsigned char *U, int *A, int n, unsigned char * num_indexes, int * indexes, int openMP) { + int *B; + int *bucket_A, *bucket_B; + int m, pidx, i; + + /* Check arguments. */ + if((T == NULL) || (U == NULL) || (n < 0)) { return -1; } + else if(n <= 1) { if(n == 1) { U[0] = T[0]; } return n; } + + if((B = A) == NULL) { B = (int *)malloc((size_t)(n + 1) * sizeof(int)); } + bucket_A = (int *)malloc(BUCKET_A_SIZE * sizeof(int)); + bucket_B = (int *)malloc(BUCKET_B_SIZE * sizeof(int)); + + /* Burrows-Wheeler Transform. */ + if((B != NULL) && (bucket_A != NULL) && (bucket_B != NULL)) { + m = sort_typeBstar(T, B, bucket_A, bucket_B, n, openMP); + + if (num_indexes == NULL || indexes == NULL) { + pidx = construct_BWT(T, B, bucket_A, bucket_B, n, m); + } else { + pidx = construct_BWT_indexes(T, B, bucket_A, bucket_B, n, m, num_indexes, indexes); + } + + /* Copy to output string. */ + U[0] = T[n - 1]; + for(i = 0; i < pidx; ++i) { U[i + 1] = (unsigned char)B[i]; } + for(i += 1; i < n; ++i) { U[i] = (unsigned char)B[i]; } + pidx += 1; + } else { + pidx = -2; + } + + free(bucket_B); + free(bucket_A); + if(A == NULL) { free(B); } + + return pidx; +} diff --git a/cpp/third_party/zstd-1.5.7/lib/dictBuilder/divsufsort.h b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/divsufsort.h new file mode 100644 index 000000000..3ed2b287a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/divsufsort.h @@ -0,0 +1,57 @@ +/* + * divsufsort.h for libdivsufsort-lite + * Copyright (c) 2003-2008 Yuta Mori All Rights Reserved. + * + * 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 _DIVSUFSORT_H +#define _DIVSUFSORT_H 1 + +/*- Prototypes -*/ + +/** + * Constructs the suffix array of a given string. + * @param T [0..n-1] The input string. + * @param SA [0..n-1] The output array of suffixes. + * @param n The length of the given string. + * @param openMP enables OpenMP optimization. + * @return 0 if no error occurred, -1 or -2 otherwise. + */ +int +divsufsort(const unsigned char *T, int *SA, int n, int openMP); + +/** + * Constructs the burrows-wheeler transformed string of a given string. + * @param T [0..n-1] The input string. + * @param U [0..n-1] The output string. (can be T) + * @param A [0..n-1] The temporary array. (can be NULL) + * @param n The length of the given string. + * @param num_indexes The length of secondary indexes array. (can be NULL) + * @param indexes The secondary indexes array. (can be NULL) + * @param openMP enables OpenMP optimization. + * @return The primary index if no error occurred, -1 or -2 otherwise. + */ +int +divbwt(const unsigned char *T, unsigned char *U, int *A, int n, unsigned char * num_indexes, int * indexes, int openMP); + +#endif /* _DIVSUFSORT_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/dictBuilder/fastcover.c b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/fastcover.c new file mode 100644 index 000000000..a958eb337 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/fastcover.c @@ -0,0 +1,766 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/*-************************************* +* Dependencies +***************************************/ +#include /* fprintf */ +#include /* malloc, free, qsort */ +#include /* memset */ +#include /* clock */ + +#ifndef ZDICT_STATIC_LINKING_ONLY +# define ZDICT_STATIC_LINKING_ONLY +#endif + +#include "../common/mem.h" /* read */ +#include "../common/pool.h" +#include "../common/threading.h" +#include "../common/zstd_internal.h" /* includes zstd.h */ +#include "../compress/zstd_compress_internal.h" /* ZSTD_hash*() */ +#include "../zdict.h" +#include "cover.h" + + +/*-************************************* +* Constants +***************************************/ +/** +* There are 32bit indexes used to ref samples, so limit samples size to 4GB +* on 64bit builds. +* For 32bit builds we choose 1 GB. +* Most 32bit platforms have 2GB user-mode addressable space and we allocate a large +* contiguous buffer, so 1GB is already a high limit. +*/ +#define FASTCOVER_MAX_SAMPLES_SIZE (sizeof(size_t) == 8 ? ((unsigned)-1) : ((unsigned)1 GB)) +#define FASTCOVER_MAX_F 31 +#define FASTCOVER_MAX_ACCEL 10 +#define FASTCOVER_DEFAULT_SPLITPOINT 0.75 +#define DEFAULT_F 20 +#define DEFAULT_ACCEL 1 + + +/*-************************************* +* Console display +***************************************/ +#ifndef LOCALDISPLAYLEVEL +static int g_displayLevel = 0; +#endif +#undef DISPLAY +#define DISPLAY(...) \ + { \ + fprintf(stderr, __VA_ARGS__); \ + fflush(stderr); \ + } +#undef LOCALDISPLAYLEVEL +#define LOCALDISPLAYLEVEL(displayLevel, l, ...) \ + if (displayLevel >= l) { \ + DISPLAY(__VA_ARGS__); \ + } /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */ +#undef DISPLAYLEVEL +#define DISPLAYLEVEL(l, ...) LOCALDISPLAYLEVEL(g_displayLevel, l, __VA_ARGS__) + +#ifndef LOCALDISPLAYUPDATE +static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100; +static clock_t g_time = 0; +#endif +#undef LOCALDISPLAYUPDATE +#define LOCALDISPLAYUPDATE(displayLevel, l, ...) \ + if (displayLevel >= l) { \ + if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \ + g_time = clock(); \ + DISPLAY(__VA_ARGS__); \ + } \ + } +#undef DISPLAYUPDATE +#define DISPLAYUPDATE(l, ...) LOCALDISPLAYUPDATE(g_displayLevel, l, __VA_ARGS__) + + +/*-************************************* +* Hash Functions +***************************************/ +/** + * Hash the d-byte value pointed to by p and mod 2^f into the frequency vector + */ +static size_t FASTCOVER_hashPtrToIndex(const void* p, U32 f, unsigned d) { + if (d == 6) { + return ZSTD_hash6Ptr(p, f); + } + return ZSTD_hash8Ptr(p, f); +} + + +/*-************************************* +* Acceleration +***************************************/ +typedef struct { + unsigned finalize; /* Percentage of training samples used for ZDICT_finalizeDictionary */ + unsigned skip; /* Number of dmer skipped between each dmer counted in computeFrequency */ +} FASTCOVER_accel_t; + + +static const FASTCOVER_accel_t FASTCOVER_defaultAccelParameters[FASTCOVER_MAX_ACCEL+1] = { + { 100, 0 }, /* accel = 0, should not happen because accel = 0 defaults to accel = 1 */ + { 100, 0 }, /* accel = 1 */ + { 50, 1 }, /* accel = 2 */ + { 34, 2 }, /* accel = 3 */ + { 25, 3 }, /* accel = 4 */ + { 20, 4 }, /* accel = 5 */ + { 17, 5 }, /* accel = 6 */ + { 14, 6 }, /* accel = 7 */ + { 13, 7 }, /* accel = 8 */ + { 11, 8 }, /* accel = 9 */ + { 10, 9 }, /* accel = 10 */ +}; + + +/*-************************************* +* Context +***************************************/ +typedef struct { + const BYTE *samples; + size_t *offsets; + const size_t *samplesSizes; + size_t nbSamples; + size_t nbTrainSamples; + size_t nbTestSamples; + size_t nbDmers; + U32 *freqs; + unsigned d; + unsigned f; + FASTCOVER_accel_t accelParams; +} FASTCOVER_ctx_t; + + +/*-************************************* +* Helper functions +***************************************/ +/** + * Selects the best segment in an epoch. + * Segments of are scored according to the function: + * + * Let F(d) be the frequency of all dmers with hash value d. + * Let S_i be hash value of the dmer at position i of segment S which has length k. + * + * Score(S) = F(S_1) + F(S_2) + ... + F(S_{k-d+1}) + * + * Once the dmer with hash value d is in the dictionary we set F(d) = 0. + */ +static COVER_segment_t FASTCOVER_selectSegment(const FASTCOVER_ctx_t *ctx, + U32 *freqs, U32 begin, U32 end, + ZDICT_cover_params_t parameters, + U16* segmentFreqs) { + /* Constants */ + const U32 k = parameters.k; + const U32 d = parameters.d; + const U32 f = ctx->f; + const U32 dmersInK = k - d + 1; + + /* Try each segment (activeSegment) and save the best (bestSegment) */ + COVER_segment_t bestSegment = {0, 0, 0}; + COVER_segment_t activeSegment; + + /* Reset the activeDmers in the segment */ + /* The activeSegment starts at the beginning of the epoch. */ + activeSegment.begin = begin; + activeSegment.end = begin; + activeSegment.score = 0; + + /* Slide the activeSegment through the whole epoch. + * Save the best segment in bestSegment. + */ + while (activeSegment.end < end) { + /* Get hash value of current dmer */ + const size_t idx = FASTCOVER_hashPtrToIndex(ctx->samples + activeSegment.end, f, d); + + /* Add frequency of this index to score if this is the first occurrence of index in active segment */ + if (segmentFreqs[idx] == 0) { + activeSegment.score += freqs[idx]; + } + /* Increment end of segment and segmentFreqs*/ + activeSegment.end += 1; + segmentFreqs[idx] += 1; + /* If the window is now too large, drop the first position */ + if (activeSegment.end - activeSegment.begin == dmersInK + 1) { + /* Get hash value of the dmer to be eliminated from active segment */ + const size_t delIndex = FASTCOVER_hashPtrToIndex(ctx->samples + activeSegment.begin, f, d); + segmentFreqs[delIndex] -= 1; + /* Subtract frequency of this index from score if this is the last occurrence of this index in active segment */ + if (segmentFreqs[delIndex] == 0) { + activeSegment.score -= freqs[delIndex]; + } + /* Increment start of segment */ + activeSegment.begin += 1; + } + + /* If this segment is the best so far save it */ + if (activeSegment.score > bestSegment.score) { + bestSegment = activeSegment; + } + } + + /* Zero out rest of segmentFreqs array */ + while (activeSegment.begin < end) { + const size_t delIndex = FASTCOVER_hashPtrToIndex(ctx->samples + activeSegment.begin, f, d); + segmentFreqs[delIndex] -= 1; + activeSegment.begin += 1; + } + + { + /* Zero the frequency of hash value of each dmer covered by the chosen segment. */ + U32 pos; + for (pos = bestSegment.begin; pos != bestSegment.end; ++pos) { + const size_t i = FASTCOVER_hashPtrToIndex(ctx->samples + pos, f, d); + freqs[i] = 0; + } + } + + return bestSegment; +} + + +static int FASTCOVER_checkParameters(ZDICT_cover_params_t parameters, + size_t maxDictSize, unsigned f, + unsigned accel) { + /* k, d, and f are required parameters */ + if (parameters.d == 0 || parameters.k == 0) { + return 0; + } + /* d has to be 6 or 8 */ + if (parameters.d != 6 && parameters.d != 8) { + return 0; + } + /* k <= maxDictSize */ + if (parameters.k > maxDictSize) { + return 0; + } + /* d <= k */ + if (parameters.d > parameters.k) { + return 0; + } + /* 0 < f <= FASTCOVER_MAX_F*/ + if (f > FASTCOVER_MAX_F || f == 0) { + return 0; + } + /* 0 < splitPoint <= 1 */ + if (parameters.splitPoint <= 0 || parameters.splitPoint > 1) { + return 0; + } + /* 0 < accel <= 10 */ + if (accel > 10 || accel == 0) { + return 0; + } + return 1; +} + + +/** + * Clean up a context initialized with `FASTCOVER_ctx_init()`. + */ +static void +FASTCOVER_ctx_destroy(FASTCOVER_ctx_t* ctx) +{ + if (!ctx) return; + + free(ctx->freqs); + ctx->freqs = NULL; + + free(ctx->offsets); + ctx->offsets = NULL; +} + + +/** + * Calculate for frequency of hash value of each dmer in ctx->samples + */ +static void +FASTCOVER_computeFrequency(U32* freqs, const FASTCOVER_ctx_t* ctx) +{ + const unsigned f = ctx->f; + const unsigned d = ctx->d; + const unsigned skip = ctx->accelParams.skip; + const unsigned readLength = MAX(d, 8); + size_t i; + assert(ctx->nbTrainSamples >= 5); + assert(ctx->nbTrainSamples <= ctx->nbSamples); + for (i = 0; i < ctx->nbTrainSamples; i++) { + size_t start = ctx->offsets[i]; /* start of current dmer */ + size_t const currSampleEnd = ctx->offsets[i+1]; + while (start + readLength <= currSampleEnd) { + const size_t dmerIndex = FASTCOVER_hashPtrToIndex(ctx->samples + start, f, d); + freqs[dmerIndex]++; + start = start + skip + 1; + } + } +} + + +/** + * Prepare a context for dictionary building. + * The context is only dependent on the parameter `d` and can be used multiple + * times. + * Returns 0 on success or error code on error. + * The context must be destroyed with `FASTCOVER_ctx_destroy()`. + */ +static size_t +FASTCOVER_ctx_init(FASTCOVER_ctx_t* ctx, + const void* samplesBuffer, + const size_t* samplesSizes, unsigned nbSamples, + unsigned d, double splitPoint, unsigned f, + FASTCOVER_accel_t accelParams) +{ + const BYTE* const samples = (const BYTE*)samplesBuffer; + const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples); + /* Split samples into testing and training sets */ + const unsigned nbTrainSamples = splitPoint < 1.0 ? (unsigned)((double)nbSamples * splitPoint) : nbSamples; + const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples; + const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize; + const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize; + + /* Checks */ + if (totalSamplesSize < MAX(d, sizeof(U64)) || + totalSamplesSize >= (size_t)FASTCOVER_MAX_SAMPLES_SIZE) { + DISPLAYLEVEL(1, "Total samples size is too large (%u MB), maximum size is %u MB\n", + (unsigned)(totalSamplesSize >> 20), (FASTCOVER_MAX_SAMPLES_SIZE >> 20)); + return ERROR(srcSize_wrong); + } + + /* Check if there are at least 5 training samples */ + if (nbTrainSamples < 5) { + DISPLAYLEVEL(1, "Total number of training samples is %u and is invalid\n", nbTrainSamples); + return ERROR(srcSize_wrong); + } + + /* Check if there's testing sample */ + if (nbTestSamples < 1) { + DISPLAYLEVEL(1, "Total number of testing samples is %u and is invalid.\n", nbTestSamples); + return ERROR(srcSize_wrong); + } + + /* Zero the context */ + memset(ctx, 0, sizeof(*ctx)); + DISPLAYLEVEL(2, "Training on %u samples of total size %u\n", nbTrainSamples, + (unsigned)trainingSamplesSize); + DISPLAYLEVEL(2, "Testing on %u samples of total size %u\n", nbTestSamples, + (unsigned)testSamplesSize); + + ctx->samples = samples; + ctx->samplesSizes = samplesSizes; + ctx->nbSamples = nbSamples; + ctx->nbTrainSamples = nbTrainSamples; + ctx->nbTestSamples = nbTestSamples; + ctx->nbDmers = trainingSamplesSize - MAX(d, sizeof(U64)) + 1; + ctx->d = d; + ctx->f = f; + ctx->accelParams = accelParams; + + /* The offsets of each file */ + ctx->offsets = (size_t*)calloc((nbSamples + 1), sizeof(size_t)); + if (ctx->offsets == NULL) { + DISPLAYLEVEL(1, "Failed to allocate scratch buffers \n"); + FASTCOVER_ctx_destroy(ctx); + return ERROR(memory_allocation); + } + + /* Fill offsets from the samplesSizes */ + { U32 i; + ctx->offsets[0] = 0; + assert(nbSamples >= 5); + for (i = 1; i <= nbSamples; ++i) { + ctx->offsets[i] = ctx->offsets[i - 1] + samplesSizes[i - 1]; + } + } + + /* Initialize frequency array of size 2^f */ + ctx->freqs = (U32*)calloc(((U64)1 << f), sizeof(U32)); + if (ctx->freqs == NULL) { + DISPLAYLEVEL(1, "Failed to allocate frequency table \n"); + FASTCOVER_ctx_destroy(ctx); + return ERROR(memory_allocation); + } + + DISPLAYLEVEL(2, "Computing frequencies\n"); + FASTCOVER_computeFrequency(ctx->freqs, ctx); + + return 0; +} + + +/** + * Given the prepared context build the dictionary. + */ +static size_t +FASTCOVER_buildDictionary(const FASTCOVER_ctx_t* ctx, + U32* freqs, + void* dictBuffer, size_t dictBufferCapacity, + ZDICT_cover_params_t parameters, + U16* segmentFreqs) +{ + BYTE *const dict = (BYTE *)dictBuffer; + size_t tail = dictBufferCapacity; + /* Divide the data into epochs. We will select one segment from each epoch. */ + const COVER_epoch_info_t epochs = COVER_computeEpochs( + (U32)dictBufferCapacity, (U32)ctx->nbDmers, parameters.k, 1); + const size_t maxZeroScoreRun = 10; + size_t zeroScoreRun = 0; + size_t epoch; + DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n", + (U32)epochs.num, (U32)epochs.size); + /* Loop through the epochs until there are no more segments or the dictionary + * is full. + */ + for (epoch = 0; tail > 0; epoch = (epoch + 1) % epochs.num) { + const U32 epochBegin = (U32)(epoch * epochs.size); + const U32 epochEnd = epochBegin + epochs.size; + size_t segmentSize; + /* Select a segment */ + COVER_segment_t segment = FASTCOVER_selectSegment( + ctx, freqs, epochBegin, epochEnd, parameters, segmentFreqs); + + /* If the segment covers no dmers, then we are out of content. + * There may be new content in other epochs, for continue for some time. + */ + if (segment.score == 0) { + if (++zeroScoreRun >= maxZeroScoreRun) { + break; + } + continue; + } + zeroScoreRun = 0; + + /* Trim the segment if necessary and if it is too small then we are done */ + segmentSize = MIN(segment.end - segment.begin + parameters.d - 1, tail); + if (segmentSize < parameters.d) { + break; + } + + /* We fill the dictionary from the back to allow the best segments to be + * referenced with the smallest offsets. + */ + tail -= segmentSize; + memcpy(dict + tail, ctx->samples + segment.begin, segmentSize); + DISPLAYUPDATE( + 2, "\r%u%% ", + (unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity)); + } + DISPLAYLEVEL(2, "\r%79s\r", ""); + return tail; +} + +/** + * Parameters for FASTCOVER_tryParameters(). + */ +typedef struct FASTCOVER_tryParameters_data_s { + const FASTCOVER_ctx_t* ctx; + COVER_best_t* best; + size_t dictBufferCapacity; + ZDICT_cover_params_t parameters; +} FASTCOVER_tryParameters_data_t; + + +/** + * Tries a set of parameters and updates the COVER_best_t with the results. + * This function is thread safe if zstd is compiled with multithreaded support. + * It takes its parameters as an *OWNING* opaque pointer to support threading. + */ +static void FASTCOVER_tryParameters(void* opaque) +{ + /* Save parameters as local variables */ + FASTCOVER_tryParameters_data_t *const data = (FASTCOVER_tryParameters_data_t*)opaque; + const FASTCOVER_ctx_t *const ctx = data->ctx; + const ZDICT_cover_params_t parameters = data->parameters; + size_t dictBufferCapacity = data->dictBufferCapacity; + size_t totalCompressedSize = ERROR(GENERIC); + /* Initialize array to keep track of frequency of dmer within activeSegment */ + U16* segmentFreqs = (U16*)calloc(((U64)1 << ctx->f), sizeof(U16)); + /* Allocate space for hash table, dict, and freqs */ + BYTE *const dict = (BYTE*)malloc(dictBufferCapacity); + COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC)); + U32* freqs = (U32*) malloc(((U64)1 << ctx->f) * sizeof(U32)); + if (!segmentFreqs || !dict || !freqs) { + DISPLAYLEVEL(1, "Failed to allocate buffers: out of memory\n"); + goto _cleanup; + } + /* Copy the frequencies because we need to modify them */ + memcpy(freqs, ctx->freqs, ((U64)1 << ctx->f) * sizeof(U32)); + /* Build the dictionary */ + { const size_t tail = FASTCOVER_buildDictionary(ctx, freqs, dict, dictBufferCapacity, + parameters, segmentFreqs); + + const unsigned nbFinalizeSamples = (unsigned)(ctx->nbTrainSamples * ctx->accelParams.finalize / 100); + selection = COVER_selectDict(dict + tail, dictBufferCapacity, dictBufferCapacity - tail, + ctx->samples, ctx->samplesSizes, nbFinalizeSamples, ctx->nbTrainSamples, ctx->nbSamples, parameters, ctx->offsets, + totalCompressedSize); + + if (COVER_dictSelectionIsError(selection)) { + DISPLAYLEVEL(1, "Failed to select dictionary\n"); + goto _cleanup; + } + } +_cleanup: + free(dict); + COVER_best_finish(data->best, parameters, selection); + free(data); + free(segmentFreqs); + COVER_dictSelectionFree(selection); + free(freqs); +} + + +static void +FASTCOVER_convertToCoverParams(ZDICT_fastCover_params_t fastCoverParams, + ZDICT_cover_params_t* coverParams) +{ + coverParams->k = fastCoverParams.k; + coverParams->d = fastCoverParams.d; + coverParams->steps = fastCoverParams.steps; + coverParams->nbThreads = fastCoverParams.nbThreads; + coverParams->splitPoint = fastCoverParams.splitPoint; + coverParams->zParams = fastCoverParams.zParams; + coverParams->shrinkDict = fastCoverParams.shrinkDict; +} + + +static void +FASTCOVER_convertToFastCoverParams(ZDICT_cover_params_t coverParams, + ZDICT_fastCover_params_t* fastCoverParams, + unsigned f, unsigned accel) +{ + fastCoverParams->k = coverParams.k; + fastCoverParams->d = coverParams.d; + fastCoverParams->steps = coverParams.steps; + fastCoverParams->nbThreads = coverParams.nbThreads; + fastCoverParams->splitPoint = coverParams.splitPoint; + fastCoverParams->f = f; + fastCoverParams->accel = accel; + fastCoverParams->zParams = coverParams.zParams; + fastCoverParams->shrinkDict = coverParams.shrinkDict; +} + + +ZDICTLIB_STATIC_API size_t +ZDICT_trainFromBuffer_fastCover(void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, + const size_t* samplesSizes, unsigned nbSamples, + ZDICT_fastCover_params_t parameters) +{ + BYTE* const dict = (BYTE*)dictBuffer; + FASTCOVER_ctx_t ctx; + ZDICT_cover_params_t coverParams; + FASTCOVER_accel_t accelParams; + /* Initialize global data */ + g_displayLevel = (int)parameters.zParams.notificationLevel; + /* Assign splitPoint and f if not provided */ + parameters.splitPoint = 1.0; + parameters.f = parameters.f == 0 ? DEFAULT_F : parameters.f; + parameters.accel = parameters.accel == 0 ? DEFAULT_ACCEL : parameters.accel; + /* Convert to cover parameter */ + memset(&coverParams, 0 , sizeof(coverParams)); + FASTCOVER_convertToCoverParams(parameters, &coverParams); + /* Checks */ + if (!FASTCOVER_checkParameters(coverParams, dictBufferCapacity, parameters.f, + parameters.accel)) { + DISPLAYLEVEL(1, "FASTCOVER parameters incorrect\n"); + return ERROR(parameter_outOfBound); + } + if (nbSamples == 0) { + DISPLAYLEVEL(1, "FASTCOVER must have at least one input file\n"); + return ERROR(srcSize_wrong); + } + if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) { + DISPLAYLEVEL(1, "dictBufferCapacity must be at least %u\n", + ZDICT_DICTSIZE_MIN); + return ERROR(dstSize_tooSmall); + } + /* Assign corresponding FASTCOVER_accel_t to accelParams*/ + accelParams = FASTCOVER_defaultAccelParameters[parameters.accel]; + /* Initialize context */ + { + size_t const initVal = FASTCOVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, + coverParams.d, parameters.splitPoint, parameters.f, + accelParams); + if (ZSTD_isError(initVal)) { + DISPLAYLEVEL(1, "Failed to initialize context\n"); + return initVal; + } + } + COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.nbDmers, g_displayLevel); + /* Build the dictionary */ + DISPLAYLEVEL(2, "Building dictionary\n"); + { + /* Initialize array to keep track of frequency of dmer within activeSegment */ + U16* segmentFreqs = (U16 *)calloc(((U64)1 << parameters.f), sizeof(U16)); + const size_t tail = FASTCOVER_buildDictionary(&ctx, ctx.freqs, dictBuffer, + dictBufferCapacity, coverParams, segmentFreqs); + const unsigned nbFinalizeSamples = (unsigned)(ctx.nbTrainSamples * ctx.accelParams.finalize / 100); + const size_t dictionarySize = ZDICT_finalizeDictionary( + dict, dictBufferCapacity, dict + tail, dictBufferCapacity - tail, + samplesBuffer, samplesSizes, nbFinalizeSamples, coverParams.zParams); + if (!ZSTD_isError(dictionarySize)) { + DISPLAYLEVEL(2, "Constructed dictionary of size %u\n", + (unsigned)dictionarySize); + } + FASTCOVER_ctx_destroy(&ctx); + free(segmentFreqs); + return dictionarySize; + } +} + + +ZDICTLIB_STATIC_API size_t +ZDICT_optimizeTrainFromBuffer_fastCover( + void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, + const size_t* samplesSizes, unsigned nbSamples, + ZDICT_fastCover_params_t* parameters) +{ + ZDICT_cover_params_t coverParams; + FASTCOVER_accel_t accelParams; + /* constants */ + const unsigned nbThreads = parameters->nbThreads; + const double splitPoint = + parameters->splitPoint <= 0.0 ? FASTCOVER_DEFAULT_SPLITPOINT : parameters->splitPoint; + const unsigned kMinD = parameters->d == 0 ? 6 : parameters->d; + const unsigned kMaxD = parameters->d == 0 ? 8 : parameters->d; + const unsigned kMinK = parameters->k == 0 ? 50 : parameters->k; + const unsigned kMaxK = parameters->k == 0 ? 2000 : parameters->k; + const unsigned kSteps = parameters->steps == 0 ? 40 : parameters->steps; + const unsigned kStepSize = MAX((kMaxK - kMinK) / kSteps, 1); + const unsigned kIterations = + (1 + (kMaxD - kMinD) / 2) * (1 + (kMaxK - kMinK) / kStepSize); + const unsigned f = parameters->f == 0 ? DEFAULT_F : parameters->f; + const unsigned accel = parameters->accel == 0 ? DEFAULT_ACCEL : parameters->accel; + const unsigned shrinkDict = 0; + /* Local variables */ + const int displayLevel = (int)parameters->zParams.notificationLevel; + unsigned iteration = 1; + unsigned d; + unsigned k; + COVER_best_t best; + POOL_ctx *pool = NULL; + int warned = 0; + /* Checks */ + if (splitPoint <= 0 || splitPoint > 1) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect splitPoint\n"); + return ERROR(parameter_outOfBound); + } + if (accel == 0 || accel > FASTCOVER_MAX_ACCEL) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect accel\n"); + return ERROR(parameter_outOfBound); + } + if (kMinK < kMaxD || kMaxK < kMinK) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect k\n"); + return ERROR(parameter_outOfBound); + } + if (nbSamples == 0) { + LOCALDISPLAYLEVEL(displayLevel, 1, "FASTCOVER must have at least one input file\n"); + return ERROR(srcSize_wrong); + } + if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) { + LOCALDISPLAYLEVEL(displayLevel, 1, "dictBufferCapacity must be at least %u\n", + ZDICT_DICTSIZE_MIN); + return ERROR(dstSize_tooSmall); + } + if (nbThreads > 1) { + pool = POOL_create(nbThreads, 1); + if (!pool) { + return ERROR(memory_allocation); + } + } + /* Initialization */ + COVER_best_init(&best); + memset(&coverParams, 0 , sizeof(coverParams)); + FASTCOVER_convertToCoverParams(*parameters, &coverParams); + accelParams = FASTCOVER_defaultAccelParameters[accel]; + /* Turn down global display level to clean up display at level 2 and below */ + g_displayLevel = displayLevel == 0 ? 0 : displayLevel - 1; + /* Loop through d first because each new value needs a new context */ + LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n", + kIterations); + for (d = kMinD; d <= kMaxD; d += 2) { + /* Initialize the context for this value of d */ + FASTCOVER_ctx_t ctx; + LOCALDISPLAYLEVEL(displayLevel, 3, "d=%u\n", d); + { + size_t const initVal = FASTCOVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, d, splitPoint, f, accelParams); + if (ZSTD_isError(initVal)) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to initialize context\n"); + COVER_best_destroy(&best); + POOL_free(pool); + return initVal; + } + } + if (!warned) { + COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.nbDmers, displayLevel); + warned = 1; + } + /* Loop through k reusing the same context */ + for (k = kMinK; k <= kMaxK; k += kStepSize) { + /* Prepare the arguments */ + FASTCOVER_tryParameters_data_t *data = (FASTCOVER_tryParameters_data_t *)malloc( + sizeof(FASTCOVER_tryParameters_data_t)); + LOCALDISPLAYLEVEL(displayLevel, 3, "k=%u\n", k); + if (!data) { + LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to allocate parameters\n"); + COVER_best_destroy(&best); + FASTCOVER_ctx_destroy(&ctx); + POOL_free(pool); + return ERROR(memory_allocation); + } + data->ctx = &ctx; + data->best = &best; + data->dictBufferCapacity = dictBufferCapacity; + data->parameters = coverParams; + data->parameters.k = k; + data->parameters.d = d; + data->parameters.splitPoint = splitPoint; + data->parameters.steps = kSteps; + data->parameters.shrinkDict = shrinkDict; + data->parameters.zParams.notificationLevel = (unsigned)g_displayLevel; + /* Check the parameters */ + if (!FASTCOVER_checkParameters(data->parameters, dictBufferCapacity, + data->ctx->f, accel)) { + DISPLAYLEVEL(1, "FASTCOVER parameters incorrect\n"); + free(data); + continue; + } + /* Call the function and pass ownership of data to it */ + COVER_best_start(&best); + if (pool) { + POOL_add(pool, &FASTCOVER_tryParameters, data); + } else { + FASTCOVER_tryParameters(data); + } + /* Print status */ + LOCALDISPLAYUPDATE(displayLevel, 2, "\r%u%% ", + (unsigned)((iteration * 100) / kIterations)); + ++iteration; + } + COVER_best_wait(&best); + FASTCOVER_ctx_destroy(&ctx); + } + LOCALDISPLAYLEVEL(displayLevel, 2, "\r%79s\r", ""); + /* Fill the output buffer and parameters with output of the best parameters */ + { + const size_t dictSize = best.dictSize; + if (ZSTD_isError(best.compressedSize)) { + const size_t compressedSize = best.compressedSize; + COVER_best_destroy(&best); + POOL_free(pool); + return compressedSize; + } + FASTCOVER_convertToFastCoverParams(best.parameters, parameters, f, accel); + memcpy(dictBuffer, best.dict, dictSize); + COVER_best_destroy(&best); + POOL_free(pool); + return dictSize; + } + +} diff --git a/cpp/third_party/zstd-1.5.7/lib/dictBuilder/zdict.c b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/zdict.c new file mode 100644 index 000000000..d5e60a4da --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dictBuilder/zdict.c @@ -0,0 +1,1133 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/*-************************************** +* Tuning parameters +****************************************/ +#define MINRATIO 4 /* minimum nb of apparition to be selected in dictionary */ +#define ZDICT_MAX_SAMPLES_SIZE (2000U << 20) +#define ZDICT_MIN_SAMPLES_SIZE (ZDICT_CONTENTSIZE_MIN * MINRATIO) + + +/*-************************************** +* Compiler Options +****************************************/ +/* Unix Large Files support (>4GB) */ +#define _FILE_OFFSET_BITS 64 +#if (defined(__sun__) && (!defined(__LP64__))) /* Sun Solaris 32-bits requires specific definitions */ +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE +# endif +#elif ! defined(__LP64__) /* No point defining Large file for 64 bit */ +# ifndef _LARGEFILE64_SOURCE +# define _LARGEFILE64_SOURCE +# endif +#endif + + +/*-************************************* +* Dependencies +***************************************/ +#include /* malloc, free */ +#include /* memset */ +#include /* fprintf, fopen, ftello64 */ +#include /* clock */ + +#ifndef ZDICT_STATIC_LINKING_ONLY +# define ZDICT_STATIC_LINKING_ONLY +#endif + +#include "../common/mem.h" /* read */ +#include "../common/fse.h" /* FSE_normalizeCount, FSE_writeNCount */ +#include "../common/huf.h" /* HUF_buildCTable, HUF_writeCTable */ +#include "../common/zstd_internal.h" /* includes zstd.h */ +#include "../common/xxhash.h" /* XXH64 */ +#include "../compress/zstd_compress_internal.h" /* ZSTD_loadCEntropy() */ +#include "../zdict.h" +#include "divsufsort.h" +#include "../common/bits.h" /* ZSTD_NbCommonBytes */ + + +/*-************************************* +* Constants +***************************************/ +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +#define DICTLISTSIZE_DEFAULT 10000 + +#define NOISELENGTH 32 + +static const U32 g_selectivity_default = 9; + + +/*-************************************* +* Console display +***************************************/ +#undef DISPLAY +#define DISPLAY(...) do { fprintf(stderr, __VA_ARGS__); fflush( stderr ); } while (0) +#undef DISPLAYLEVEL +#define DISPLAYLEVEL(l, ...) do { if (notificationLevel>=l) { DISPLAY(__VA_ARGS__); } } while (0) /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */ + +static clock_t ZDICT_clockSpan(clock_t nPrevious) { return clock() - nPrevious; } + +static void ZDICT_printHex(const void* ptr, size_t length) +{ + const BYTE* const b = (const BYTE*)ptr; + size_t u; + for (u=0; u126) c = '.'; /* non-printable char */ + DISPLAY("%c", c); + } +} + + +/*-******************************************************** +* Helper functions +**********************************************************/ +unsigned ZDICT_isError(size_t errorCode) { return ERR_isError(errorCode); } + +const char* ZDICT_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); } + +unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize) +{ + if (dictSize < 8) return 0; + if (MEM_readLE32(dictBuffer) != ZSTD_MAGIC_DICTIONARY) return 0; + return MEM_readLE32((const char*)dictBuffer + 4); +} + +size_t ZDICT_getDictHeaderSize(const void* dictBuffer, size_t dictSize) +{ + size_t headerSize; + if (dictSize <= 8 || MEM_readLE32(dictBuffer) != ZSTD_MAGIC_DICTIONARY) return ERROR(dictionary_corrupted); + + { ZSTD_compressedBlockState_t* bs = (ZSTD_compressedBlockState_t*)malloc(sizeof(ZSTD_compressedBlockState_t)); + U32* wksp = (U32*)malloc(HUF_WORKSPACE_SIZE); + if (!bs || !wksp) { + headerSize = ERROR(memory_allocation); + } else { + ZSTD_reset_compressedBlockState(bs); + headerSize = ZSTD_loadCEntropy(bs, wksp, dictBuffer, dictSize); + } + + free(bs); + free(wksp); + } + + return headerSize; +} + +/*-******************************************************** +* Dictionary training functions +**********************************************************/ +/*! ZDICT_count() : + Count the nb of common bytes between 2 pointers. + Note : this function presumes end of buffer followed by noisy guard band. +*/ +static size_t ZDICT_count(const void* pIn, const void* pMatch) +{ + const char* const pStart = (const char*)pIn; + for (;;) { + size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); + if (!diff) { + pIn = (const char*)pIn+sizeof(size_t); + pMatch = (const char*)pMatch+sizeof(size_t); + continue; + } + pIn = (const char*)pIn+ZSTD_NbCommonBytes(diff); + return (size_t)((const char*)pIn - pStart); + } +} + + +typedef struct { + U32 pos; + U32 length; + U32 savings; +} dictItem; + +static void ZDICT_initDictItem(dictItem* d) +{ + d->pos = 1; + d->length = 0; + d->savings = (U32)(-1); +} + + +#define LLIMIT 64 /* heuristic determined experimentally */ +#define MINMATCHLENGTH 7 /* heuristic determined experimentally */ +static dictItem ZDICT_analyzePos( + BYTE* doneMarks, + const int* suffix, U32 start, + const void* buffer, U32 minRatio, U32 notificationLevel) +{ + U32 lengthList[LLIMIT] = {0}; + U32 cumulLength[LLIMIT] = {0}; + U32 savings[LLIMIT] = {0}; + const BYTE* b = (const BYTE*)buffer; + size_t maxLength = LLIMIT; + size_t pos = (size_t)suffix[start]; + U32 end = start; + dictItem solution; + + /* init */ + memset(&solution, 0, sizeof(solution)); + doneMarks[pos] = 1; + + /* trivial repetition cases */ + if ( (MEM_read16(b+pos+0) == MEM_read16(b+pos+2)) + ||(MEM_read16(b+pos+1) == MEM_read16(b+pos+3)) + ||(MEM_read16(b+pos+2) == MEM_read16(b+pos+4)) ) { + /* skip and mark segment */ + U16 const pattern16 = MEM_read16(b+pos+4); + U32 u, patternEnd = 6; + while (MEM_read16(b+pos+patternEnd) == pattern16) patternEnd+=2 ; + if (b[pos+patternEnd] == b[pos+patternEnd-1]) patternEnd++; + for (u=1; u= MINMATCHLENGTH); + } + + /* look backward */ + { size_t length; + do { + length = ZDICT_count(b + pos, b + *(suffix+start-1)); + if (length >=MINMATCHLENGTH) start--; + } while(length >= MINMATCHLENGTH); + } + + /* exit if not found a minimum nb of repetitions */ + if (end-start < minRatio) { + U32 idx; + for(idx=start; idx= %i at pos %7u ", (unsigned)(end-start), MINMATCHLENGTH, (unsigned)pos); + DISPLAYLEVEL(4, "\n"); + + for (mml = MINMATCHLENGTH ; ; mml++) { + BYTE currentChar = 0; + U32 currentCount = 0; + U32 currentID = refinedStart; + U32 id; + U32 selectedCount = 0; + U32 selectedID = currentID; + for (id =refinedStart; id < refinedEnd; id++) { + if (b[suffix[id] + mml] != currentChar) { + if (currentCount > selectedCount) { + selectedCount = currentCount; + selectedID = currentID; + } + currentID = id; + currentChar = b[ suffix[id] + mml]; + currentCount = 0; + } + currentCount ++; + } + if (currentCount > selectedCount) { /* for last */ + selectedCount = currentCount; + selectedID = currentID; + } + + if (selectedCount < minRatio) + break; + refinedStart = selectedID; + refinedEnd = refinedStart + selectedCount; + } + + /* evaluate gain based on new dict */ + start = refinedStart; + pos = suffix[refinedStart]; + end = start; + memset(lengthList, 0, sizeof(lengthList)); + + /* look forward */ + { size_t length; + do { + end++; + length = ZDICT_count(b + pos, b + suffix[end]); + if (length >= LLIMIT) length = LLIMIT-1; + lengthList[length]++; + } while (length >=MINMATCHLENGTH); + } + + /* look backward */ + { size_t length = MINMATCHLENGTH; + while ((length >= MINMATCHLENGTH) & (start > 0)) { + length = ZDICT_count(b + pos, b + suffix[start - 1]); + if (length >= LLIMIT) length = LLIMIT - 1; + lengthList[length]++; + if (length >= MINMATCHLENGTH) start--; + } + } + + /* largest useful length */ + memset(cumulLength, 0, sizeof(cumulLength)); + cumulLength[maxLength-1] = lengthList[maxLength-1]; + for (i=(int)(maxLength-2); i>=0; i--) + cumulLength[i] = cumulLength[i+1] + lengthList[i]; + + for (i=LLIMIT-1; i>=MINMATCHLENGTH; i--) if (cumulLength[i]>=minRatio) break; + maxLength = i; + + /* reduce maxLength in case of final into repetitive data */ + { U32 l = (U32)maxLength; + BYTE const c = b[pos + maxLength-1]; + while (b[pos+l-2]==c) l--; + maxLength = l; + } + if (maxLength < MINMATCHLENGTH) return solution; /* skip : no long-enough solution */ + + /* calculate savings */ + savings[5] = 0; + for (i=MINMATCHLENGTH; i<=(int)maxLength; i++) + savings[i] = savings[i-1] + (lengthList[i] * (i-3)); + + DISPLAYLEVEL(4, "Selected dict at position %u, of length %u : saves %u (ratio: %.2f) \n", + (unsigned)pos, (unsigned)maxLength, (unsigned)savings[maxLength], (double)savings[maxLength] / (double)maxLength); + + solution.pos = (U32)pos; + solution.length = (U32)maxLength; + solution.savings = savings[maxLength]; + + /* mark positions done */ + { U32 id; + for (id=start; id solution.length) length = solution.length; + } + pEnd = (U32)(testedPos + length); + for (p=testedPos; ppos; + const U32 eltEnd = elt.pos + elt.length; + const char* const buf = (const char*) buffer; + + /* tail overlap */ + U32 u; for (u=1; u elt.pos) && (table[u].pos <= eltEnd)) { /* overlap, existing > new */ + /* append */ + U32 const addedLength = table[u].pos - elt.pos; + table[u].length += addedLength; + table[u].pos = elt.pos; + table[u].savings += elt.savings * addedLength / elt.length; /* rough approx */ + table[u].savings += elt.length / 8; /* rough approx bonus */ + elt = table[u]; + /* sort : improve rank */ + while ((u>1) && (table[u-1].savings < elt.savings)) + table[u] = table[u-1], u--; + table[u] = elt; + return u; + } } + + /* front overlap */ + for (u=1; u= elt.pos) && (table[u].pos < elt.pos)) { /* overlap, existing < new */ + /* append */ + int const addedLength = (int)eltEnd - (int)(table[u].pos + table[u].length); + table[u].savings += elt.length / 8; /* rough approx bonus */ + if (addedLength > 0) { /* otherwise, elt fully included into existing */ + table[u].length += addedLength; + table[u].savings += elt.savings * addedLength / elt.length; /* rough approx */ + } + /* sort : improve rank */ + elt = table[u]; + while ((u>1) && (table[u-1].savings < elt.savings)) + table[u] = table[u-1], u--; + table[u] = elt; + return u; + } + + if (MEM_read64(buf + table[u].pos) == MEM_read64(buf + elt.pos + 1)) { + if (isIncluded(buf + table[u].pos, buf + elt.pos + 1, table[u].length)) { + size_t const addedLength = MAX( (int)elt.length - (int)table[u].length , 1 ); + table[u].pos = elt.pos; + table[u].savings += (U32)(elt.savings * addedLength / elt.length); + table[u].length = MIN(elt.length, table[u].length + 1); + return u; + } + } + } + + return 0; +} + + +static void ZDICT_removeDictItem(dictItem* table, U32 id) +{ + /* convention : table[0].pos stores nb of elts */ + U32 const max = table[0].pos; + U32 u; + if (!id) return; /* protection, should never happen */ + for (u=id; upos--; +} + + +static void ZDICT_insertDictItem(dictItem* table, U32 maxSize, dictItem elt, const void* buffer) +{ + /* merge if possible */ + U32 mergeId = ZDICT_tryMerge(table, elt, 0, buffer); + if (mergeId) { + U32 newMerge = 1; + while (newMerge) { + newMerge = ZDICT_tryMerge(table, table[mergeId], mergeId, buffer); + if (newMerge) ZDICT_removeDictItem(table, mergeId); + mergeId = newMerge; + } + return; + } + + /* insert */ + { U32 current; + U32 nextElt = table->pos; + if (nextElt >= maxSize) nextElt = maxSize-1; + current = nextElt-1; + while (table[current].savings < elt.savings) { + table[current+1] = table[current]; + current--; + } + table[current+1] = elt; + table->pos = nextElt+1; + } +} + + +static U32 ZDICT_dictSize(const dictItem* dictList) +{ + U32 u, dictSize = 0; + for (u=1; u=l) { \ + if (ZDICT_clockSpan(displayClock) > refreshRate) { \ + displayClock = clock(); \ + DISPLAY(__VA_ARGS__); \ + } \ + if (notificationLevel>=4) fflush(stderr); \ + } \ + } while (0) + + /* init */ + DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */ + if (!suffix0 || !reverseSuffix || !doneMarks || !filePos) { + result = ERROR(memory_allocation); + goto _cleanup; + } + if (minRatio < MINRATIO) minRatio = MINRATIO; + memset(doneMarks, 0, bufferSize+16); + + /* limit sample set size (divsufsort limitation)*/ + if (bufferSize > ZDICT_MAX_SAMPLES_SIZE) DISPLAYLEVEL(3, "sample set too large : reduced to %u MB ...\n", (unsigned)(ZDICT_MAX_SAMPLES_SIZE>>20)); + while (bufferSize > ZDICT_MAX_SAMPLES_SIZE) bufferSize -= fileSizes[--nbFiles]; + + /* sort */ + DISPLAYLEVEL(2, "sorting %u files of total size %u MB ...\n", nbFiles, (unsigned)(bufferSize>>20)); + { int const divSuftSortResult = divsufsort((const unsigned char*)buffer, suffix, (int)bufferSize, 0); + if (divSuftSortResult != 0) { result = ERROR(GENERIC); goto _cleanup; } + } + suffix[bufferSize] = (int)bufferSize; /* leads into noise */ + suffix0[0] = (int)bufferSize; /* leads into noise */ + /* build reverse suffix sort */ + { size_t pos; + for (pos=0; pos < bufferSize; pos++) + reverseSuffix[suffix[pos]] = (U32)pos; + /* note filePos tracks borders between samples. + It's not used at this stage, but planned to become useful in a later update */ + filePos[0] = 0; + for (pos=1; pos> 21); + } +} + + +typedef struct +{ + ZSTD_CDict* dict; /* dictionary */ + ZSTD_CCtx* zc; /* working context */ + void* workPlace; /* must be ZSTD_BLOCKSIZE_MAX allocated */ +} EStats_ress_t; + +#define MAXREPOFFSET 1024 + +static void ZDICT_countEStats(EStats_ress_t esr, const ZSTD_parameters* params, + unsigned* countLit, unsigned* offsetcodeCount, unsigned* matchlengthCount, unsigned* litlengthCount, U32* repOffsets, + const void* src, size_t srcSize, + U32 notificationLevel) +{ + size_t const blockSizeMax = MIN (ZSTD_BLOCKSIZE_MAX, 1 << params->cParams.windowLog); + size_t cSize; + + if (srcSize > blockSizeMax) srcSize = blockSizeMax; /* protection vs large samples */ + { size_t const errorCode = ZSTD_compressBegin_usingCDict_deprecated(esr.zc, esr.dict); + if (ZSTD_isError(errorCode)) { DISPLAYLEVEL(1, "warning : ZSTD_compressBegin_usingCDict failed \n"); return; } + + } + cSize = ZSTD_compressBlock_deprecated(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_MAX, src, srcSize); + if (ZSTD_isError(cSize)) { DISPLAYLEVEL(3, "warning : could not compress sample size %u \n", (unsigned)srcSize); return; } + + if (cSize) { /* if == 0; block is not compressible */ + const SeqStore_t* const seqStorePtr = ZSTD_getSeqStore(esr.zc); + + /* literals stats */ + { const BYTE* bytePtr; + for(bytePtr = seqStorePtr->litStart; bytePtr < seqStorePtr->lit; bytePtr++) + countLit[*bytePtr]++; + } + + /* seqStats */ + { U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + ZSTD_seqToCodes(seqStorePtr); + + { const BYTE* codePtr = seqStorePtr->ofCode; + U32 u; + for (u=0; umlCode; + U32 u; + for (u=0; ullCode; + U32 u; + for (u=0; u= 2) { /* rep offsets */ + const SeqDef* const seq = seqStorePtr->sequencesStart; + U32 offset1 = seq[0].offBase - ZSTD_REP_NUM; + U32 offset2 = seq[1].offBase - ZSTD_REP_NUM; + if (offset1 >= MAXREPOFFSET) offset1 = 0; + if (offset2 >= MAXREPOFFSET) offset2 = 0; + repOffsets[offset1] += 3; + repOffsets[offset2] += 1; + } } } +} + +static size_t ZDICT_totalSampleSize(const size_t* fileSizes, unsigned nbFiles) +{ + size_t total=0; + unsigned u; + for (u=0; u0; u--) { + offsetCount_t tmp; + if (table[u-1].count >= table[u].count) break; + tmp = table[u-1]; + table[u-1] = table[u]; + table[u] = tmp; + } +} + +/* ZDICT_flatLit() : + * rewrite `countLit` to contain a mostly flat but still compressible distribution of literals. + * necessary to avoid generating a non-compressible distribution that HUF_writeCTable() cannot encode. + */ +static void ZDICT_flatLit(unsigned* countLit) +{ + int u; + for (u=1; u<256; u++) countLit[u] = 2; + countLit[0] = 4; + countLit[253] = 1; + countLit[254] = 1; +} + +#define OFFCODE_MAX 30 /* only applicable to first block */ +static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize, + int compressionLevel, + const void* srcBuffer, const size_t* fileSizes, unsigned nbFiles, + const void* dictBuffer, size_t dictBufferSize, + unsigned notificationLevel) +{ + unsigned countLit[256]; + HUF_CREATE_STATIC_CTABLE(hufTable, 255); + unsigned offcodeCount[OFFCODE_MAX+1]; + short offcodeNCount[OFFCODE_MAX+1]; + U32 offcodeMax = ZSTD_highbit32((U32)(dictBufferSize + 128 KB)); + unsigned matchLengthCount[MaxML+1]; + short matchLengthNCount[MaxML+1]; + unsigned litLengthCount[MaxLL+1]; + short litLengthNCount[MaxLL+1]; + U32 repOffset[MAXREPOFFSET]; + offsetCount_t bestRepOffset[ZSTD_REP_NUM+1]; + EStats_ress_t esr = { NULL, NULL, NULL }; + ZSTD_parameters params; + U32 u, huffLog = 11, Offlog = OffFSELog, mlLog = MLFSELog, llLog = LLFSELog, total; + size_t pos = 0, errorCode; + size_t eSize = 0; + size_t const totalSrcSize = ZDICT_totalSampleSize(fileSizes, nbFiles); + size_t const averageSampleSize = totalSrcSize / (nbFiles + !nbFiles); + BYTE* dstPtr = (BYTE*)dstBuffer; + U32 wksp[HUF_CTABLE_WORKSPACE_SIZE_U32]; + + /* init */ + DEBUGLOG(4, "ZDICT_analyzeEntropy"); + if (offcodeMax>OFFCODE_MAX) { eSize = ERROR(dictionaryCreation_failed); goto _cleanup; } /* too large dictionary */ + for (u=0; u<256; u++) countLit[u] = 1; /* any character must be described */ + for (u=0; u<=offcodeMax; u++) offcodeCount[u] = 1; + for (u=0; u<=MaxML; u++) matchLengthCount[u] = 1; + for (u=0; u<=MaxLL; u++) litLengthCount[u] = 1; + memset(repOffset, 0, sizeof(repOffset)); + repOffset[1] = repOffset[4] = repOffset[8] = 1; + memset(bestRepOffset, 0, sizeof(bestRepOffset)); + if (compressionLevel==0) compressionLevel = ZSTD_CLEVEL_DEFAULT; + params = ZSTD_getParams(compressionLevel, averageSampleSize, dictBufferSize); + + esr.dict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, ZSTD_dlm_byRef, ZSTD_dct_rawContent, params.cParams, ZSTD_defaultCMem); + esr.zc = ZSTD_createCCtx(); + esr.workPlace = malloc(ZSTD_BLOCKSIZE_MAX); + if (!esr.dict || !esr.zc || !esr.workPlace) { + eSize = ERROR(memory_allocation); + DISPLAYLEVEL(1, "Not enough memory \n"); + goto _cleanup; + } + + /* collect stats on all samples */ + for (u=0; u= 4) { + /* writeStats */ + DISPLAYLEVEL(4, "Offset Code Frequencies : \n"); + for (u=0; u<=offcodeMax; u++) { + DISPLAYLEVEL(4, "%2u :%7u \n", u, offcodeCount[u]); + } } + + /* analyze, build stats, starting with literals */ + { size_t maxNbBits = HUF_buildCTable_wksp(hufTable, countLit, 255, huffLog, wksp, sizeof(wksp)); + if (HUF_isError(maxNbBits)) { + eSize = maxNbBits; + DISPLAYLEVEL(1, " HUF_buildCTable error \n"); + goto _cleanup; + } + if (maxNbBits==8) { /* not compressible : will fail on HUF_writeCTable() */ + DISPLAYLEVEL(2, "warning : pathological dataset : literals are not compressible : samples are noisy or too regular \n"); + ZDICT_flatLit(countLit); /* replace distribution by a fake "mostly flat but still compressible" distribution, that HUF_writeCTable() can encode */ + maxNbBits = HUF_buildCTable_wksp(hufTable, countLit, 255, huffLog, wksp, sizeof(wksp)); + assert(maxNbBits==9); + } + huffLog = (U32)maxNbBits; + } + + /* looking for most common first offsets */ + { U32 offset; + for (offset=1; offset dictBufferCapacity) { + dictContentSize = dictBufferCapacity - hSize; + } + + /* Pad the dictionary content with zeros if it is too small */ + if (dictContentSize < minContentSize) { + RETURN_ERROR_IF(hSize + minContentSize > dictBufferCapacity, dstSize_tooSmall, + "dictBufferCapacity too small to fit max repcode"); + paddingSize = minContentSize - dictContentSize; + } else { + paddingSize = 0; + } + + { + size_t const dictSize = hSize + paddingSize + dictContentSize; + + /* The dictionary consists of the header, optional padding, and the content. + * The padding comes before the content because the "best" position in the + * dictionary is the last byte. + */ + BYTE* const outDictHeader = (BYTE*)dictBuffer; + BYTE* const outDictPadding = outDictHeader + hSize; + BYTE* const outDictContent = outDictPadding + paddingSize; + + assert(dictSize <= dictBufferCapacity); + assert(outDictContent + dictContentSize == (BYTE*)dictBuffer + dictSize); + + /* First copy the customDictContent into its final location. + * `customDictContent` and `dictBuffer` may overlap, so we must + * do this before any other writes into the output buffer. + * Then copy the header & padding into the output buffer. + */ + memmove(outDictContent, customDictContent, dictContentSize); + memcpy(outDictHeader, header, hSize); + memset(outDictPadding, 0, paddingSize); + + return dictSize; + } +} + + +static size_t ZDICT_addEntropyTablesFromBuffer_advanced( + void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_params_t params) +{ + int const compressionLevel = (params.compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : params.compressionLevel; + U32 const notificationLevel = params.notificationLevel; + size_t hSize = 8; + + /* calculate entropy tables */ + DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */ + DISPLAYLEVEL(2, "statistics ... \n"); + { size_t const eSize = ZDICT_analyzeEntropy((char*)dictBuffer+hSize, dictBufferCapacity-hSize, + compressionLevel, + samplesBuffer, samplesSizes, nbSamples, + (char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize, + notificationLevel); + if (ZDICT_isError(eSize)) return eSize; + hSize += eSize; + } + + /* add dictionary header (after entropy tables) */ + MEM_writeLE32(dictBuffer, ZSTD_MAGIC_DICTIONARY); + { U64 const randomID = XXH64((char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize, 0); + U32 const compliantID = (randomID % ((1U<<31)-32768)) + 32768; + U32 const dictID = params.dictID ? params.dictID : compliantID; + MEM_writeLE32((char*)dictBuffer+4, dictID); + } + + if (hSize + dictContentSize < dictBufferCapacity) + memmove((char*)dictBuffer + hSize, (char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize); + return MIN(dictBufferCapacity, hSize+dictContentSize); +} + +/*! ZDICT_trainFromBuffer_unsafe_legacy() : +* Warning : `samplesBuffer` must be followed by noisy guard band !!! +* @return : size of dictionary, or an error code which can be tested with ZDICT_isError() +*/ +static size_t ZDICT_trainFromBuffer_unsafe_legacy( + void* dictBuffer, size_t maxDictSize, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_legacy_params_t params) +{ + U32 const dictListSize = MAX(MAX(DICTLISTSIZE_DEFAULT, nbSamples), (U32)(maxDictSize/16)); + dictItem* const dictList = (dictItem*)malloc(dictListSize * sizeof(*dictList)); + unsigned const selectivity = params.selectivityLevel == 0 ? g_selectivity_default : params.selectivityLevel; + unsigned const minRep = (selectivity > 30) ? MINRATIO : nbSamples >> selectivity; + size_t const targetDictSize = maxDictSize; + size_t const samplesBuffSize = ZDICT_totalSampleSize(samplesSizes, nbSamples); + size_t dictSize = 0; + U32 const notificationLevel = params.zParams.notificationLevel; + + /* checks */ + if (!dictList) return ERROR(memory_allocation); + if (maxDictSize < ZDICT_DICTSIZE_MIN) { free(dictList); return ERROR(dstSize_tooSmall); } /* requested dictionary size is too small */ + if (samplesBuffSize < ZDICT_MIN_SAMPLES_SIZE) { free(dictList); return ERROR(dictionaryCreation_failed); } /* not enough source to create dictionary */ + + /* init */ + ZDICT_initDictItem(dictList); + + /* build dictionary */ + ZDICT_trainBuffer_legacy(dictList, dictListSize, + samplesBuffer, samplesBuffSize, + samplesSizes, nbSamples, + minRep, notificationLevel); + + /* display best matches */ + if (params.zParams.notificationLevel>= 3) { + unsigned const nb = MIN(25, dictList[0].pos); + unsigned const dictContentSize = ZDICT_dictSize(dictList); + unsigned u; + DISPLAYLEVEL(3, "\n %u segments found, of total size %u \n", (unsigned)dictList[0].pos-1, dictContentSize); + DISPLAYLEVEL(3, "list %u best segments \n", nb-1); + for (u=1; u samplesBuffSize) || ((pos + length) > samplesBuffSize)) { + free(dictList); + return ERROR(GENERIC); /* should never happen */ + } + DISPLAYLEVEL(3, "%3u:%3u bytes at pos %8u, savings %7u bytes |", + u, length, pos, (unsigned)dictList[u].savings); + ZDICT_printHex((const char*)samplesBuffer+pos, printedLength); + DISPLAYLEVEL(3, "| \n"); + } } + + + /* create dictionary */ + { unsigned dictContentSize = ZDICT_dictSize(dictList); + if (dictContentSize < ZDICT_CONTENTSIZE_MIN) { free(dictList); return ERROR(dictionaryCreation_failed); } /* dictionary content too small */ + if (dictContentSize < targetDictSize/4) { + DISPLAYLEVEL(2, "! warning : selected content significantly smaller than requested (%u < %u) \n", dictContentSize, (unsigned)maxDictSize); + if (samplesBuffSize < 10 * targetDictSize) + DISPLAYLEVEL(2, "! consider increasing the number of samples (total size : %u MB)\n", (unsigned)(samplesBuffSize>>20)); + if (minRep > MINRATIO) { + DISPLAYLEVEL(2, "! consider increasing selectivity to produce larger dictionary (-s%u) \n", selectivity+1); + DISPLAYLEVEL(2, "! note : larger dictionaries are not necessarily better, test its efficiency on samples \n"); + } + } + + if ((dictContentSize > targetDictSize*3) && (nbSamples > 2*MINRATIO) && (selectivity>1)) { + unsigned proposedSelectivity = selectivity-1; + while ((nbSamples >> proposedSelectivity) <= MINRATIO) { proposedSelectivity--; } + DISPLAYLEVEL(2, "! note : calculated dictionary significantly larger than requested (%u > %u) \n", dictContentSize, (unsigned)maxDictSize); + DISPLAYLEVEL(2, "! consider increasing dictionary size, or produce denser dictionary (-s%u) \n", proposedSelectivity); + DISPLAYLEVEL(2, "! always test dictionary efficiency on real samples \n"); + } + + /* limit dictionary size */ + { U32 const max = dictList->pos; /* convention : nb of useful elts within dictList */ + U32 currentSize = 0; + U32 n; for (n=1; n targetDictSize) { currentSize -= dictList[n].length; break; } + } + dictList->pos = n; + dictContentSize = currentSize; + } + + /* build dict content */ + { U32 u; + BYTE* ptr = (BYTE*)dictBuffer + maxDictSize; + for (u=1; upos; u++) { + U32 l = dictList[u].length; + ptr -= l; + if (ptr<(BYTE*)dictBuffer) { free(dictList); return ERROR(GENERIC); } /* should not happen */ + memcpy(ptr, (const char*)samplesBuffer+dictList[u].pos, l); + } } + + dictSize = ZDICT_addEntropyTablesFromBuffer_advanced(dictBuffer, dictContentSize, maxDictSize, + samplesBuffer, samplesSizes, nbSamples, + params.zParams); + } + + /* clean up */ + free(dictList); + return dictSize; +} + + +/* ZDICT_trainFromBuffer_legacy() : + * issue : samplesBuffer need to be followed by a noisy guard band. + * work around : duplicate the buffer, and add the noise */ +size_t ZDICT_trainFromBuffer_legacy(void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_legacy_params_t params) +{ + size_t result; + void* newBuff; + size_t const sBuffSize = ZDICT_totalSampleSize(samplesSizes, nbSamples); + if (sBuffSize < ZDICT_MIN_SAMPLES_SIZE) return 0; /* not enough content => no dictionary */ + + newBuff = malloc(sBuffSize + NOISELENGTH); + if (!newBuff) return ERROR(memory_allocation); + + memcpy(newBuff, samplesBuffer, sBuffSize); + ZDICT_fillNoise((char*)newBuff + sBuffSize, NOISELENGTH); /* guard band, for end of buffer condition */ + + result = + ZDICT_trainFromBuffer_unsafe_legacy(dictBuffer, dictBufferCapacity, newBuff, + samplesSizes, nbSamples, params); + free(newBuff); + return result; +} + + +size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples) +{ + ZDICT_fastCover_params_t params; + DEBUGLOG(3, "ZDICT_trainFromBuffer"); + memset(¶ms, 0, sizeof(params)); + params.d = 8; + params.steps = 4; + /* Use default level since no compression level information is available */ + params.zParams.compressionLevel = ZSTD_CLEVEL_DEFAULT; +#if defined(DEBUGLEVEL) && (DEBUGLEVEL>=1) + params.zParams.notificationLevel = DEBUGLEVEL; +#endif + return ZDICT_optimizeTrainFromBuffer_fastCover(dictBuffer, dictBufferCapacity, + samplesBuffer, samplesSizes, nbSamples, + ¶ms); +} + +size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples) +{ + ZDICT_params_t params; + memset(¶ms, 0, sizeof(params)); + return ZDICT_addEntropyTablesFromBuffer_advanced(dictBuffer, dictContentSize, dictBufferCapacity, + samplesBuffer, samplesSizes, nbSamples, + params); +} diff --git a/cpp/third_party/zstd-1.5.7/lib/dll/example/Makefile b/cpp/third_party/zstd-1.5.7/lib/dll/example/Makefile new file mode 100644 index 000000000..86cf6906e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dll/example/Makefile @@ -0,0 +1,48 @@ +# ################################################################ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ + +VOID := /dev/null +ZSTDDIR := ../include +LIBDIR := ../static +DLLDIR := ../dll + +CFLAGS ?= -O3 # can select custom flags. For example : CFLAGS="-O2 -g" make +CFLAGS += -Wall -Wextra -Wundef -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum \ + -Wdeclaration-after-statement -Wstrict-prototypes \ + -Wpointer-arith -Wstrict-aliasing=1 +CFLAGS += $(MOREFLAGS) +CPPFLAGS:= -I$(ZSTDDIR) -DXXH_NAMESPACE=ZSTD_ +FLAGS := $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) + + +# Define *.exe as extension for Windows systems +ifneq (,$(filter Windows%,$(OS))) +EXT =.exe +else +EXT = +endif + +.PHONY: default fullbench-dll fullbench-lib + + +default: all + +all: fullbench-dll fullbench-lib + + +fullbench-lib: fullbench.c datagen.c + $(CC) $(FLAGS) $^ -o $@$(EXT) $(LIBDIR)/libzstd_static.lib + +fullbench-dll: fullbench.c datagen.c + $(CC) $(FLAGS) $^ -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(DLLDIR)/libzstd.dll + +clean: + @$(RM) fullbench-dll$(EXT) fullbench-lib$(EXT) \ + @echo Cleaning completed diff --git a/cpp/third_party/zstd-1.5.7/lib/dll/example/README.md b/cpp/third_party/zstd-1.5.7/lib/dll/example/README.md new file mode 100644 index 000000000..46aec7980 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dll/example/README.md @@ -0,0 +1,63 @@ +# ZSTD Windows binary package + +## The package contents + +- `zstd.exe` : Command Line Utility, supporting gzip-like arguments +- `dll\libzstd.dll` : The ZSTD dynamic library (DLL) +- `dll\libzstd.lib` : The import library of the ZSTD dynamic library (DLL) for Visual C++ +- `example\` : The example of usage of the ZSTD library +- `include\` : Header files required by the ZSTD library +- `static\libzstd_static.lib` : The static ZSTD library (LIB) + +## Usage of Command Line Interface + +Command Line Interface (CLI) supports gzip-like arguments. +By default CLI takes an input file and compresses it to an output file: + + Usage: zstd [arg] [input] [output] + +The full list of commands for CLI can be obtained with `-h` or `-H`. The ratio can +be improved with commands from `-3` to `-16` but higher levels also have slower +compression. CLI includes in-memory compression benchmark module with compression +levels starting from `-b` and ending with `-e` with iteration time of `-i` seconds. +CLI supports aggregation of parameters i.e. `-b1`, `-e18`, and `-i1` can be joined +into `-b1e18i1`. + +## The example of usage of static and dynamic ZSTD libraries with gcc/MinGW + +Use `cd example` and `make` to build `fullbench-dll` and `fullbench-lib`. +`fullbench-dll` uses a dynamic ZSTD library from the `dll` directory. +`fullbench-lib` uses a static ZSTD library from the `lib` directory. + +## Using ZSTD DLL with gcc/MinGW + +The header files from `include\` and the dynamic library `dll\libzstd.dll` +are required to compile a project using gcc/MinGW. +The dynamic library has to be added to linking options. +It means that if a project that uses ZSTD consists of a single `test-dll.c` +file it should be linked with `dll\libzstd.dll`. For example: + + gcc $(CFLAGS) -Iinclude\ test-dll.c -o test-dll dll\libzstd.dll + +The compiled executable will require ZSTD DLL which is available at `dll\libzstd.dll`. + +## The example of usage of static and dynamic ZSTD libraries with Visual C++ + +Open `example\fullbench-dll.sln` to compile `fullbench-dll` that uses a +dynamic ZSTD library from the `dll` directory. The solution works with Visual C++ +2010 or newer. When one will open the solution with Visual C++ newer than 2010 +then the solution will be upgraded to the current version. + +## Using ZSTD DLL with Visual C++ + +The header files from `include\` and the import library `dll\libzstd.lib` +are required to compile a project using Visual C++. + +1. The path to header files should be added to `Additional Include Directories` that can + be found in project properties `C/C++` then `General`. +2. The import library has to be added to `Additional Dependencies` that can + be found in project properties `Linker` then `Input`. + If one will provide only the name `libzstd.lib` without a full path to the library + the directory has to be added to `Linker\General\Additional Library Directories`. + +The compiled executable will require ZSTD DLL which is available at `dll\libzstd.dll`. diff --git a/cpp/third_party/zstd-1.5.7/lib/dll/example/build_package.bat b/cpp/third_party/zstd-1.5.7/lib/dll/example/build_package.bat new file mode 100644 index 000000000..8baabc7b2 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dll/example/build_package.bat @@ -0,0 +1,20 @@ +@ECHO OFF +MKDIR bin\dll bin\static bin\example bin\include +COPY tests\fullbench.c bin\example\ +COPY programs\datagen.c bin\example\ +COPY programs\datagen.h bin\example\ +COPY programs\util.h bin\example\ +COPY programs\platform.h bin\example\ +COPY lib\common\mem.h bin\example\ +COPY lib\common\zstd_internal.h bin\example\ +COPY lib\common\error_private.h bin\example\ +COPY lib\common\xxhash.h bin\example\ +COPY lib\libzstd.a bin\static\libzstd_static.lib +COPY lib\dll\libzstd.* bin\dll\ +COPY lib\dll\example\Makefile bin\example\ +COPY lib\dll\example\fullbench-dll.* bin\example\ +COPY lib\dll\example\README.md bin\ +COPY lib\zstd.h bin\include\ +COPY lib\common\zstd_errors.h bin\include\ +COPY lib\dictBuilder\zdict.h bin\include\ +COPY programs\zstd.exe bin\zstd.exe diff --git a/cpp/third_party/zstd-1.5.7/lib/dll/example/fullbench-dll.sln b/cpp/third_party/zstd-1.5.7/lib/dll/example/fullbench-dll.sln new file mode 100644 index 000000000..72e302e7f --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dll/example/fullbench-dll.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2012 for Windows Desktop +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench-dll", "fullbench-dll.vcxproj", "{13992FD2-077E-4954-B065-A428198201A9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {13992FD2-077E-4954-B065-A428198201A9}.Debug|Win32.ActiveCfg = Debug|Win32 + {13992FD2-077E-4954-B065-A428198201A9}.Debug|Win32.Build.0 = Debug|Win32 + {13992FD2-077E-4954-B065-A428198201A9}.Debug|x64.ActiveCfg = Debug|x64 + {13992FD2-077E-4954-B065-A428198201A9}.Debug|x64.Build.0 = Debug|x64 + {13992FD2-077E-4954-B065-A428198201A9}.Release|Win32.ActiveCfg = Release|Win32 + {13992FD2-077E-4954-B065-A428198201A9}.Release|Win32.Build.0 = Release|Win32 + {13992FD2-077E-4954-B065-A428198201A9}.Release|x64.ActiveCfg = Release|x64 + {13992FD2-077E-4954-B065-A428198201A9}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cpp/third_party/zstd-1.5.7/lib/dll/example/fullbench-dll.vcxproj b/cpp/third_party/zstd-1.5.7/lib/dll/example/fullbench-dll.vcxproj new file mode 100644 index 000000000..44bbaf788 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/dll/example/fullbench-dll.vcxproj @@ -0,0 +1,181 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8} + Win32Proj + fullbench-dll + $(SolutionDir)bin\$(Platform)_$(Configuration)\ + $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + true + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + true + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + false + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + false + $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); + false + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) + true + false + ..\include + + + Console + true + $(SolutionDir)..\dll;%(AdditionalLibraryDirectories) + libzstd.lib;%(AdditionalDependencies) + false + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) + true + false + ..\include + + + Console + true + $(SolutionDir)..\dll;%(AdditionalLibraryDirectories) + libzstd.lib;%(AdditionalDependencies) + + + + + Level4 + + + MaxSpeed + true + true + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) + false + ..\include + false + MultiThreaded + + + Console + true + true + true + $(SolutionDir)..\dll;%(AdditionalLibraryDirectories) + libzstd.lib;%(AdditionalDependencies) + false + + + + + Level4 + + + MaxSpeed + true + true + WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) + false + false + ..\include + MultiThreaded + + + Console + true + true + true + $(SolutionDir)..\dll;%(AdditionalLibraryDirectories) + libzstd.lib;%(AdditionalDependencies) + + + + + + + + + + + + + \ No newline at end of file diff --git a/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_legacy.h b/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_legacy.h new file mode 100644 index 000000000..7a8a04e59 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_legacy.h @@ -0,0 +1,452 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LEGACY_H +#define ZSTD_LEGACY_H + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ************************************* +* Includes +***************************************/ +#include "../common/mem.h" /* MEM_STATIC */ +#include "../common/error_private.h" /* ERROR */ +#include "../common/zstd_internal.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTD_frameSizeInfo */ + +#if !defined (ZSTD_LEGACY_SUPPORT) || (ZSTD_LEGACY_SUPPORT == 0) +# undef ZSTD_LEGACY_SUPPORT +# define ZSTD_LEGACY_SUPPORT 8 +#endif + +#if (ZSTD_LEGACY_SUPPORT <= 1) +# include "zstd_v01.h" +#endif +#if (ZSTD_LEGACY_SUPPORT <= 2) +# include "zstd_v02.h" +#endif +#if (ZSTD_LEGACY_SUPPORT <= 3) +# include "zstd_v03.h" +#endif +#if (ZSTD_LEGACY_SUPPORT <= 4) +# include "zstd_v04.h" +#endif +#if (ZSTD_LEGACY_SUPPORT <= 5) +# include "zstd_v05.h" +#endif +#if (ZSTD_LEGACY_SUPPORT <= 6) +# include "zstd_v06.h" +#endif +#if (ZSTD_LEGACY_SUPPORT <= 7) +# include "zstd_v07.h" +#endif + +/** ZSTD_isLegacy() : + @return : > 0 if supported by legacy decoder. 0 otherwise. + return value is the version. +*/ +MEM_STATIC unsigned ZSTD_isLegacy(const void* src, size_t srcSize) +{ + U32 magicNumberLE; + if (srcSize<4) return 0; + magicNumberLE = MEM_readLE32(src); + switch(magicNumberLE) + { +#if (ZSTD_LEGACY_SUPPORT <= 1) + case ZSTDv01_magicNumberLE:return 1; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 2) + case ZSTDv02_magicNumber : return 2; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 3) + case ZSTDv03_magicNumber : return 3; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 4) + case ZSTDv04_magicNumber : return 4; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 5) + case ZSTDv05_MAGICNUMBER : return 5; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 6) + case ZSTDv06_MAGICNUMBER : return 6; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 7) + case ZSTDv07_MAGICNUMBER : return 7; +#endif + default : return 0; + } +} + + +MEM_STATIC unsigned long long ZSTD_getDecompressedSize_legacy(const void* src, size_t srcSize) +{ + U32 const version = ZSTD_isLegacy(src, srcSize); + if (version < 5) return 0; /* no decompressed size in frame header, or not a legacy format */ +#if (ZSTD_LEGACY_SUPPORT <= 5) + if (version==5) { + ZSTDv05_parameters fParams; + size_t const frResult = ZSTDv05_getFrameParams(&fParams, src, srcSize); + if (frResult != 0) return 0; + return fParams.srcSize; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 6) + if (version==6) { + ZSTDv06_frameParams fParams; + size_t const frResult = ZSTDv06_getFrameParams(&fParams, src, srcSize); + if (frResult != 0) return 0; + return fParams.frameContentSize; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 7) + if (version==7) { + ZSTDv07_frameParams fParams; + size_t const frResult = ZSTDv07_getFrameParams(&fParams, src, srcSize); + if (frResult != 0) return 0; + return fParams.frameContentSize; + } +#endif + return 0; /* should not be possible */ +} + + +MEM_STATIC size_t ZSTD_decompressLegacy( + void* dst, size_t dstCapacity, + const void* src, size_t compressedSize, + const void* dict,size_t dictSize) +{ + U32 const version = ZSTD_isLegacy(src, compressedSize); + char x; + /* Avoid passing NULL to legacy decoding. */ + if (dst == NULL) { + assert(dstCapacity == 0); + dst = &x; + } + if (src == NULL) { + assert(compressedSize == 0); + src = &x; + } + if (dict == NULL) { + assert(dictSize == 0); + dict = &x; + } + (void)dst; (void)dstCapacity; (void)dict; (void)dictSize; /* unused when ZSTD_LEGACY_SUPPORT >= 8 */ + switch(version) + { +#if (ZSTD_LEGACY_SUPPORT <= 1) + case 1 : + return ZSTDv01_decompress(dst, dstCapacity, src, compressedSize); +#endif +#if (ZSTD_LEGACY_SUPPORT <= 2) + case 2 : + return ZSTDv02_decompress(dst, dstCapacity, src, compressedSize); +#endif +#if (ZSTD_LEGACY_SUPPORT <= 3) + case 3 : + return ZSTDv03_decompress(dst, dstCapacity, src, compressedSize); +#endif +#if (ZSTD_LEGACY_SUPPORT <= 4) + case 4 : + return ZSTDv04_decompress(dst, dstCapacity, src, compressedSize); +#endif +#if (ZSTD_LEGACY_SUPPORT <= 5) + case 5 : + { size_t result; + ZSTDv05_DCtx* const zd = ZSTDv05_createDCtx(); + if (zd==NULL) return ERROR(memory_allocation); + result = ZSTDv05_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize); + ZSTDv05_freeDCtx(zd); + return result; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 6) + case 6 : + { size_t result; + ZSTDv06_DCtx* const zd = ZSTDv06_createDCtx(); + if (zd==NULL) return ERROR(memory_allocation); + result = ZSTDv06_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize); + ZSTDv06_freeDCtx(zd); + return result; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 7) + case 7 : + { size_t result; + ZSTDv07_DCtx* const zd = ZSTDv07_createDCtx(); + if (zd==NULL) return ERROR(memory_allocation); + result = ZSTDv07_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize); + ZSTDv07_freeDCtx(zd); + return result; + } +#endif + default : + return ERROR(prefix_unknown); + } +} + +MEM_STATIC ZSTD_frameSizeInfo ZSTD_findFrameSizeInfoLegacy(const void *src, size_t srcSize) +{ + ZSTD_frameSizeInfo frameSizeInfo; + U32 const version = ZSTD_isLegacy(src, srcSize); + switch(version) + { +#if (ZSTD_LEGACY_SUPPORT <= 1) + case 1 : + ZSTDv01_findFrameSizeInfoLegacy(src, srcSize, + &frameSizeInfo.compressedSize, + &frameSizeInfo.decompressedBound); + break; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 2) + case 2 : + ZSTDv02_findFrameSizeInfoLegacy(src, srcSize, + &frameSizeInfo.compressedSize, + &frameSizeInfo.decompressedBound); + break; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 3) + case 3 : + ZSTDv03_findFrameSizeInfoLegacy(src, srcSize, + &frameSizeInfo.compressedSize, + &frameSizeInfo.decompressedBound); + break; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 4) + case 4 : + ZSTDv04_findFrameSizeInfoLegacy(src, srcSize, + &frameSizeInfo.compressedSize, + &frameSizeInfo.decompressedBound); + break; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 5) + case 5 : + ZSTDv05_findFrameSizeInfoLegacy(src, srcSize, + &frameSizeInfo.compressedSize, + &frameSizeInfo.decompressedBound); + break; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 6) + case 6 : + ZSTDv06_findFrameSizeInfoLegacy(src, srcSize, + &frameSizeInfo.compressedSize, + &frameSizeInfo.decompressedBound); + break; +#endif +#if (ZSTD_LEGACY_SUPPORT <= 7) + case 7 : + ZSTDv07_findFrameSizeInfoLegacy(src, srcSize, + &frameSizeInfo.compressedSize, + &frameSizeInfo.decompressedBound); + break; +#endif + default : + frameSizeInfo.compressedSize = ERROR(prefix_unknown); + frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR; + break; + } + if (!ZSTD_isError(frameSizeInfo.compressedSize) && frameSizeInfo.compressedSize > srcSize) { + frameSizeInfo.compressedSize = ERROR(srcSize_wrong); + frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR; + } + /* In all cases, decompressedBound == nbBlocks * ZSTD_BLOCKSIZE_MAX. + * So we can compute nbBlocks without having to change every function. + */ + if (frameSizeInfo.decompressedBound != ZSTD_CONTENTSIZE_ERROR) { + assert((frameSizeInfo.decompressedBound & (ZSTD_BLOCKSIZE_MAX - 1)) == 0); + frameSizeInfo.nbBlocks = (size_t)(frameSizeInfo.decompressedBound / ZSTD_BLOCKSIZE_MAX); + } + return frameSizeInfo; +} + +MEM_STATIC size_t ZSTD_findFrameCompressedSizeLegacy(const void *src, size_t srcSize) +{ + ZSTD_frameSizeInfo frameSizeInfo = ZSTD_findFrameSizeInfoLegacy(src, srcSize); + return frameSizeInfo.compressedSize; +} + +MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version) +{ + switch(version) + { + default : + case 1 : + case 2 : + case 3 : + (void)legacyContext; + return ERROR(version_unsupported); +#if (ZSTD_LEGACY_SUPPORT <= 4) + case 4 : return ZBUFFv04_freeDCtx((ZBUFFv04_DCtx*)legacyContext); +#endif +#if (ZSTD_LEGACY_SUPPORT <= 5) + case 5 : return ZBUFFv05_freeDCtx((ZBUFFv05_DCtx*)legacyContext); +#endif +#if (ZSTD_LEGACY_SUPPORT <= 6) + case 6 : return ZBUFFv06_freeDCtx((ZBUFFv06_DCtx*)legacyContext); +#endif +#if (ZSTD_LEGACY_SUPPORT <= 7) + case 7 : return ZBUFFv07_freeDCtx((ZBUFFv07_DCtx*)legacyContext); +#endif + } +} + + +MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion, + const void* dict, size_t dictSize) +{ + char x; + /* Avoid passing NULL to legacy decoding. */ + if (dict == NULL) { + assert(dictSize == 0); + dict = &x; + } + DEBUGLOG(5, "ZSTD_initLegacyStream for v0.%u", newVersion); + if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion); + switch(newVersion) + { + default : + case 1 : + case 2 : + case 3 : + (void)dict; (void)dictSize; + return 0; +#if (ZSTD_LEGACY_SUPPORT <= 4) + case 4 : + { + ZBUFFv04_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv04_createDCtx() : (ZBUFFv04_DCtx*)*legacyContext; + if (dctx==NULL) return ERROR(memory_allocation); + ZBUFFv04_decompressInit(dctx); + ZBUFFv04_decompressWithDictionary(dctx, dict, dictSize); + *legacyContext = dctx; + return 0; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 5) + case 5 : + { + ZBUFFv05_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv05_createDCtx() : (ZBUFFv05_DCtx*)*legacyContext; + if (dctx==NULL) return ERROR(memory_allocation); + ZBUFFv05_decompressInitDictionary(dctx, dict, dictSize); + *legacyContext = dctx; + return 0; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 6) + case 6 : + { + ZBUFFv06_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv06_createDCtx() : (ZBUFFv06_DCtx*)*legacyContext; + if (dctx==NULL) return ERROR(memory_allocation); + ZBUFFv06_decompressInitDictionary(dctx, dict, dictSize); + *legacyContext = dctx; + return 0; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 7) + case 7 : + { + ZBUFFv07_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv07_createDCtx() : (ZBUFFv07_DCtx*)*legacyContext; + if (dctx==NULL) return ERROR(memory_allocation); + ZBUFFv07_decompressInitDictionary(dctx, dict, dictSize); + *legacyContext = dctx; + return 0; + } +#endif + } +} + + + +MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version, + ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + static char x; + /* Avoid passing NULL to legacy decoding. */ + if (output->dst == NULL) { + assert(output->size == 0); + output->dst = &x; + } + if (input->src == NULL) { + assert(input->size == 0); + input->src = &x; + } + DEBUGLOG(5, "ZSTD_decompressLegacyStream for v0.%u", version); + switch(version) + { + default : + case 1 : + case 2 : + case 3 : + (void)legacyContext; (void)output; (void)input; + return ERROR(version_unsupported); +#if (ZSTD_LEGACY_SUPPORT <= 4) + case 4 : + { + ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) legacyContext; + const void* src = (const char*)input->src + input->pos; + size_t readSize = input->size - input->pos; + void* dst = (char*)output->dst + output->pos; + size_t decodedSize = output->size - output->pos; + size_t const hintSize = ZBUFFv04_decompressContinue(dctx, dst, &decodedSize, src, &readSize); + output->pos += decodedSize; + input->pos += readSize; + return hintSize; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 5) + case 5 : + { + ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) legacyContext; + const void* src = (const char*)input->src + input->pos; + size_t readSize = input->size - input->pos; + void* dst = (char*)output->dst + output->pos; + size_t decodedSize = output->size - output->pos; + size_t const hintSize = ZBUFFv05_decompressContinue(dctx, dst, &decodedSize, src, &readSize); + output->pos += decodedSize; + input->pos += readSize; + return hintSize; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 6) + case 6 : + { + ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) legacyContext; + const void* src = (const char*)input->src + input->pos; + size_t readSize = input->size - input->pos; + void* dst = (char*)output->dst + output->pos; + size_t decodedSize = output->size - output->pos; + size_t const hintSize = ZBUFFv06_decompressContinue(dctx, dst, &decodedSize, src, &readSize); + output->pos += decodedSize; + input->pos += readSize; + return hintSize; + } +#endif +#if (ZSTD_LEGACY_SUPPORT <= 7) + case 7 : + { + ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) legacyContext; + const void* src = (const char*)input->src + input->pos; + size_t readSize = input->size - input->pos; + void* dst = (char*)output->dst + output->pos; + size_t decodedSize = output->size - output->pos; + size_t const hintSize = ZBUFFv07_decompressContinue(dctx, dst, &decodedSize, src, &readSize); + output->pos += decodedSize; + input->pos += readSize; + return hintSize; + } +#endif + } +} + + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_LEGACY_H */ diff --git a/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v01.c b/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v01.c new file mode 100644 index 000000000..ad3c9330e --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v01.c @@ -0,0 +1,2127 @@ +/* + * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/****************************************** +* Includes +******************************************/ +#include /* size_t, ptrdiff_t */ +#include "zstd_v01.h" +#include "../common/compiler.h" +#include "../common/error_private.h" + + +/****************************************** +* Static allocation +******************************************/ +/* You can statically allocate FSE CTable/DTable as a table of unsigned using below macro */ +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect +* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ +#define FSE_MAX_MEMORY_USAGE 14 +#define FSE_DEFAULT_MEMORY_USAGE 13 + +/* FSE_MAX_SYMBOL_VALUE : +* Maximum symbol value authorized. +* Required for proper stack allocation */ +#define FSE_MAX_SYMBOL_VALUE 255 + + +/**************************************************************** +* template functions type & suffix +****************************************************************/ +#define FSE_FUNCTION_TYPE BYTE +#define FSE_FUNCTION_EXTENSION + + +/**************************************************************** +* Byte symbol type +****************************************************************/ +typedef struct +{ + unsigned short newState; + unsigned char symbol; + unsigned char nbBits; +} FSE_decode_t; /* size == U32 */ + + + +/**************************************************************** +* Compiler specifics +****************************************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# define FORCE_INLINE static __forceinline +# include /* For Visual 2005 */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ +#else +# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# ifdef __GNUC__ +# define FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define FORCE_INLINE static inline +# endif +# else +# define FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +#endif + + +/**************************************************************** +* Includes +****************************************************************/ +#include /* malloc, free, qsort */ +#include /* memcpy, memset */ +#include /* printf (debug) */ + + +#ifndef MEM_ACCESS_MODULE +#define MEM_ACCESS_MODULE +/**************************************************************** +* Basic Types +*****************************************************************/ +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# include +typedef uint8_t BYTE; +typedef uint16_t U16; +typedef int16_t S16; +typedef uint32_t U32; +typedef int32_t S32; +typedef uint64_t U64; +typedef int64_t S64; +#else +typedef unsigned char BYTE; +typedef unsigned short U16; +typedef signed short S16; +typedef unsigned int U32; +typedef signed int S32; +typedef unsigned long long U64; +typedef signed long long S64; +#endif + +#endif /* MEM_ACCESS_MODULE */ + +/**************************************************************** +* Memory I/O +*****************************************************************/ + +static unsigned FSE_32bits(void) +{ + return sizeof(void*)==4; +} + +static unsigned FSE_isLittleEndian(void) +{ + const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +} + +static U16 FSE_read16(const void* memPtr) +{ + U16 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +static U32 FSE_read32(const void* memPtr) +{ + U32 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +static U64 FSE_read64(const void* memPtr) +{ + U64 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +static U16 FSE_readLE16(const void* memPtr) +{ + if (FSE_isLittleEndian()) + return FSE_read16(memPtr); + else + { + const BYTE* p = (const BYTE*)memPtr; + return (U16)(p[0] + (p[1]<<8)); + } +} + +static U32 FSE_readLE32(const void* memPtr) +{ + if (FSE_isLittleEndian()) + return FSE_read32(memPtr); + else + { + const BYTE* p = (const BYTE*)memPtr; + return (U32)((U32)p[0] + ((U32)p[1]<<8) + ((U32)p[2]<<16) + ((U32)p[3]<<24)); + } +} + + +static U64 FSE_readLE64(const void* memPtr) +{ + if (FSE_isLittleEndian()) + return FSE_read64(memPtr); + else + { + const BYTE* p = (const BYTE*)memPtr; + return (U64)((U64)p[0] + ((U64)p[1]<<8) + ((U64)p[2]<<16) + ((U64)p[3]<<24) + + ((U64)p[4]<<32) + ((U64)p[5]<<40) + ((U64)p[6]<<48) + ((U64)p[7]<<56)); + } +} + +static size_t FSE_readLEST(const void* memPtr) +{ + if (FSE_32bits()) + return (size_t)FSE_readLE32(memPtr); + else + return (size_t)FSE_readLE64(memPtr); +} + + + +/**************************************************************** +* Constants +*****************************************************************/ +#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) +#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX +#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" +#endif + + +/**************************************************************** +* Error Management +****************************************************************/ +#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ + + +/**************************************************************** +* Complex types +****************************************************************/ +typedef struct +{ + int deltaFindState; + U32 deltaNbBits; +} FSE_symbolCompressionTransform; /* total 8 bytes */ + +typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; + +/**************************************************************** +* Internal functions +****************************************************************/ +FORCE_INLINE unsigned FSE_highbit32 (U32 val) +{ +# if defined(_MSC_VER) /* Visual */ + unsigned long r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; +# elif defined(__GNUC__) && (GCC_VERSION >= 304) /* GCC Intrinsic */ + return __builtin_clz (val) ^ 31; +# else /* Software version */ + static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; + U32 v = val; + unsigned r; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; + return r; +# endif +} + + +/**************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + + + +static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; } + +#define FSE_DECODE_TYPE FSE_decode_t + + +typedef struct { + U16 tableLog; + U16 fastMode; +} FSE_DTableHeader; /* sizeof U32 */ + +static size_t FSE_buildDTable +(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + void* ptr = dt; + FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; + FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*)(ptr) + 1; /* because dt is unsigned, 32-bits aligned on 32-bits */ + const U32 tableSize = 1 << tableLog; + const U32 tableMask = tableSize-1; + const U32 step = FSE_tableStep(tableSize); + U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; + U32 position = 0; + U32 highThreshold = tableSize-1; + const S16 largeLimit= (S16)(1 << (tableLog-1)); + U32 noLarge = 1; + U32 s; + + /* Sanity Checks */ + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return (size_t)-FSE_ERROR_maxSymbolValue_tooLarge; + if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_tableLog_tooLarge; + + /* Init, lay down lowprob symbols */ + DTableH[0].tableLog = (U16)tableLog; + for (s=0; s<=maxSymbolValue; s++) + { + if (normalizedCounter[s]==-1) + { + tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s; + symbolNext[s] = 1; + } + else + { + if (normalizedCounter[s] >= largeLimit) noLarge=0; + symbolNext[s] = normalizedCounter[s]; + } + } + + /* Spread symbols */ + for (s=0; s<=maxSymbolValue; s++) + { + int i; + for (i=0; i highThreshold) position = (position + step) & tableMask; /* lowprob area */ + } + } + + if (position!=0) return (size_t)-FSE_ERROR_GENERIC; /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + + /* Build Decoding table */ + { + U32 i; + for (i=0; ifastMode = (U16)noLarge; + return 0; +} + + +/****************************************** +* FSE byte symbol +******************************************/ +#ifndef FSE_COMMONDEFS_ONLY + +static unsigned FSE_isError(size_t code) { return (code > (size_t)(-FSE_ERROR_maxCode)); } + +static short FSE_abs(short a) +{ + return a<0? -a : a; +} + + +/**************************************************************** +* Header bitstream management +****************************************************************/ +static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + const BYTE* const istart = (const BYTE*) headerBuffer; + const BYTE* const iend = istart + hbSize; + const BYTE* ip = istart; + int nbBits; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + int previous0 = 0; + + if (hbSize < 4) return (size_t)-FSE_ERROR_srcSize_wrong; + bitStream = FSE_readLE32(ip); + nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ + if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return (size_t)-FSE_ERROR_tableLog_tooLarge; + bitStream >>= 4; + bitCount = 4; + *tableLogPtr = nbBits; + remaining = (1<1) && (charnum<=*maxSVPtr)) + { + if (previous0) + { + unsigned n0 = charnum; + while ((bitStream & 0xFFFF) == 0xFFFF) + { + n0+=24; + if (ip < iend-5) + { + ip+=2; + bitStream = FSE_readLE32(ip) >> bitCount; + } + else + { + bitStream >>= 16; + bitCount+=16; + } + } + while ((bitStream & 3) == 3) + { + n0+=3; + bitStream>>=2; + bitCount+=2; + } + n0 += bitStream & 3; + bitCount += 2; + if (n0 > *maxSVPtr) return (size_t)-FSE_ERROR_maxSymbolValue_tooSmall; + while (charnum < n0) normalizedCounter[charnum++] = 0; + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) + { + ip += bitCount>>3; + bitCount &= 7; + bitStream = FSE_readLE32(ip) >> bitCount; + } + else + bitStream >>= 2; + } + { + const short max = (short)((2*threshold-1)-remaining); + short count; + + if ((bitStream & (threshold-1)) < (U32)max) + { + count = (short)(bitStream & (threshold-1)); + bitCount += nbBits-1; + } + else + { + count = (short)(bitStream & (2*threshold-1)); + if (count >= threshold) count -= max; + bitCount += nbBits; + } + + count--; /* extra accuracy */ + remaining -= FSE_abs(count); + normalizedCounter[charnum++] = count; + previous0 = !count; + while (remaining < threshold) + { + nbBits--; + threshold >>= 1; + } + + { + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) + { + ip += bitCount>>3; + bitCount &= 7; + } + else + { + bitCount -= (int)(8 * (iend - 4 - ip)); + ip = iend - 4; + } + bitStream = FSE_readLE32(ip) >> (bitCount & 31); + } + } + } + if (remaining != 1) return (size_t)-FSE_ERROR_GENERIC; + *maxSVPtr = charnum-1; + + ip += (bitCount+7)>>3; + if ((size_t)(ip-istart) > hbSize) return (size_t)-FSE_ERROR_srcSize_wrong; + return ip-istart; +} + + +/********************************************************* +* Decompression (Byte symbols) +*********************************************************/ +static size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue) +{ + void* ptr = dt; + FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; + FSE_decode_t* const cell = (FSE_decode_t*)(ptr) + 1; /* because dt is unsigned */ + + DTableH->tableLog = 0; + DTableH->fastMode = 0; + + cell->newState = 0; + cell->symbol = symbolValue; + cell->nbBits = 0; + + return 0; +} + + +static size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) +{ + void* ptr = dt; + FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; + FSE_decode_t* const dinfo = (FSE_decode_t*)(ptr) + 1; /* because dt is unsigned */ + const unsigned tableSize = 1 << nbBits; + const unsigned tableMask = tableSize - 1; + const unsigned maxSymbolValue = tableMask; + unsigned s; + + /* Sanity checks */ + if (nbBits < 1) return (size_t)-FSE_ERROR_GENERIC; /* min size */ + + /* Build Decoding Table */ + DTableH->tableLog = (U16)nbBits; + DTableH->fastMode = 1; + for (s=0; s<=maxSymbolValue; s++) + { + dinfo[s].newState = 0; + dinfo[s].symbol = (BYTE)s; + dinfo[s].nbBits = (BYTE)nbBits; + } + + return 0; +} + + +/* FSE_initDStream + * Initialize a FSE_DStream_t. + * srcBuffer must point at the beginning of an FSE block. + * The function result is the size of the FSE_block (== srcSize). + * If srcSize is too small, the function will return an errorCode; + */ +static size_t FSE_initDStream(FSE_DStream_t* bitD, const void* srcBuffer, size_t srcSize) +{ + if (srcSize < 1) return (size_t)-FSE_ERROR_srcSize_wrong; + + if (srcSize >= sizeof(size_t)) + { + U32 contain32; + bitD->start = (const char*)srcBuffer; + bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(size_t); + bitD->bitContainer = FSE_readLEST(bitD->ptr); + contain32 = ((const BYTE*)srcBuffer)[srcSize-1]; + if (contain32 == 0) return (size_t)-FSE_ERROR_GENERIC; /* stop bit not present */ + bitD->bitsConsumed = 8 - FSE_highbit32(contain32); + } + else + { + U32 contain32; + bitD->start = (const char*)srcBuffer; + bitD->ptr = bitD->start; + bitD->bitContainer = *(const BYTE*)(bitD->start); + switch(srcSize) + { + case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16); + /* fallthrough */ + case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24); + /* fallthrough */ + case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32); + /* fallthrough */ + case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24; + /* fallthrough */ + case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16; + /* fallthrough */ + case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) << 8; + /* fallthrough */ + default:; + } + contain32 = ((const BYTE*)srcBuffer)[srcSize-1]; + if (contain32 == 0) return (size_t)-FSE_ERROR_GENERIC; /* stop bit not present */ + bitD->bitsConsumed = 8 - FSE_highbit32(contain32); + bitD->bitsConsumed += (U32)(sizeof(size_t) - srcSize)*8; + } + + return srcSize; +} + + +/*!FSE_lookBits + * Provides next n bits from the bitContainer. + * bitContainer is not modified (bits are still present for next read/look) + * On 32-bits, maxNbBits==25 + * On 64-bits, maxNbBits==57 + * return : value extracted. + */ +static size_t FSE_lookBits(FSE_DStream_t* bitD, U32 nbBits) +{ + const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1; + return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask); +} + +static size_t FSE_lookBitsFast(FSE_DStream_t* bitD, U32 nbBits) /* only if nbBits >= 1 !! */ +{ + const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1; + return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask); +} + +static void FSE_skipBits(FSE_DStream_t* bitD, U32 nbBits) +{ + bitD->bitsConsumed += nbBits; +} + + +/*!FSE_readBits + * Read next n bits from the bitContainer. + * On 32-bits, don't read more than maxNbBits==25 + * On 64-bits, don't read more than maxNbBits==57 + * Use the fast variant *only* if n >= 1. + * return : value extracted. + */ +static size_t FSE_readBits(FSE_DStream_t* bitD, U32 nbBits) +{ + size_t value = FSE_lookBits(bitD, nbBits); + FSE_skipBits(bitD, nbBits); + return value; +} + +static size_t FSE_readBitsFast(FSE_DStream_t* bitD, U32 nbBits) /* only if nbBits >= 1 !! */ +{ + size_t value = FSE_lookBitsFast(bitD, nbBits); + FSE_skipBits(bitD, nbBits); + return value; +} + +static unsigned FSE_reloadDStream(FSE_DStream_t* bitD) +{ + if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */ + return FSE_DStream_tooFar; + + if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) + { + bitD->ptr -= bitD->bitsConsumed >> 3; + bitD->bitsConsumed &= 7; + bitD->bitContainer = FSE_readLEST(bitD->ptr); + return FSE_DStream_unfinished; + } + if (bitD->ptr == bitD->start) + { + if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return FSE_DStream_endOfBuffer; + return FSE_DStream_completed; + } + { + U32 nbBytes = bitD->bitsConsumed >> 3; + U32 result = FSE_DStream_unfinished; + if (bitD->ptr - nbBytes < bitD->start) + { + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ + result = FSE_DStream_endOfBuffer; + } + bitD->ptr -= nbBytes; + bitD->bitsConsumed -= nbBytes*8; + bitD->bitContainer = FSE_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */ + return result; + } +} + + +static void FSE_initDState(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD, const FSE_DTable* dt) +{ + const void* ptr = dt; + const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; + DStatePtr->state = FSE_readBits(bitD, DTableH->tableLog); + FSE_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +static BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD) +{ + const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + const U32 nbBits = DInfo.nbBits; + BYTE symbol = DInfo.symbol; + size_t lowBits = FSE_readBits(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +static BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD) +{ + const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + const U32 nbBits = DInfo.nbBits; + BYTE symbol = DInfo.symbol; + size_t lowBits = FSE_readBitsFast(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +/* FSE_endOfDStream + Tells if bitD has reached end of bitStream or not */ + +static unsigned FSE_endOfDStream(const FSE_DStream_t* bitD) +{ + return ((bitD->ptr == bitD->start) && (bitD->bitsConsumed == sizeof(bitD->bitContainer)*8)); +} + +static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) +{ + return DStatePtr->state == 0; +} + + +FORCE_INLINE size_t FSE_decompress_usingDTable_generic( + void* dst, size_t maxDstSize, + const void* cSrc, size_t cSrcSize, + const FSE_DTable* dt, const unsigned fast) +{ + BYTE* const ostart = (BYTE*) dst; + BYTE* op = ostart; + BYTE* const omax = op + maxDstSize; + BYTE* const olimit = omax-3; + + FSE_DStream_t bitD; + FSE_DState_t state1; + FSE_DState_t state2; + size_t errorCode; + + /* Init */ + errorCode = FSE_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */ + if (FSE_isError(errorCode)) return errorCode; + + FSE_initDState(&state1, &bitD, dt); + FSE_initDState(&state2, &bitD, dt); + +#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD) + + /* 4 symbols per loop */ + for ( ; (FSE_reloadDStream(&bitD)==FSE_DStream_unfinished) && (op sizeof(bitD.bitContainer)*8) /* This test must be static */ + FSE_reloadDStream(&bitD); + + op[1] = FSE_GETSYMBOL(&state2); + + if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + { if (FSE_reloadDStream(&bitD) > FSE_DStream_unfinished) { op+=2; break; } } + + op[2] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + FSE_reloadDStream(&bitD); + + op[3] = FSE_GETSYMBOL(&state2); + } + + /* tail */ + /* note : FSE_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly FSE_DStream_completed */ + while (1) + { + if ( (FSE_reloadDStream(&bitD)>FSE_DStream_completed) || (op==omax) || (FSE_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state1))) ) + break; + + *op++ = FSE_GETSYMBOL(&state1); + + if ( (FSE_reloadDStream(&bitD)>FSE_DStream_completed) || (op==omax) || (FSE_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state2))) ) + break; + + *op++ = FSE_GETSYMBOL(&state2); + } + + /* end ? */ + if (FSE_endOfDStream(&bitD) && FSE_endOfDState(&state1) && FSE_endOfDState(&state2)) + return op-ostart; + + if (op==omax) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* dst buffer is full, but cSrc unfinished */ + + return (size_t)-FSE_ERROR_corruptionDetected; +} + + +static size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, + const void* cSrc, size_t cSrcSize, + const FSE_DTable* dt) +{ + FSE_DTableHeader DTableH; + memcpy(&DTableH, dt, sizeof(DTableH)); /* memcpy() into local variable, to avoid strict aliasing warning */ + + /* select fast mode (static) */ + if (DTableH.fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); + return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); +} + + +static size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize) +{ + const BYTE* const istart = (const BYTE*)cSrc; + const BYTE* ip = istart; + short counting[FSE_MAX_SYMBOL_VALUE+1]; + DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + size_t errorCode; + + if (cSrcSize<2) return (size_t)-FSE_ERROR_srcSize_wrong; /* too small input size */ + + /* normal FSE decoding mode */ + errorCode = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + if (FSE_isError(errorCode)) return errorCode; + if (errorCode >= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong; /* too small input size */ + ip += errorCode; + cSrcSize -= errorCode; + + errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog); + if (FSE_isError(errorCode)) return errorCode; + + /* always return, even if it is an error code */ + return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); +} + + + +/* ******************************************************* +* Huff0 : Huffman block compression +*********************************************************/ +#define HUF_MAX_SYMBOL_VALUE 255 +#define HUF_DEFAULT_TABLELOG 12 /* used by default, when not specified */ +#define HUF_MAX_TABLELOG 12 /* max possible tableLog; for allocation purpose; can be modified */ +#define HUF_ABSOLUTEMAX_TABLELOG 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#if (HUF_MAX_TABLELOG > HUF_ABSOLUTEMAX_TABLELOG) +# error "HUF_MAX_TABLELOG is too large !" +#endif + +typedef struct HUF_CElt_s { + U16 val; + BYTE nbBits; +} HUF_CElt ; + +typedef struct nodeElt_s { + U32 count; + U16 parent; + BYTE byte; + BYTE nbBits; +} nodeElt; + + +/* ******************************************************* +* Huff0 : Huffman block decompression +*********************************************************/ +typedef struct { + BYTE byte; + BYTE nbBits; +} HUF_DElt; + +static size_t HUF_readDTable (U16* DTable, const void* src, size_t srcSize) +{ + BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1]; + U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */ + U32 weightTotal; + U32 maxBits; + const BYTE* ip = (const BYTE*) src; + size_t iSize; + size_t oSize; + U32 n; + U32 nextRankStart; + void* ptr = DTable+1; + HUF_DElt* const dt = (HUF_DElt*)ptr; + + if (!srcSize) return (size_t)-FSE_ERROR_srcSize_wrong; + iSize = ip[0]; + + FSE_STATIC_ASSERT(sizeof(HUF_DElt) == sizeof(U16)); /* if compilation fails here, assertion is false */ + //memset(huffWeight, 0, sizeof(huffWeight)); /* should not be necessary, but some analyzer complain ... */ + if (iSize >= 128) /* special header */ + { + if (iSize >= (242)) /* RLE */ + { + static int l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 }; + oSize = l[iSize-242]; + memset(huffWeight, 1, sizeof(huffWeight)); + iSize = 0; + } + else /* Incompressible */ + { + oSize = iSize - 127; + iSize = ((oSize+1)/2); + if (iSize+1 > srcSize) return (size_t)-FSE_ERROR_srcSize_wrong; + ip += 1; + for (n=0; n> 4; + huffWeight[n+1] = ip[n/2] & 15; + } + } + } + else /* header compressed with FSE (normal case) */ + { + if (iSize+1 > srcSize) return (size_t)-FSE_ERROR_srcSize_wrong; + oSize = FSE_decompress(huffWeight, HUF_MAX_SYMBOL_VALUE, ip+1, iSize); /* max 255 values decoded, last one is implied */ + if (FSE_isError(oSize)) return oSize; + } + + /* collect weight stats */ + memset(rankVal, 0, sizeof(rankVal)); + weightTotal = 0; + for (n=0; n= HUF_ABSOLUTEMAX_TABLELOG) return (size_t)-FSE_ERROR_corruptionDetected; + rankVal[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } + if (weightTotal == 0) return (size_t)-FSE_ERROR_corruptionDetected; + + /* get last non-null symbol weight (implied, total must be 2^n) */ + maxBits = FSE_highbit32(weightTotal) + 1; + if (maxBits > DTable[0]) return (size_t)-FSE_ERROR_tableLog_tooLarge; /* DTable is too small */ + DTable[0] = (U16)maxBits; + { + U32 total = 1 << maxBits; + U32 rest = total - weightTotal; + U32 verif = 1 << FSE_highbit32(rest); + U32 lastWeight = FSE_highbit32(rest) + 1; + if (verif != rest) return (size_t)-FSE_ERROR_corruptionDetected; /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankVal[lastWeight]++; + } + + /* check tree construction validity */ + if ((rankVal[1] < 2) || (rankVal[1] & 1)) return (size_t)-FSE_ERROR_corruptionDetected; /* by construction : at least 2 elts of rank 1, must be even */ + + /* Prepare ranks */ + nextRankStart = 0; + for (n=1; n<=maxBits; n++) + { + U32 current = nextRankStart; + nextRankStart += (rankVal[n] << (n-1)); + rankVal[n] = current; + } + + /* fill DTable */ + for (n=0; n<=oSize; n++) + { + const U32 w = huffWeight[n]; + const U32 length = (1 << w) >> 1; + U32 i; + HUF_DElt D; + D.byte = (BYTE)n; D.nbBits = (BYTE)(maxBits + 1 - w); + for (i = rankVal[w]; i < rankVal[w] + length; i++) + dt[i] = D; + rankVal[w] += length; + } + + return iSize+1; +} + + +static BYTE HUF_decodeSymbol(FSE_DStream_t* Dstream, const HUF_DElt* dt, const U32 dtLog) +{ + const size_t val = FSE_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ + const BYTE c = dt[val].byte; + FSE_skipBits(Dstream, dt[val].nbBits); + return c; +} + +static size_t HUF_decompress_usingDTable( /* -3% slower when non static */ + void* dst, size_t maxDstSize, + const void* cSrc, size_t cSrcSize, + const U16* DTable) +{ + if (cSrcSize < 6) return (size_t)-FSE_ERROR_srcSize_wrong; + { + BYTE* const ostart = (BYTE*) dst; + BYTE* op = ostart; + BYTE* const omax = op + maxDstSize; + BYTE* const olimit = maxDstSize < 15 ? op : omax-15; + + const void* ptr = DTable; + const HUF_DElt* const dt = (const HUF_DElt*)(ptr)+1; + const U32 dtLog = DTable[0]; + size_t errorCode; + U32 reloadStatus; + + /* Init */ + + const U16* jumpTable = (const U16*)cSrc; + const size_t length1 = FSE_readLE16(jumpTable); + const size_t length2 = FSE_readLE16(jumpTable+1); + const size_t length3 = FSE_readLE16(jumpTable+2); + const size_t length4 = cSrcSize - 6 - length1 - length2 - length3; /* check coherency !! */ + const char* const start1 = (const char*)(cSrc) + 6; + const char* const start2 = start1 + length1; + const char* const start3 = start2 + length2; + const char* const start4 = start3 + length3; + FSE_DStream_t bitD1, bitD2, bitD3, bitD4; + + if (length1+length2+length3+6 >= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong; + + errorCode = FSE_initDStream(&bitD1, start1, length1); + if (FSE_isError(errorCode)) return errorCode; + errorCode = FSE_initDStream(&bitD2, start2, length2); + if (FSE_isError(errorCode)) return errorCode; + errorCode = FSE_initDStream(&bitD3, start3, length3); + if (FSE_isError(errorCode)) return errorCode; + errorCode = FSE_initDStream(&bitD4, start4, length4); + if (FSE_isError(errorCode)) return errorCode; + + reloadStatus=FSE_reloadDStream(&bitD2); + + /* 16 symbols per loop */ + for ( ; (reloadStatus12)) FSE_reloadDStream(&Dstream) + + #define HUF_DECODE_SYMBOL_2(n, Dstream) \ + op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog); \ + if (FSE_32bits()) FSE_reloadDStream(&Dstream) + + HUF_DECODE_SYMBOL_1( 0, bitD1); + HUF_DECODE_SYMBOL_1( 1, bitD2); + HUF_DECODE_SYMBOL_1( 2, bitD3); + HUF_DECODE_SYMBOL_1( 3, bitD4); + HUF_DECODE_SYMBOL_2( 4, bitD1); + HUF_DECODE_SYMBOL_2( 5, bitD2); + HUF_DECODE_SYMBOL_2( 6, bitD3); + HUF_DECODE_SYMBOL_2( 7, bitD4); + HUF_DECODE_SYMBOL_1( 8, bitD1); + HUF_DECODE_SYMBOL_1( 9, bitD2); + HUF_DECODE_SYMBOL_1(10, bitD3); + HUF_DECODE_SYMBOL_1(11, bitD4); + HUF_DECODE_SYMBOL_0(12, bitD1); + HUF_DECODE_SYMBOL_0(13, bitD2); + HUF_DECODE_SYMBOL_0(14, bitD3); + HUF_DECODE_SYMBOL_0(15, bitD4); + } + + if (reloadStatus!=FSE_DStream_completed) /* not complete : some bitStream might be FSE_DStream_unfinished */ + return (size_t)-FSE_ERROR_corruptionDetected; + + /* tail */ + { + /* bitTail = bitD1; */ /* *much* slower : -20% !??! */ + FSE_DStream_t bitTail; + bitTail.ptr = bitD1.ptr; + bitTail.bitsConsumed = bitD1.bitsConsumed; + bitTail.bitContainer = bitD1.bitContainer; /* required in case of FSE_DStream_endOfBuffer */ + bitTail.start = start1; + for ( ; (FSE_reloadDStream(&bitTail) < FSE_DStream_completed) && (op= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong; + ip += errorCode; + cSrcSize -= errorCode; + + return HUF_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, DTable); +} + + +#endif /* FSE_COMMONDEFS_ONLY */ + +/* + zstd - standard compression library + Copyright (C) 2014-2015, Yann Collet. + + BSD 2-Clause License (https://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 : + - zstd source repository : https://github.com/Cyan4973/zstd + - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c +*/ + +/**************************************************************** +* Tuning parameters +*****************************************************************/ +/* MEMORY_USAGE : +* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect */ +#define ZSTD_MEMORY_USAGE 17 + + +/************************************** + CPU Feature Detection +**************************************/ +/* + * Automated efficient unaligned memory access detection + * Based on known hardware architectures + * This list will be updated thanks to feedbacks + */ +#if defined(CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS) \ + || defined(__ARM_FEATURE_UNALIGNED) \ + || defined(__i386__) || defined(__x86_64__) \ + || defined(_M_IX86) || defined(_M_X64) \ + || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) \ + || (defined(_M_ARM) && (_M_ARM >= 7)) +# define ZSTD_UNALIGNED_ACCESS 1 +#else +# define ZSTD_UNALIGNED_ACCESS 0 +#endif + + +/******************************************************** +* Includes +*********************************************************/ +#include /* calloc */ +#include /* memcpy, memmove */ +#include /* debug : printf */ + + +/******************************************************** +* Compiler specifics +*********************************************************/ +#ifdef __AVX2__ +# include /* AVX2 intrinsics */ +#endif + +#ifdef _MSC_VER /* Visual Studio */ +# include /* For Visual 2005 */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4324) /* disable: C4324: padded structure */ +#endif + + +#ifndef MEM_ACCESS_MODULE +#define MEM_ACCESS_MODULE +/******************************************************** +* Basic Types +*********************************************************/ +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# if defined(_AIX) +# include +# else +# include /* intptr_t */ +# endif +typedef uint8_t BYTE; +typedef uint16_t U16; +typedef int16_t S16; +typedef uint32_t U32; +typedef int32_t S32; +typedef uint64_t U64; +#else +typedef unsigned char BYTE; +typedef unsigned short U16; +typedef signed short S16; +typedef unsigned int U32; +typedef signed int S32; +typedef unsigned long long U64; +#endif + +#endif /* MEM_ACCESS_MODULE */ + + +/******************************************************** +* Constants +*********************************************************/ +static const U32 ZSTD_magicNumber = 0xFD2FB51E; /* 3rd version : seqNb header */ + +#define HASH_LOG (ZSTD_MEMORY_USAGE - 2) +#define HASH_TABLESIZE (1 << HASH_LOG) +#define HASH_MASK (HASH_TABLESIZE - 1) + +#define KNUTH 2654435761 + +#define BIT7 128 +#define BIT6 64 +#define BIT5 32 +#define BIT4 16 + +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +#define BLOCKSIZE (128 KB) /* define, for static allocation */ + +#define WORKPLACESIZE (BLOCKSIZE*3) +#define MINMATCH 4 +#define MLbits 7 +#define LLbits 6 +#define Offbits 5 +#define MaxML ((1<>3]; +#else + U32 hashTable[HASH_TABLESIZE]; +#endif + BYTE buffer[WORKPLACESIZE]; +} cctxi_t; + + + + +/************************************** +* Error Management +**************************************/ +/* published entry point */ +unsigned ZSTDv01_isError(size_t code) { return ERR_isError(code); } + + +/************************************** +* Tool functions +**************************************/ +#define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */ +#define ZSTD_VERSION_MINOR 1 /* for new (non-breaking) interface capabilities */ +#define ZSTD_VERSION_RELEASE 3 /* for tweaks, bug-fixes, or development */ +#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) + +/************************************************************** +* Decompression code +**************************************************************/ + +static size_t ZSTDv01_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr) +{ + const BYTE* const in = (const BYTE* const)src; + BYTE headerFlags; + U32 cSize; + + if (srcSize < 3) return ERROR(srcSize_wrong); + + headerFlags = *in; + cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16); + + bpPtr->blockType = (blockType_t)(headerFlags >> 6); + bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0; + + if (bpPtr->blockType == bt_end) return 0; + if (bpPtr->blockType == bt_rle) return 1; + return cSize; +} + + +static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize) +{ + if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall); + if (srcSize > 0) { + memcpy(dst, src, srcSize); + } + return srcSize; +} + + +static size_t ZSTD_decompressLiterals(void* ctx, + void* dst, size_t maxDstSize, + const void* src, size_t srcSize) +{ + BYTE* op = (BYTE*)dst; + BYTE* const oend = op + maxDstSize; + const BYTE* ip = (const BYTE*)src; + size_t errorCode; + size_t litSize; + + /* check : minimum 2, for litSize, +1, for content */ + if (srcSize <= 3) return ERROR(corruption_detected); + + litSize = ip[1] + (ip[0]<<8); + litSize += ((ip[-3] >> 3) & 7) << 16; /* mmmmh.... */ + op = oend - litSize; + + (void)ctx; + if (litSize > maxDstSize) return ERROR(dstSize_tooSmall); + errorCode = HUF_decompress(op, litSize, ip+2, srcSize-2); + if (FSE_isError(errorCode)) return ERROR(GENERIC); + return litSize; +} + + +static size_t ZSTDv01_decodeLiteralsBlock(void* ctx, + void* dst, size_t maxDstSize, + const BYTE** litStart, size_t* litSize, + const void* src, size_t srcSize) +{ + const BYTE* const istart = (const BYTE* const)src; + const BYTE* ip = istart; + BYTE* const ostart = (BYTE* const)dst; + BYTE* const oend = ostart + maxDstSize; + blockProperties_t litbp; + + size_t litcSize = ZSTDv01_getcBlockSize(src, srcSize, &litbp); + if (ZSTDv01_isError(litcSize)) return litcSize; + if (litcSize > srcSize - ZSTD_blockHeaderSize) return ERROR(srcSize_wrong); + ip += ZSTD_blockHeaderSize; + + switch(litbp.blockType) + { + case bt_raw: + *litStart = ip; + ip += litcSize; + *litSize = litcSize; + break; + case bt_rle: + { + size_t rleSize = litbp.origSize; + if (rleSize>maxDstSize) return ERROR(dstSize_tooSmall); + if (!srcSize) return ERROR(srcSize_wrong); + if (rleSize > 0) { + memset(oend - rleSize, *ip, rleSize); + } + *litStart = oend - rleSize; + *litSize = rleSize; + ip++; + break; + } + case bt_compressed: + { + size_t decodedLitSize = ZSTD_decompressLiterals(ctx, dst, maxDstSize, ip, litcSize); + if (ZSTDv01_isError(decodedLitSize)) return decodedLitSize; + *litStart = oend - decodedLitSize; + *litSize = decodedLitSize; + ip += litcSize; + break; + } + case bt_end: + default: + return ERROR(GENERIC); + } + + return ip-istart; +} + + +static size_t ZSTDv01_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr, + FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb, + const void* src, size_t srcSize) +{ + const BYTE* const istart = (const BYTE* const)src; + const BYTE* ip = istart; + const BYTE* const iend = istart + srcSize; + U32 LLtype, Offtype, MLtype; + U32 LLlog, Offlog, MLlog; + size_t dumpsLength; + + /* check */ + if (srcSize < 5) return ERROR(srcSize_wrong); + + /* SeqHead */ + *nbSeq = ZSTD_readLE16(ip); ip+=2; + LLtype = *ip >> 6; + Offtype = (*ip >> 4) & 3; + MLtype = (*ip >> 2) & 3; + if (*ip & 2) + { + dumpsLength = ip[2]; + dumpsLength += ip[1] << 8; + ip += 3; + } + else + { + dumpsLength = ip[1]; + dumpsLength += (ip[0] & 1) << 8; + ip += 2; + } + *dumpsPtr = ip; + ip += dumpsLength; + *dumpsLengthPtr = dumpsLength; + + /* check */ + if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */ + + /* sequences */ + { + S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL and MaxOff */ + size_t headerSize; + + /* Build DTables */ + switch(LLtype) + { + case bt_rle : + LLlog = 0; + FSE_buildDTable_rle(DTableLL, *ip++); break; + case bt_raw : + LLlog = LLbits; + FSE_buildDTable_raw(DTableLL, LLbits); break; + default : + { U32 max = MaxLL; + headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip); + if (FSE_isError(headerSize)) return ERROR(GENERIC); + if (LLlog > LLFSELog) return ERROR(corruption_detected); + ip += headerSize; + FSE_buildDTable(DTableLL, norm, max, LLlog); + } } + + switch(Offtype) + { + case bt_rle : + Offlog = 0; + if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */ + FSE_buildDTable_rle(DTableOffb, *ip++); break; + case bt_raw : + Offlog = Offbits; + FSE_buildDTable_raw(DTableOffb, Offbits); break; + default : + { U32 max = MaxOff; + headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip); + if (FSE_isError(headerSize)) return ERROR(GENERIC); + if (Offlog > OffFSELog) return ERROR(corruption_detected); + ip += headerSize; + FSE_buildDTable(DTableOffb, norm, max, Offlog); + } } + + switch(MLtype) + { + case bt_rle : + MLlog = 0; + if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */ + FSE_buildDTable_rle(DTableML, *ip++); break; + case bt_raw : + MLlog = MLbits; + FSE_buildDTable_raw(DTableML, MLbits); break; + default : + { U32 max = MaxML; + headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip); + if (FSE_isError(headerSize)) return ERROR(GENERIC); + if (MLlog > MLFSELog) return ERROR(corruption_detected); + ip += headerSize; + FSE_buildDTable(DTableML, norm, max, MLlog); + } } } + + return ip-istart; +} + + +typedef struct { + size_t litLength; + size_t offset; + size_t matchLength; +} seq_t; + +typedef struct { + FSE_DStream_t DStream; + FSE_DState_t stateLL; + FSE_DState_t stateOffb; + FSE_DState_t stateML; + size_t prevOffset; + const BYTE* dumps; + const BYTE* dumpsEnd; +} seqState_t; + + +static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) +{ + size_t litLength; + size_t prevOffset; + size_t offset; + size_t matchLength; + const BYTE* dumps = seqState->dumps; + const BYTE* const de = seqState->dumpsEnd; + + /* Literal length */ + litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); + prevOffset = litLength ? seq->offset : seqState->prevOffset; + seqState->prevOffset = seq->offset; + if (litLength == MaxLL) + { + const U32 add = dumpsstateOffb), &(seqState->DStream)); + if (ZSTD_32bits()) FSE_reloadDStream(&(seqState->DStream)); + nbBits = offsetCode - 1; + if (offsetCode==0) nbBits = 0; /* cmove */ + offset = ((size_t)1 << (nbBits & ((sizeof(offset)*8)-1))) + FSE_readBits(&(seqState->DStream), nbBits); + if (ZSTD_32bits()) FSE_reloadDStream(&(seqState->DStream)); + if (offsetCode==0) offset = prevOffset; + } + + /* MatchLength */ + matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream)); + if (matchLength == MaxML) + { + const U32 add = dumpslitLength = litLength; + seq->offset = offset; + seq->matchLength = matchLength; + seqState->dumps = dumps; +} + + +static size_t ZSTD_execSequence(BYTE* op, + seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + BYTE* const base, BYTE* const oend) +{ + static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */ + static const int dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* subtracted */ + const BYTE* const ostart = op; + BYTE* const oLitEnd = op + sequence.litLength; + const size_t litLength = sequence.litLength; + BYTE* const endMatch = op + litLength + sequence.matchLength; /* risk : address space overflow (32-bits) */ + const BYTE* const litEnd = *litPtr + litLength; + + /* checks */ + size_t const seqLength = sequence.litLength + sequence.matchLength; + + if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall); + if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected); + /* Now we know there are no overflow in literal nor match lengths, can use pointer checks */ + if (sequence.offset > (U32)(oLitEnd - base)) return ERROR(corruption_detected); + + if (endMatch > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ + if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */ + if (sequence.matchLength > (size_t)(*litPtr-op)) return ERROR(dstSize_tooSmall); /* overwrite literal segment */ + + /* copy Literals */ + ZSTD_memmove(op, *litPtr, sequence.litLength); /* note : v0.1 seems to allow scenarios where output or input are close to end of buffer */ + + op += litLength; + *litPtr = litEnd; /* update for next sequence */ + + /* check : last match must be at a minimum distance of 8 from end of dest buffer */ + if (oend-op < 8) return ERROR(dstSize_tooSmall); + + /* copy Match */ + { + const U32 overlapRisk = (((size_t)(litEnd - endMatch)) < 12); + const BYTE* match = op - sequence.offset; /* possible underflow at op - offset ? */ + size_t qutt = 12; + U64 saved[2]; + + /* check */ + if (match < base) return ERROR(corruption_detected); + if (sequence.offset > (size_t)base) return ERROR(corruption_detected); + + /* save beginning of literal sequence, in case of write overlap */ + if (overlapRisk) + { + if ((endMatch + qutt) > oend) qutt = oend-endMatch; + memcpy(saved, endMatch, qutt); + } + + if (sequence.offset < 8) + { + const int dec64 = dec64table[sequence.offset]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[sequence.offset]; + ZSTD_copy4(op+4, match); + match -= dec64; + } else { ZSTD_copy8(op, match); } + op += 8; match += 8; + + if (endMatch > oend-(16-MINMATCH)) + { + if (op < oend-8) + { + ZSTD_wildcopy(op, match, (oend-8) - op); + match += (oend-8) - op; + op = oend-8; + } + while (opLLTable; + U32* DTableML = dctx->MLTable; + U32* DTableOffb = dctx->OffTable; + BYTE* const base = (BYTE*) (dctx->base); + + /* Build Decoding Tables */ + errorCode = ZSTDv01_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength, + DTableLL, DTableML, DTableOffb, + ip, iend-ip); + if (ZSTDv01_isError(errorCode)) return errorCode; + ip += errorCode; + + /* Regen sequences */ + { + seq_t sequence; + seqState_t seqState; + + memset(&sequence, 0, sizeof(sequence)); + seqState.dumps = dumps; + seqState.dumpsEnd = dumps + dumpsLength; + seqState.prevOffset = 1; + errorCode = FSE_initDStream(&(seqState.DStream), ip, iend-ip); + if (FSE_isError(errorCode)) return ERROR(corruption_detected); + FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL); + FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb); + FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML); + + for ( ; (FSE_reloadDStream(&(seqState.DStream)) <= FSE_DStream_completed) && (nbSeq>0) ; ) + { + size_t oneSeqSize; + nbSeq--; + ZSTD_decodeSequence(&sequence, &seqState); + oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litEnd, base, oend); + if (ZSTDv01_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } + + /* check if reached exact end */ + if ( !FSE_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* requested too much : data is corrupted */ + if (nbSeq<0) return ERROR(corruption_detected); /* requested too many sequences : data is corrupted */ + + /* last literal segment */ + { + size_t lastLLSize = litEnd - litPtr; + if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall); + if (lastLLSize > 0) { + if (op != litPtr) memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + } + } + + return op-ostart; +} + + +static size_t ZSTD_decompressBlock( + void* ctx, + void* dst, size_t maxDstSize, + const void* src, size_t srcSize) +{ + /* blockType == blockCompressed, srcSize is trusted */ + const BYTE* ip = (const BYTE*)src; + const BYTE* litPtr = NULL; + size_t litSize = 0; + size_t errorCode; + + /* Decode literals sub-block */ + errorCode = ZSTDv01_decodeLiteralsBlock(ctx, dst, maxDstSize, &litPtr, &litSize, src, srcSize); + if (ZSTDv01_isError(errorCode)) return errorCode; + ip += errorCode; + srcSize -= errorCode; + + return ZSTD_decompressSequences(ctx, dst, maxDstSize, ip, srcSize, litPtr, litSize); +} + + +size_t ZSTDv01_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize) +{ + const BYTE* ip = (const BYTE*)src; + const BYTE* iend = ip + srcSize; + BYTE* const ostart = (BYTE* const)dst; + BYTE* op = ostart; + BYTE* const oend = ostart + maxDstSize; + size_t remainingSize = srcSize; + U32 magicNumber; + size_t errorCode=0; + blockProperties_t blockProperties; + + /* Frame Header */ + if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong); + magicNumber = ZSTD_readBE32(src); + if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown); + ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize; + + /* Loop on each block */ + while (1) + { + size_t blockSize = ZSTDv01_getcBlockSize(ip, iend-ip, &blockProperties); + if (ZSTDv01_isError(blockSize)) return blockSize; + + ip += ZSTD_blockHeaderSize; + remainingSize -= ZSTD_blockHeaderSize; + if (blockSize > remainingSize) return ERROR(srcSize_wrong); + + switch(blockProperties.blockType) + { + case bt_compressed: + errorCode = ZSTD_decompressBlock(ctx, op, oend-op, ip, blockSize); + break; + case bt_raw : + errorCode = ZSTD_copyUncompressedBlock(op, oend-op, ip, blockSize); + break; + case bt_rle : + return ERROR(GENERIC); /* not yet supported */ + break; + case bt_end : + /* end of frame */ + if (remainingSize) return ERROR(srcSize_wrong); + break; + default: + return ERROR(GENERIC); + } + if (blockSize == 0) break; /* bt_end */ + + if (ZSTDv01_isError(errorCode)) return errorCode; + op += errorCode; + ip += blockSize; + remainingSize -= blockSize; + } + + return op-ostart; +} + +size_t ZSTDv01_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize) +{ + dctx_t ctx; + ctx.base = dst; + return ZSTDv01_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize); +} + +/* ZSTD_errorFrameSizeInfoLegacy() : + assumes `cSize` and `dBound` are _not_ NULL */ +static void ZSTD_errorFrameSizeInfoLegacy(size_t* cSize, unsigned long long* dBound, size_t ret) +{ + *cSize = ret; + *dBound = ZSTD_CONTENTSIZE_ERROR; +} + +void ZSTDv01_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cSize, unsigned long long* dBound) +{ + const BYTE* ip = (const BYTE*)src; + size_t remainingSize = srcSize; + size_t nbBlocks = 0; + U32 magicNumber; + blockProperties_t blockProperties; + + /* Frame Header */ + if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong)); + return; + } + magicNumber = ZSTD_readBE32(src); + if (magicNumber != ZSTD_magicNumber) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(prefix_unknown)); + return; + } + ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize; + + /* Loop on each block */ + while (1) + { + size_t blockSize = ZSTDv01_getcBlockSize(ip, remainingSize, &blockProperties); + if (ZSTDv01_isError(blockSize)) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, blockSize); + return; + } + + ip += ZSTD_blockHeaderSize; + remainingSize -= ZSTD_blockHeaderSize; + if (blockSize > remainingSize) { + ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong)); + return; + } + + if (blockSize == 0) break; /* bt_end */ + + ip += blockSize; + remainingSize -= blockSize; + nbBlocks++; + } + + *cSize = ip - (const BYTE*)src; + *dBound = nbBlocks * BLOCKSIZE; +} + +/******************************* +* Streaming Decompression API +*******************************/ + +size_t ZSTDv01_resetDCtx(ZSTDv01_Dctx* dctx) +{ + dctx->expected = ZSTD_frameHeaderSize; + dctx->phase = 0; + dctx->previousDstEnd = NULL; + dctx->base = NULL; + return 0; +} + +ZSTDv01_Dctx* ZSTDv01_createDCtx(void) +{ + ZSTDv01_Dctx* dctx = (ZSTDv01_Dctx*)malloc(sizeof(ZSTDv01_Dctx)); + if (dctx==NULL) return NULL; + ZSTDv01_resetDCtx(dctx); + return dctx; +} + +size_t ZSTDv01_freeDCtx(ZSTDv01_Dctx* dctx) +{ + free(dctx); + return 0; +} + +size_t ZSTDv01_nextSrcSizeToDecompress(ZSTDv01_Dctx* dctx) +{ + return ((dctx_t*)dctx)->expected; +} + +size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize) +{ + dctx_t* ctx = (dctx_t*)dctx; + + /* Sanity check */ + if (srcSize != ctx->expected) return ERROR(srcSize_wrong); + if (dst != ctx->previousDstEnd) /* not contiguous */ + ctx->base = dst; + + /* Decompress : frame header */ + if (ctx->phase == 0) + { + /* Check frame magic header */ + U32 magicNumber = ZSTD_readBE32(src); + if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown); + ctx->phase = 1; + ctx->expected = ZSTD_blockHeaderSize; + return 0; + } + + /* Decompress : block header */ + if (ctx->phase == 1) + { + blockProperties_t bp; + size_t blockSize = ZSTDv01_getcBlockSize(src, ZSTD_blockHeaderSize, &bp); + if (ZSTDv01_isError(blockSize)) return blockSize; + if (bp.blockType == bt_end) + { + ctx->expected = 0; + ctx->phase = 0; + } + else + { + ctx->expected = blockSize; + ctx->bType = bp.blockType; + ctx->phase = 2; + } + + return 0; + } + + /* Decompress : block content */ + { + size_t rSize; + switch(ctx->bType) + { + case bt_compressed: + rSize = ZSTD_decompressBlock(ctx, dst, maxDstSize, src, srcSize); + break; + case bt_raw : + rSize = ZSTD_copyUncompressedBlock(dst, maxDstSize, src, srcSize); + break; + case bt_rle : + return ERROR(GENERIC); /* not yet handled */ + break; + case bt_end : /* should never happen (filtered at phase 1) */ + rSize = 0; + break; + default: + return ERROR(GENERIC); + } + ctx->phase = 1; + ctx->expected = ZSTD_blockHeaderSize; + if (ZSTDv01_isError(rSize)) return rSize; + ctx->previousDstEnd = (void*)( ((char*)dst) + rSize); + return rSize; + } + +} diff --git a/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v01.h b/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v01.h new file mode 100644 index 000000000..6ac876954 --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v01.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_V01_H_28739879432 +#define ZSTD_V01_H_28739879432 + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ************************************* +* Includes +***************************************/ +#include /* size_t */ + + +/* ************************************* +* Simple one-step function +***************************************/ +/** +ZSTDv01_decompress() : decompress ZSTD frames compliant with v0.1.x format + compressedSize : is the exact source size + maxOriginalSize : is the size of the 'dst' buffer, which must be already allocated. + It must be equal or larger than originalSize, otherwise decompression will fail. + return : the number of bytes decompressed into destination buffer (originalSize) + or an errorCode if it fails (which can be tested using ZSTDv01_isError()) +*/ +size_t ZSTDv01_decompress( void* dst, size_t maxOriginalSize, + const void* src, size_t compressedSize); + + /** + ZSTDv01_findFrameSizeInfoLegacy() : get the source length and decompressed bound of a ZSTD frame compliant with v0.1.x format + srcSize : The size of the 'src' buffer, at least as large as the frame pointed to by 'src' + cSize (output parameter) : the number of bytes that would be read to decompress this frame + or an error code if it fails (which can be tested using ZSTDv01_isError()) + dBound (output parameter) : an upper-bound for the decompressed size of the data in the frame + or ZSTD_CONTENTSIZE_ERROR if an error occurs + + note : assumes `cSize` and `dBound` are _not_ NULL. + */ +void ZSTDv01_findFrameSizeInfoLegacy(const void *src, size_t srcSize, + size_t* cSize, unsigned long long* dBound); + +/** +ZSTDv01_isError() : tells if the result of ZSTDv01_decompress() is an error +*/ +unsigned ZSTDv01_isError(size_t code); + + +/* ************************************* +* Advanced functions +***************************************/ +typedef struct ZSTDv01_Dctx_s ZSTDv01_Dctx; +ZSTDv01_Dctx* ZSTDv01_createDCtx(void); +size_t ZSTDv01_freeDCtx(ZSTDv01_Dctx* dctx); + +size_t ZSTDv01_decompressDCtx(void* ctx, + void* dst, size_t maxOriginalSize, + const void* src, size_t compressedSize); + +/* ************************************* +* Streaming functions +***************************************/ +size_t ZSTDv01_resetDCtx(ZSTDv01_Dctx* dctx); + +size_t ZSTDv01_nextSrcSizeToDecompress(ZSTDv01_Dctx* dctx); +size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize); +/** + Use above functions alternatively. + ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue(). + ZSTD_decompressContinue() will use previous data blocks to improve compression if they are located prior to current block. + Result is the number of bytes regenerated within 'dst'. + It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header. +*/ + +/* ************************************* +* Prefix - version detection +***************************************/ +#define ZSTDv01_magicNumber 0xFD2FB51E /* Big Endian version */ +#define ZSTDv01_magicNumberLE 0x1EB52FFD /* Little Endian version */ + + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_V01_H_28739879432 */ diff --git a/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v02.c b/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v02.c new file mode 100644 index 000000000..d1e00385a --- /dev/null +++ b/cpp/third_party/zstd-1.5.7/lib/legacy/zstd_v02.c @@ -0,0 +1,3465 @@ +/* + * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#include /* size_t, ptrdiff_t */ +#include "zstd_v02.h" +#include "../common/compiler.h" +#include "../common/error_private.h" + + +/****************************************** +* Compiler-specific +******************************************/ +#if defined(_MSC_VER) /* Visual Studio */ +# include /* _byteswap_ulong */ +# include /* _byteswap_* */ +#endif + + +/* ****************************************************************** + mem.h + low-level memory access routines + Copyright (C) 2013-2015, Yann Collet. + + BSD 2-Clause License (https://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 : + - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ +#ifndef MEM_H_MODULE +#define MEM_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + +/****************************************** +* Includes +******************************************/ +#include /* size_t, ptrdiff_t */ +#include /* memcpy */ + + +/**************************************************************** +* Basic Types +*****************************************************************/ +#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# if defined(_AIX) +# include +# else +# include /* intptr_t */ +# endif + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef int16_t S16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; + typedef int64_t S64; +#else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef signed short S16; + typedef unsigned int U32; + typedef signed int S32; + typedef unsigned long long U64; + typedef signed long long S64; +#endif + + +/**************************************************************** +* Memory I/O +*****************************************************************/ + +MEM_STATIC unsigned MEM_32bits(void) { return sizeof(void*)==4; } +MEM_STATIC unsigned MEM_64bits(void) { return sizeof(void*)==8; } + +MEM_STATIC unsigned MEM_isLittleEndian(void) +{ + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +} + +MEM_STATIC U16 MEM_read16(const void* memPtr) +{ + U16 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U32 MEM_read32(const void* memPtr) +{ + U32 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U64 MEM_read64(const void* memPtr) +{ + U64 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC U16 MEM_readLE16(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read16(memPtr); + else + { + const BYTE* p = (const BYTE*)memPtr; + return (U16)(p[0] + (p[1]<<8)); + } +} + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) +{ + if (MEM_isLittleEndian()) + { + MEM_write16(memPtr, val); + } + else + { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE)val; + p[1] = (BYTE)(val>>8); + } +} + +MEM_STATIC U32 MEM_readLE24(const void* memPtr) +{ + return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16); +} + +MEM_STATIC U32 MEM_readLE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read32(memPtr); + else + { + const BYTE* p = (const BYTE*)memPtr; + return (U32)((U32)p[0] + ((U32)p[1]<<8) + ((U32)p[2]<<16) + ((U32)p[3]<<24)); + } +} + + +MEM_STATIC U64 MEM_readLE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read64(memPtr); + else + { + const BYTE* p = (const BYTE*)memPtr; + return (U64)((U64)p[0] + ((U64)p[1]<<8) + ((U64)p[2]<<16) + ((U64)p[3]<<24) + + ((U64)p[4]<<32) + ((U64)p[5]<<40) + ((U64)p[6]<<48) + ((U64)p[7]<<56)); + } +} + + +MEM_STATIC size_t MEM_readLEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readLE32(memPtr); + else + return (size_t)MEM_readLE64(memPtr); +} + +#if defined (__cplusplus) +} +#endif + +#endif /* MEM_H_MODULE */ + + +/* ****************************************************************** + bitstream + Part of NewGen Entropy library + header file (to include) + Copyright (C) 2013-2015, Yann Collet. + + BSD 2-Clause License (https://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 : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ +#ifndef BITSTREAM_H_MODULE +#define BITSTREAM_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* +* This API consists of small unitary functions, which highly benefit from being inlined. +* Since link-time-optimization is not available for all compilers, +* these functions are defined into a .h to be included. +*/ + + +/********************************************** +* bitStream decompression API (read backward) +**********************************************/ +typedef struct +{ + size_t bitContainer; + unsigned bitsConsumed; + const char* ptr; + const char* start; +} BIT_DStream_t; + +typedef enum { BIT_DStream_unfinished = 0, + BIT_DStream_endOfBuffer = 1, + BIT_DStream_completed = 2, + BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */ + /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ + +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); +MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); + + +/****************************************** +* unsafe API +******************************************/ +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); +/* faster, but works only if nbBits >= 1 */ + + + +/**************************************************************** +* Helper functions +****************************************************************/ +MEM_STATIC unsigned BIT_highbit32 (U32 val) +{ +# if defined(_MSC_VER) /* Visual */ + unsigned long r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; +# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ + return __builtin_clz (val) ^ 31; +# else /* Software version */ + static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; + U32 v = val; + unsigned r; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; + return r; +# endif +} + + + +/********************************************************** +* bitStream decoding +**********************************************************/ + +/*!BIT_initDStream +* Initialize a BIT_DStream_t. +* @bitD : a pointer to an already allocated BIT_DStream_t structure +* @srcBuffer must point at the beginning of a bitStream +* @srcSize must be the exact size of the bitStream +* @result : size of stream (== srcSize) or an errorCode if a problem is detected +*/ +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) +{ + if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } + + if (srcSize >= sizeof(size_t)) /* normal case */ + { + U32 contain32; + bitD->start = (const char*)srcBuffer; + bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(size_t); + bitD->bitContainer = MEM_readLEST(bitD->ptr); + contain32 = ((const BYTE*)srcBuffer)[srcSize-1]; + if (contain32 == 0) return ERROR(GENERIC); /* endMark not present */ + bitD->bitsConsumed = 8 - BIT_highbit32(contain32); + } + else + { + U32 contain32; + bitD->start = (const char*)srcBuffer; + bitD->ptr = bitD->start; + bitD->bitContainer = *(const BYTE*)(bitD->start); + switch(srcSize) + { + case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16); + /* fallthrough */ + case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24); + /* fallthrough */ + case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32); + /* fallthrough */ + case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24; + /* fallthrough */ + case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16; + /* fallthrough */ + case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) << 8; + /* fallthrough */ + default:; + } + contain32 = ((const BYTE*)srcBuffer)[srcSize-1]; + if (contain32 == 0) return ERROR(GENERIC); /* endMark not present */ + bitD->bitsConsumed = 8 - BIT_highbit32(contain32); + bitD->bitsConsumed += (U32)(sizeof(size_t) - srcSize)*8; + } + + return srcSize; +} + +MEM_STATIC size_t BIT_lookBits(BIT_DStream_t* bitD, U32 nbBits) +{ + const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1; + return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask); +} + +/*! BIT_lookBitsFast : +* unsafe version; only works if nbBits >= 1 */ +MEM_STATIC size_t BIT_lookBitsFast(BIT_DStream_t* bitD, U32 nbBits) +{ + const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1; + return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask); +} + +MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +{ + bitD->bitsConsumed += nbBits; +} + +MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits) +{ + size_t value = BIT_lookBits(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*!BIT_readBitsFast : +* unsafe version; only works if nbBits >= 1 */ +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) +{ + size_t value = BIT_lookBitsFast(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) +{ + if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */ + return BIT_DStream_overflow; + + if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) + { + bitD->ptr -= bitD->bitsConsumed >> 3; + bitD->bitsConsumed &= 7; + bitD->bitContainer = MEM_readLEST(bitD->ptr); + return BIT_DStream_unfinished; + } + if (bitD->ptr == bitD->start) + { + if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; + return BIT_DStream_completed; + } + { + U32 nbBytes = bitD->bitsConsumed >> 3; + BIT_DStream_status result = BIT_DStream_unfinished; + if (bitD->ptr - nbBytes < bitD->start) + { + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ + result = BIT_DStream_endOfBuffer; + } + bitD->ptr -= nbBytes; + bitD->bitsConsumed -= nbBytes*8; + bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */ + return result; + } +} + +/*! BIT_endOfDStream +* @return Tells if DStream has reached its exact end +*/ +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) +{ + return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); +} + +#if defined (__cplusplus) +} +#endif + +#endif /* BITSTREAM_H_MODULE */ +/* ****************************************************************** + Error codes and messages + Copyright (C) 2013-2015, Yann Collet + + BSD 2-Clause License (https://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 : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ +#ifndef ERROR_H_MODULE +#define ERROR_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + + +/****************************************** +* Compiler-specific +******************************************/ +#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define ERR_STATIC static inline +#elif defined(_MSC_VER) +# define ERR_STATIC static __inline +#elif defined(__GNUC__) +# define ERR_STATIC static __attribute__((unused)) +#else +# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif + + +/****************************************** +* Error Management +******************************************/ +#define PREFIX(name) ZSTD_error_##name + +#define ERROR(name) (size_t)-PREFIX(name) + +#define ERROR_LIST(ITEM) \ + ITEM(PREFIX(No_Error)) ITEM(PREFIX(GENERIC)) \ + ITEM(PREFIX(dstSize_tooSmall)) ITEM(PREFIX(srcSize_wrong)) \ + ITEM(PREFIX(prefix_unknown)) ITEM(PREFIX(corruption_detected)) \ + ITEM(PREFIX(tableLog_tooLarge)) ITEM(PREFIX(maxSymbolValue_tooLarge)) ITEM(PREFIX(maxSymbolValue_tooSmall)) \ + ITEM(PREFIX(maxCode)) + +#define ERROR_GENERATE_ENUM(ENUM) ENUM, +typedef enum { ERROR_LIST(ERROR_GENERATE_ENUM) } ERR_codes; /* enum is exposed, to detect & handle specific errors; compare function result to -enum value */ + +#define ERROR_CONVERTTOSTRING(STRING) #STRING, +#define ERROR_GENERATE_STRING(EXPR) ERROR_CONVERTTOSTRING(EXPR) +static const char* ERR_strings[] = { ERROR_LIST(ERROR_GENERATE_STRING) }; + +ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } + +ERR_STATIC const char* ERR_getErrorName(size_t code) +{ + static const char* codeError = "Unspecified error code"; + if (ERR_isError(code)) return ERR_strings[-(int)(code)]; + return codeError; +} + + +#if defined (__cplusplus) +} +#endif + +#endif /* ERROR_H_MODULE */ +/* +Constructor and Destructor of type FSE_CTable + Note that its size depends on 'tableLog' and 'maxSymbolValue' */ +typedef unsigned FSE_CTable; /* don't allocate that. It's just a way to be more restrictive than void* */ +typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ + + +/* ****************************************************************** + FSE : Finite State Entropy coder + header file for static linking (only) + Copyright (C) 2013-2015, Yann Collet + + BSD 2-Clause License (https://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 : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ +#if defined (__cplusplus) +extern "C" { +#endif + + +/****************************************** +* Static allocation +******************************************/ +/* FSE buffer bounds */ +#define FSE_NCOUNTBOUND 512 +#define FSE_BLOCKBOUND(size) (size + (size>>7)) +#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* You can statically allocate FSE CTable/DTable as a table of unsigned using below macro */ +#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2)) +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<= 1 (otherwise, result will be corrupted) */ + + +/****************************************** +* Implementation of inline functions +******************************************/ + +/* decompression */ + +typedef struct { + U16 tableLog; + U16 fastMode; +} FSE_DTableHeader; /* sizeof U32 */ + +typedef struct +{ + unsigned short newState; + unsigned char symbol; + unsigned char nbBits; +} FSE_decode_t; /* size == U32 */ + +MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) +{ + FSE_DTableHeader DTableH; + memcpy(&DTableH, dt, sizeof(DTableH)); + DStatePtr->state = BIT_readBits(bitD, DTableH.tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + const U32 nbBits = DInfo.nbBits; + BYTE symbol = DInfo.symbol; + size_t lowBits = BIT_readBits(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + const U32 nbBits = DInfo.nbBits; + BYTE symbol = DInfo.symbol; + size_t lowBits = BIT_readBitsFast(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) +{ + return DStatePtr->state == 0; +} + + +#if defined (__cplusplus) +} +#endif +/* ****************************************************************** + Huff0 : Huffman coder, part of New Generation Entropy library + header file for static linking (only) + Copyright (C) 2013-2015, Yann Collet + + BSD 2-Clause License (https://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 : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ + +#if defined (__cplusplus) +extern "C" { +#endif + +/****************************************** +* Static allocation macros +******************************************/ +/* Huff0 buffer bounds */ +#define HUF_CTABLEBOUND 129 +#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true if incompressible pre-filtered with fast heuristic */ +#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* static allocation of Huff0's DTable */ +#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1< /* size_t */ + + +/* ************************************* +* Version +***************************************/ +#define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */ +#define ZSTD_VERSION_MINOR 2 /* for new (non-breaking) interface capabilities */ +#define ZSTD_VERSION_RELEASE 2 /* for tweaks, bug-fixes, or development */ +#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) + + +/* ************************************* +* Advanced functions +***************************************/ +typedef struct ZSTD_CCtx_s ZSTD_CCtx; /* incomplete type */ + +#if defined (__cplusplus) +} +#endif +/* + zstd - standard compression library + Header File for static linking only + Copyright (C) 2014-2015, Yann Collet. + + BSD 2-Clause License (https://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 : + - zstd source repository : https://github.com/Cyan4973/zstd + - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c +*/ + +/* The objects defined into this file should be considered experimental. + * They are not labelled stable, as their prototype may change in the future. + * You can use them for tests, provide feedback, or if you can endure risk of future changes. + */ + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ************************************* +* Streaming functions +***************************************/ + +typedef struct ZSTDv02_Dctx_s ZSTD_DCtx; + +/* + Use above functions alternatively. + ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue(). + ZSTD_decompressContinue() will use previous data blocks to improve compression if they are located prior to current block. + Result is the number of bytes regenerated within 'dst'. + It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header. +*/ + +/* ************************************* +* Prefix - version detection +***************************************/ +#define ZSTD_magicNumber 0xFD2FB522 /* v0.2 (current)*/ + + +#if defined (__cplusplus) +} +#endif +/* ****************************************************************** + FSE : Finite State Entropy coder + Copyright (C) 2013-2015, Yann Collet. + + BSD 2-Clause License (https://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 : + - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ + +#ifndef FSE_COMMONDEFS_ONLY + +/**************************************************************** +* Tuning parameters +****************************************************************/ +/* MEMORY_USAGE : +* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect +* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ +#define FSE_MAX_MEMORY_USAGE 14 +#define FSE_DEFAULT_MEMORY_USAGE 13 + +/* FSE_MAX_SYMBOL_VALUE : +* Maximum symbol value authorized. +* Required for proper stack allocation */ +#define FSE_MAX_SYMBOL_VALUE 255 + + +/**************************************************************** +* template functions type & suffix +****************************************************************/ +#define FSE_FUNCTION_TYPE BYTE +#define FSE_FUNCTION_EXTENSION + + +/**************************************************************** +* Byte symbol type +****************************************************************/ +#endif /* !FSE_COMMONDEFS_ONLY */ + + +/**************************************************************** +* Compiler specifics +****************************************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# define FORCE_INLINE static __forceinline +# include /* For Visual 2005 */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ +#else +# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# ifdef __GNUC__ +# define FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define FORCE_INLINE static inline +# endif +# else +# define FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +#endif + + +/**************************************************************** +* Includes +****************************************************************/ +#include /* malloc, free, qsort */ +#include /* memcpy, memset */ +#include /* printf (debug) */ + +/**************************************************************** +* Constants +*****************************************************************/ +#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) +#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX +#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" +#endif + + +/**************************************************************** +* Error Management +****************************************************************/ +#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ + + +/**************************************************************** +* Complex types +****************************************************************/ +typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; + + +/**************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + + +/* Function templates */ + +#define FSE_DECODE_TYPE FSE_decode_t + +static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; } + +static size_t FSE_buildDTable +(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + void* ptr = dt+1; + FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*)ptr; + FSE_DTableHeader DTableH; + const U32 tableSize = 1 << tableLog; + const U32 tableMask = tableSize-1; + const U32 step = FSE_tableStep(tableSize); + U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; + U32 position = 0; + U32 highThreshold = tableSize-1; + const S16 largeLimit= (S16)(1 << (tableLog-1)); + U32 noLarge = 1; + U32 s; + + /* Sanity Checks */ + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + + /* Init, lay down lowprob symbols */ + DTableH.tableLog = (U16)tableLog; + for (s=0; s<=maxSymbolValue; s++) + { + if (normalizedCounter[s]==-1) + { + tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s; + symbolNext[s] = 1; + } + else + { + if (normalizedCounter[s] >= largeLimit) noLarge=0; + symbolNext[s] = normalizedCounter[s]; + } + } + + /* Spread symbols */ + for (s=0; s<=maxSymbolValue; s++) + { + int i; + for (i=0; i highThreshold) position = (position + step) & tableMask; /* lowprob area */ + } + } + + if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + + /* Build Decoding table */ + { + U32 i; + for (i=0; i FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); + bitStream >>= 4; + bitCount = 4; + *tableLogPtr = nbBits; + remaining = (1<1) && (charnum<=*maxSVPtr)) + { + if (previous0) + { + unsigned n0 = charnum; + while ((bitStream & 0xFFFF) == 0xFFFF) + { + n0+=24; + if (ip < iend-5) + { + ip+=2; + bitStream = MEM_readLE32(ip) >> bitCount; + } + else + { + bitStream >>= 16; + bitCount+=16; + } + } + while ((bitStream & 3) == 3) + { + n0+=3; + bitStream>>=2; + bitCount+=2; + } + n0 += bitStream & 3; + bitCount += 2; + if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); + while (charnum < n0) normalizedCounter[charnum++] = 0; + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) + { + ip += bitCount>>3; + bitCount &= 7; + bitStream = MEM_readLE32(ip) >> bitCount; + } + else + bitStream >>= 2; + } + { + const short max = (short)((2*threshold-1)-remaining); + short count; + + if ((bitStream & (threshold-1)) < (U32)max) + { + count = (short)(bitStream & (threshold-1)); + bitCount += nbBits-1; + } + else + { + count = (short)(bitStream & (2*threshold-1)); + if (count >= threshold) count -= max; + bitCount += nbBits; + } + + count--; /* extra accuracy */ + remaining -= FSE_abs(count); + normalizedCounter[charnum++] = count; + previous0 = !count; + while (remaining < threshold) + { + nbBits--; + threshold >>= 1; + } + + { + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) + { + ip += bitCount>>3; + bitCount &= 7; + } + else + { + bitCount -= (int)(8 * (iend - 4 - ip)); + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> (bitCount & 31); + } + } + } + if (remaining != 1) return ERROR(GENERIC); + *maxSVPtr = charnum-1; + + ip += (bitCount+7)>>3; + if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong); + return ip-istart; +} + + +/********************************************************* +* Decompression (Byte symbols) +*********************************************************/ +static size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue) +{ + void* ptr = dt; + FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; + FSE_decode_t* const cell = (FSE_decode_t*)(ptr) + 1; /* because dt is unsigned */ + + DTableH->tableLog = 0; + DTableH->fastMode = 0; + + cell->newState = 0; + cell->symbol = symbolValue; + cell->nbBits = 0; + + return 0; +} + + +static size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) +{ + void* ptr = dt; + FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; + FSE_decode_t* const dinfo = (FSE_decode_t*)(ptr) + 1; /* because dt is unsigned */ + const unsigned tableSize = 1 << nbBits; + const unsigned tableMask = tableSize - 1; + const unsigned maxSymbolValue = tableMask; + unsigned s; + + /* Sanity checks */ + if (nbBits < 1) return ERROR(GENERIC); /* min size */ + + /* Build Decoding Table */ + DTableH->tableLog = (U16)nbBits; + DTableH->fastMode = 1; + for (s=0; s<=maxSymbolValue; s++) + { + dinfo[s].newState = 0; + dinfo[s].symbol = (BYTE)s; + dinfo[s].nbBits = (BYTE)nbBits; + } + + return 0; +} + +FORCE_INLINE size_t FSE_decompress_usingDTable_generic( + void* dst, size_t maxDstSize, + const void* cSrc, size_t cSrcSize, + const FSE_DTable* dt, const unsigned fast) +{ + BYTE* const ostart = (BYTE*) dst; + BYTE* op = ostart; + BYTE* const omax = op + maxDstSize; + BYTE* const olimit = omax-3; + + BIT_DStream_t bitD; + FSE_DState_t state1; + FSE_DState_t state2; + size_t errorCode; + + /* Init */ + errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */ + if (FSE_isError(errorCode)) return errorCode; + + FSE_initDState(&state1, &bitD, dt); + FSE_initDState(&state2, &bitD, dt); + +#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD) + + /* 4 symbols per loop */ + for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) && (op sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[1] = FSE_GETSYMBOL(&state2); + + if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } + + op[2] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[3] = FSE_GETSYMBOL(&state2); + } + + /* tail */ + /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ + while (1) + { + if ( (BIT_reloadDStream(&bitD)>BIT_DStream_completed) || (op==omax) || (BIT_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state1))) ) + break; + + *op++ = FSE_GETSYMBOL(&state1); + + if ( (BIT_reloadDStream(&bitD)>BIT_DStream_completed) || (op==omax) || (BIT_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state2))) ) + break; + + *op++ = FSE_GETSYMBOL(&state2); + } + + /* end ? */ + if (BIT_endOfDStream(&bitD) && FSE_endOfDState(&state1) && FSE_endOfDState(&state2)) + return op-ostart; + + if (op==omax) return ERROR(dstSize_tooSmall); /* dst buffer is full, but cSrc unfinished */ + + return ERROR(corruption_detected); +} + + +static size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, + const void* cSrc, size_t cSrcSize, + const FSE_DTable* dt) +{ + FSE_DTableHeader DTableH; + memcpy(&DTableH, dt, sizeof(DTableH)); + + /* select fast mode (static) */ + if (DTableH.fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); + return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); +} + + +static size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize) +{ + const BYTE* const istart = (const BYTE*)cSrc; + const BYTE* ip = istart; + short counting[FSE_MAX_SYMBOL_VALUE+1]; + DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + size_t errorCode; + + if (cSrcSize<2) return ERROR(srcSize_wrong); /* too small input size */ + + /* normal FSE decoding mode */ + errorCode = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + if (FSE_isError(errorCode)) return errorCode; + if (errorCode >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */ + ip += errorCode; + cSrcSize -= errorCode; + + errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog); + if (FSE_isError(errorCode)) return errorCode; + + /* always return, even if it is an error code */ + return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); +} + + + +#endif /* FSE_COMMONDEFS_ONLY */ +/* ****************************************************************** + Huff0 : Huffman coder, part of New Generation Entropy library + Copyright (C) 2013-2015, Yann Collet. + + BSD 2-Clause License (https://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 : + - FSE+Huff0 source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ + +/**************************************************************** +* Compiler specifics +****************************************************************/ +#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +/* inline is defined */ +#elif defined(_MSC_VER) +# define inline __inline +#else +# define inline /* disable inline */ +#endif + + +#ifdef _MSC_VER /* Visual Studio */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#endif + + +/**************************************************************** +* Includes +****************************************************************/ +#include /* malloc, free, qsort */ +#include /* memcpy, memset */ +#include /* printf (debug) */ + +/**************************************************************** +* Error Management +****************************************************************/ +#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ + + +/****************************************** +* Helper functions +******************************************/ +static unsigned HUF_isError(size_t code) { return ERR_isError(code); } + +#define HUF_ABSOLUTEMAX_TABLELOG 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#define HUF_MAX_TABLELOG 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */ +#define HUF_DEFAULT_TABLELOG HUF_MAX_TABLELOG /* tableLog by default, when not specified */ +#define HUF_MAX_SYMBOL_VALUE 255 +#if (HUF_MAX_TABLELOG > HUF_ABSOLUTEMAX_TABLELOG) +# error "HUF_MAX_TABLELOG is too large !" +#endif + + + +/********************************************************* +* Huff0 : Huffman block decompression +*********************************************************/ +typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2; /* single-symbol decoding */ + +typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4; /* double-symbols decoding */ + +typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t; + +/*! HUF_readStats + Read compact Huffman tree, saved by HUF_writeCTable + @huffWeight : destination buffer + @return : size read from `src` +*/ +static size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize) +{ + U32 weightTotal; + U32 tableLog; + const BYTE* ip = (const BYTE*) src; + size_t iSize; + size_t oSize; + U32 n; + + if (!srcSize) return ERROR(srcSize_wrong); + iSize = ip[0]; + //memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */ + + if (iSize >= 128) /* special header */ + { + if (iSize >= (242)) /* RLE */ + { + static int l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 }; + oSize = l[iSize-242]; + memset(huffWeight, 1, hwSize); + iSize = 0; + } + else /* Incompressible */ + { + oSize = iSize - 127; + iSize = ((oSize+1)/2); + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + if (oSize >= hwSize) return ERROR(corruption_detected); + ip += 1; + for (n=0; n> 4; + huffWeight[n+1] = ip[n/2] & 15; + } + } + } + else /* header compressed with FSE (normal case) */ + { + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + oSize = FSE_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */ + if (FSE_isError(oSize)) return oSize; + } + + /* collect weight stats */ + memset(rankStats, 0, (HUF_ABSOLUTEMAX_TABLELOG + 1) * sizeof(U32)); + weightTotal = 0; + for (n=0; n= HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected); + rankStats[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } + if (weightTotal == 0) return ERROR(corruption_detected); + + /* get last non-null symbol weight (implied, total must be 2^n) */ + tableLog = BIT_highbit32(weightTotal) + 1; + if (tableLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected); + { + U32 total = 1 << tableLog; + U32 rest = total - weightTotal; + U32 verif = 1 << BIT_highbit32(rest); + U32 lastWeight = BIT_highbit32(rest) + 1; + if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankStats[lastWeight]++; + } + + /* check tree construction validity */ + if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ + + /* results */ + *nbSymbolsPtr = (U32)(oSize+1); + *tableLogPtr = tableLog; + return iSize+1; +} + + +/**************************/ +/* single-symbol decoding */ +/**************************/ + +static size_t HUF_readDTableX2 (U16* DTable, const void* src, size_t srcSize) +{ + BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1]; + U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */ + U32 tableLog = 0; + const BYTE* ip = (const BYTE*) src; + size_t iSize = ip[0]; + U32 nbSymbols = 0; + U32 n; + U32 nextRankStart; + void* ptr = DTable+1; + HUF_DEltX2* const dt = (HUF_DEltX2*)ptr; + + HUF_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U16)); /* if compilation fails here, assertion is false */ + //memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats(huffWeight, HUF_MAX_SYMBOL_VALUE + 1, rankVal, &nbSymbols, &tableLog, src, srcSize); + if (HUF_isError(iSize)) return iSize; + + /* check result */ + if (tableLog > DTable[0]) return ERROR(tableLog_tooLarge); /* DTable is too small */ + DTable[0] = (U16)tableLog; /* maybe should separate sizeof DTable, as allocated, from used size of DTable, in case of DTable re-use */ + + /* Prepare ranks */ + nextRankStart = 0; + for (n=1; n<=tableLog; n++) + { + U32 current = nextRankStart; + nextRankStart += (rankVal[n] << (n-1)); + rankVal[n] = current; + } + + /* fill DTable */ + for (n=0; n> 1; + U32 i; + HUF_DEltX2 D; + D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w); + for (i = rankVal[w]; i < rankVal[w] + length; i++) + dt[i] = D; + rankVal[w] += length; + } + + return iSize; +} + +static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog) +{ + const size_t val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ + const BYTE c = dt[val].byte; + BIT_skipBits(Dstream, dt[val].nbBits); + return c; +} + +#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \ + *ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ + if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \ + HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) + +#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ + if (MEM_64bits()) \ + HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) + +static inline size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX2* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 4 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4)) + { + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_1(p, bitDPtr); + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + + /* closer to the end */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd)) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + + /* no more data to retrieve from bitstream, hence no need to reload */ + while (p < pEnd) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + + return pEnd-pStart; +} + + +static size_t HUF_decompress4X2_usingDTable( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const U16* DTable) +{ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + + { + const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + + const void* ptr = DTable; + const HUF_DEltX2* const dt = ((const HUF_DEltX2*)ptr) +1; + const U32 dtLog = DTable[0]; + size_t errorCode; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + const size_t length1 = MEM_readLE16(istart); + const size_t length2 = MEM_readLE16(istart+2); + const size_t length3 = MEM_readLE16(istart+4); + size_t length4; + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + const size_t segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + U32 endSignal; + + length4 = cSrcSize - (length1 + length2 + length3 + 6); + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + errorCode = BIT_initDStream(&bitD1, istart1, length1); + if (HUF_isError(errorCode)) return errorCode; + errorCode = BIT_initDStream(&bitD2, istart2, length2); + if (HUF_isError(errorCode)) return errorCode; + errorCode = BIT_initDStream(&bitD3, istart3, length3); + if (HUF_isError(errorCode)) return errorCode; + errorCode = BIT_initDStream(&bitD4, istart4, length4); + if (HUF_isError(errorCode)) return errorCode; + + /* 16-32 symbols per loop (4-8 symbols per stream) */ + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; ) + { + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + } + + /* check corruption */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 supposed already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog); + + /* check */ + endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endSignal) return ERROR(corruption_detected); + + /* decoded size */ + return dstSize; + } +} + + +static size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_MAX_TABLELOG); + const BYTE* ip = (const BYTE*) cSrc; + size_t errorCode; + + errorCode = HUF_readDTableX2 (DTable, cSrc, cSrcSize); + if (HUF_isError(errorCode)) return errorCode; + if (errorCode >= cSrcSize) return ERROR(srcSize_wrong); + ip += errorCode; + cSrcSize -= errorCode; + + return HUF_decompress4X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable); +} + + +/***************************/ +/* double-symbols decoding */ +/***************************/ + +static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed, + const U32* rankValOrigin, const int minWeight, + const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, + U32 nbBitsBaseline, U16 baseSeq) +{ + HUF_DEltX4 DElt; + U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; + U32 s; + + /* get pre-calculated rankVal */ + memcpy(rankVal, rankValOrigin, sizeof(rankVal)); + + /* fill skipped values */ + if (minWeight>1) + { + U32 i, skipSize = rankVal[minWeight]; + MEM_writeLE16(&(DElt.sequence), baseSeq); + DElt.nbBits = (BYTE)(consumed); + DElt.length = 1; + for (i = 0; i < skipSize; i++) + DTable[i] = DElt; + } + + /* fill DTable */ + for (s=0; s= 1 */ + + rankVal[weight] += length; + } +} + +typedef U32 rankVal_t[HUF_ABSOLUTEMAX_TABLELOG][HUF_ABSOLUTEMAX_TABLELOG + 1]; + +static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog, + const sortedSymbol_t* sortedList, const U32 sortedListSize, + const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight, + const U32 nbBitsBaseline) +{ + U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; + const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ + const U32 minBits = nbBitsBaseline - maxWeight; + U32 s; + + memcpy(rankVal, rankValOrigin, sizeof(rankVal)); + + /* fill DTable */ + for (s=0; s= minBits) /* enough room for a second symbol */ + { + U32 sortedRank; + int minWeight = nbBits + scaleLog; + if (minWeight < 1) minWeight = 1; + sortedRank = rankStart[minWeight]; + HUF_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits, + rankValOrigin[nbBits], minWeight, + sortedList+sortedRank, sortedListSize-sortedRank, + nbBitsBaseline, symbol); + } + else + { + U32 i; + const U32 end = start + length; + HUF_DEltX4 DElt; + + MEM_writeLE16(&(DElt.sequence), symbol); + DElt.nbBits = (BYTE)(nbBits); + DElt.length = 1; + for (i = start; i < end; i++) + DTable[i] = DElt; + } + rankVal[weight] += length; + } +} + +static size_t HUF_readDTableX4 (U32* DTable, const void* src, size_t srcSize) +{ + BYTE weightList[HUF_MAX_SYMBOL_VALUE + 1]; + sortedSymbol_t sortedSymbol[HUF_MAX_SYMBOL_VALUE + 1]; + U32 rankStats[HUF_ABSOLUTEMAX_TABLELOG + 1] = { 0 }; + U32 rankStart0[HUF_ABSOLUTEMAX_TABLELOG + 2] = { 0 }; + U32* const rankStart = rankStart0+1; + rankVal_t rankVal; + U32 tableLog, maxW, sizeOfSort, nbSymbols; + const U32 memLog = DTable[0]; + const BYTE* ip = (const BYTE*) src; + size_t iSize = ip[0]; + void* ptr = DTable; + HUF_DEltX4* const dt = ((HUF_DEltX4*)ptr) + 1; + + HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(U32)); /* if compilation fails here, assertion is false */ + if (memLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge); + //memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats(weightList, HUF_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize); + if (HUF_isError(iSize)) return iSize; + + /* check result */ + if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ + + /* find maxWeight */ + for (maxW = tableLog; rankStats[maxW]==0; maxW--) + {if (!maxW) return ERROR(GENERIC); } /* necessarily finds a solution before maxW==0 */ + + /* Get start index of each weight */ + { + U32 w, nextRankStart = 0; + for (w=1; w<=maxW; w++) + { + U32 current = nextRankStart; + nextRankStart += rankStats[w]; + rankStart[w] = current; + } + rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/ + sizeOfSort = nextRankStart; + } + + /* sort symbols by weight */ + { + U32 s; + for (s=0; s> consumed; + } + } + } + + HUF_fillDTableX4(dt, memLog, + sortedSymbol, sizeOfSort, + rankStart0, rankVal, maxW, + tableLog+1); + + return iSize; +} + + +static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog) +{ + const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + memcpy(op, dt+val, 2); + BIT_skipBits(DStream, dt[val].nbBits); + return dt[val].length; +} + +static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog) +{ + const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + memcpy(op, dt+val, 1); + if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits); + else + { + if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) + { + BIT_skipBits(DStream, dt[val].nbBits); + if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8)) + DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ + } + } + return 1; +} + + +#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \ + ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \ + if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \ + ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \ + if (MEM_64bits()) \ + ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) + +static inline size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const HUF_DEltX4* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 8 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd-7)) + { + HUF_DECODE_SYMBOLX4_2(p, bitDPtr); + HUF_DECODE_SYMBOLX4_1(p, bitDPtr); + HUF_DECODE_SYMBOLX4_2(p, bitDPtr); + HUF_DECODE_SYMBOLX4_0(p, bitDPtr); + } + + /* closer to the end */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-2)) + HUF_DECODE_SYMBOLX4_0(p, bitDPtr); + + while (p <= pEnd-2) + HUF_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ + + if (p < pEnd) + p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog); + + return p-pStart; +} + + + +static size_t HUF_decompress4X4_usingDTable( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const U32* DTable) +{ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + + { + const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + + const void* ptr = DTable; + const HUF_DEltX4* const dt = ((const HUF_DEltX4*)ptr) +1; + const U32 dtLog = DTable[0]; + size_t errorCode; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + const size_t length1 = MEM_readLE16(istart); + const size_t length2 = MEM_readLE16(istart+2); + const size_t length3 = MEM_readLE16(istart+4); + size_t length4; + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + const size_t segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + U32 endSignal; + + length4 = cSrcSize - (length1 + length2 + length3 + 6); + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + errorCode = BIT_initDStream(&bitD1, istart1, length1); + if (HUF_isError(errorCode)) return errorCode; + errorCode = BIT_initDStream(&bitD2, istart2, length2); + if (HUF_isError(errorCode)) return errorCode; + errorCode = BIT_initDStream(&bitD3, istart3, length3); + if (HUF_isError(errorCode)) return errorCode; + errorCode = BIT_initDStream(&bitD4, istart4, length4); + if (HUF_isError(errorCode)) return errorCode; + + /* 16-32 symbols per loop (4-8 symbols per stream) */ + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; ) + { + HUF_DECODE_SYMBOLX4_2(op1, &bitD1); + HUF_DECODE_SYMBOLX4_2(op2, &bitD2); + HUF_DECODE_SYMBOLX4_2(op3, &bitD3); + HUF_DECODE_SYMBOLX4_2(op4, &bitD4); + HUF_DECODE_SYMBOLX4_1(op1, &bitD1); + HUF_DECODE_SYMBOLX4_1(op2, &bitD2); + HUF_DECODE_SYMBOLX4_1(op3, &bitD3); + HUF_DECODE_SYMBOLX4_1(op4, &bitD4); + HUF_DECODE_SYMBOLX4_2(op1, &bitD1); + HUF_DECODE_SYMBOLX4_2(op2, &bitD2); + HUF_DECODE_SYMBOLX4_2(op3, &bitD3); + HUF_DECODE_SYMBOLX4_2(op4, &bitD4); + HUF_DECODE_SYMBOLX4_0(op1, &bitD1); + HUF_DECODE_SYMBOLX4_0(op2, &bitD2); + HUF_DECODE_SYMBOLX4_0(op3, &bitD3); + HUF_DECODE_SYMBOLX4_0(op4, &bitD4); + + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + } + + /* check corruption */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 supposed already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog); + + /* check */ + endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endSignal) return ERROR(corruption_detected); + + /* decoded size */ + return dstSize; + } +} + + +static size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_MAX_TABLELOG); + const BYTE* ip = (const BYTE*) cSrc; + + size_t hSize = HUF_readDTableX4 (DTable, cSrc, cSrcSize); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; + cSrcSize -= hSize; + + return HUF_decompress4X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable); +} + + +/**********************************/ +/* quad-symbol decoding */ +/**********************************/ +typedef struct { BYTE nbBits; BYTE nbBytes; } HUF_DDescX6; +typedef union { BYTE byte[4]; U32 sequence; } HUF_DSeqX6; + +/* recursive, up to level 3; may benefit from

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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/pl.po b/cpp/third_party/xz-5.8.3/po/pl.po new file mode 100644 index 000000000..4a74b938c --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/pl.po @@ -0,0 +1,1266 @@ +# SPDX-License-Identifier: 0BSD +# +# Polish translation for xz. +# This file is published under the BSD Zero Clause License. +# Jakub Bogusz , 2011-2025. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-02-08 08:02+0100\n" +"Last-Translator: Jakub Bogusz \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Błędny argument dla --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Zbyt dużo argumentów dla --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "W --block-list brakuje rozmiaru bloku po numerze Å‚aÅ„cucha filtrów „%c:â€" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 w --block-list może być użyte wyłącznie jako ostatni element" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Nieznany typ formatu pliku" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: NieobsÅ‚ugiwany typ kontroli spójnoÅ›ci" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Wraz z opcjÄ… „--files†lub „--files0†można podać tylko jeden plik." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Zmienna Å›rodowiskowa %s zawiera zbyt dużo argumentów" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "ObsÅ‚uga kompresji zostaÅ‚a wyłączona na etapie budowania" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "ObsÅ‚uga dekompresji zostaÅ‚a wyłączona na etapie budowania" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Kompresja plików lzip (.lz) nie jest obsÅ‚ugiwana" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list jest ignorowane poza kompresjÄ… do formatu .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Przy użyciu --format=raw i zapisie do pliku wymagana jest opcja --suffix=.ROZ" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Maksymalna liczba filtrów to cztery" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Błąd w opcji --filters%s=FILTRY:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Limit użycia pamiÄ™ci jest zbyt maÅ‚y dla podanej konfiguracji filtra." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "Å‚aÅ„cuch filtrów %u użyty w --block-list, ale nie podany przez --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Używanie ustawieÅ„ predefiniowanych w trybie surowym jest odradzane." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "DokÅ‚adne opcje ustawieÅ„ predefiniowanych mogÄ… różnić siÄ™ miÄ™dzy wersjami oprogramowania." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Format .lzma obsÅ‚uguje tylko filtr LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 nie może być używany z formatem .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "ÅaÅ„cuch filtrów %u jest niezgodny z --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Przełączanie w tryb jednowÄ…tkowy z powodu --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "NieobsÅ‚ugiwane opcje w Å‚aÅ„cuchu filtrów %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Maksymalna liczba używanych wÄ…tków: %." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "NieobsÅ‚ugiwany Å‚aÅ„cuch filtrów lub opcje filtra" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Dekompresja bÄ™dzie wymagaÅ‚a %s MiB pamiÄ™ci." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Zmniejszono liczbÄ™ wÄ…tków z %s do %s, aby nie przekroczyć limitu użycia pamiÄ™ci %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Zmniejszono liczbÄ™ wÄ…tków z %s do jednego. Automatyczny limit użycia pamiÄ™ci %s MiB jest nadal przekroczony - wymagane jest %s MiB. Kontynuacja mimo to." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Przełączenie w tryb jednowÄ…tkowy, aby nie przekroczyć limitu użycia pamiÄ™ci %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Skorygowano rozmiar sÅ‚ownika LZMA%c z %s MiB do %s MiB aby nie przekroczyć limitu użycia pamiÄ™ci %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Skorygowano rozmiar sÅ‚ownika LZMA%c dla --filters%u z %s MiB do %s MiB, aby nie przekroczyć limitu użycia pamiÄ™ci %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Błąd podczas zmiany w Å‚aÅ„cuchu filtrów %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Błąd tworzenia potoku: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() nie powiodÅ‚o siÄ™: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Plik wyglÄ…da na przeniesiony, nie zostanie usuniÄ™ty" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Nie można usunąć: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Nie można ustawić wÅ‚aÅ›ciciela pliku: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Nie można ustawić grupy pliku: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Nie można ustawić uprawnieÅ„ pliku: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Synchronizacja pliku nie powiodÅ‚a siÄ™: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Synchronizacja katalogu z plikiem nie powiodÅ‚a siÄ™: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Błąd podczas pobierania flag stanu pliku ze standardowego wejÅ›cia: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Jest dowiÄ…zaniem symbolicznym, pominiÄ™to" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Jest katalogiem, pominiÄ™to" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Nie jest zwykÅ‚ym plikiem, pominiÄ™to" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Plik ma ustawiony bit setuid lub setgid, pominiÄ™to" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Plik ma ustawiony bit sticky, pominiÄ™to" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Plik wejÅ›ciowy ma wiÄ™cej niż jedno dowiÄ…zanie zwykÅ‚e, pominiÄ™to" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Pusta nazwa pliku, pominiÄ™to" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Błąd podczas odtwarzania flag stanu dla standardowego wejÅ›cia: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Błąd podczas pobierania flag stanu pliku ze standardowego wyjÅ›cia: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Otwarcie katalogu nie powiodÅ‚o siÄ™: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: Cel nie jest zwykÅ‚ym plikiem" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Błąd podczas odtwarzania flagi O_APPEND dla standardowego wyjÅ›cia: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: ZamkniÄ™cie pliku nie powiodÅ‚o siÄ™: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Zmiana pozycji nie powiodÅ‚a siÄ™ podczas próby utworzenia pliku rzadkiego: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Błąd odczytu: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Błąd podczas zmiany pozycji w pliku: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Nieoczekiwany koniec pliku" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Błąd zapisu: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Wyłączony" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Rozmiar pamiÄ™ci fizycznej (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Liczba wÄ…tków procesora:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Kompresja:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Dekompresja:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Dekompresja wielowÄ…tkowa:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "DomyÅ›lnie dla -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Informacje o sprzÄ™cie:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Limity użycia pamiÄ™ci" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Strumienie:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Bloki:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Rozmiar spakowany:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Rozmiar rozpakowany:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Współczynnik:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Kontrola spójnoÅ›ci:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Wyrównanie strumienia:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Wymagana pamięć:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Rozmiar w nagłówkach:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Liczba plików:" + +#: src/xz/list.c +msgid "Stream" +msgstr "StrumieÅ„" + +#: src/xz/list.c +msgid "Block" +msgstr "Blok" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Bloki" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "Offset spak." + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "Offset rozp." + +#: src/xz/list.c +msgid "CompSize" +msgstr "Rozm.spak." + +#: src/xz/list.c +msgid "UncompSize" +msgstr "Rozm.rozp." + +#: src/xz/list.c +msgid "TotalSize" +msgstr "Rozm.caÅ‚k." + +#: src/xz/list.c +msgid "Ratio" +msgstr "Wsp." + +#: src/xz/list.c +msgid "Check" +msgstr "Kontrola" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "S.kontr." + +#: src/xz/list.c +msgid "Padding" +msgstr "Wyrównanie" + +#: src/xz/list.c +msgid "Header" +msgstr "Nagłówek" + +#: src/xz/list.c +msgid "Flags" +msgstr "Flagi" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "Uż.pamiÄ™ci" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtry" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Brak" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Nieznany-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Nieznany-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Nieznany-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Nieznany-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Nieznany-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Nieznany-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Nieznany-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Nieznany11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Nieznany12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Nieznany13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Nieznany14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Nieznany15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Plik jest pusty" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Za maÅ‚y na poprawny plik .xz" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Strum. Bloki Spakowany Rozpakowany Wsp. Kontrola Nazwa pliku" + +#: src/xz/list.c +msgid "Yes" +msgstr "Tak" + +#: src/xz/list.c +msgid "No" +msgstr "Nie" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Minimalna wersja XZ Utils:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s plik\n" +msgstr[1] "%s pliki\n" +msgstr[2] "%s plików\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Sumarycznie:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list dziaÅ‚a tylko z plikami .xz (--format=xz lub --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "ProszÄ™ spróbować „lzmainfo†z plikami .lzma." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list nie obsÅ‚uguje odczytu ze standardowego wejÅ›cia" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Błąd odczytu nazw plików: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Nieoczekiwany koniec wejÅ›cia podczas odczytu nazw plików" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Napotkano znak NUL podczas odczytu nazw plików; może miaÅ‚o być „--files0†zamiast „--filesâ€?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Kompresja i dekompresja z opcjÄ… --robot nie jest jeszcze obsÅ‚ugiwana." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Nie można odczytać danych ze standardowego wejÅ›cia przy czytaniu nazw plików ze standardowego wejÅ›cia" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Błąd wewnÄ™trzny" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Nie można ustawić obsÅ‚ugi sygnałów" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Brak kontroli spójnoÅ›ci; poprawność plików nie bÄ™dzie weryfikowana" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "NieobsÅ‚ugiwany typ kontroli spójnoÅ›ci; poprawność plików nie bÄ™dzie weryfikowana" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "OsiÄ…gniÄ™to limit użycia pamiÄ™ci" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Nie rozpoznany format pliku" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "NieobsÅ‚ugiwane opcje" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Dane skompresowane sÄ… uszkodzone" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Nieoczekiwany koniec wejÅ›cia" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "Wymagane jest %s MiB pamiÄ™ci. Limit jest wyłączony." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "Wymagane jest %s MiB pamiÄ™ci. Limit to %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: ÅaÅ„cuch filtrów: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Polecenie „%s --help†pokaże wiÄ™cej informacji." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Błąd podczas wypisywania tekstu pomocy (kod błędu %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "SkÅ‚adnia: %s [OPCJA]... [PLIK]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Kompresja lub dekompresja PLIKÓW w formacie .xz." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Argumenty obowiÄ…zkowe dla opcji dÅ‚ugich sÄ… obowiÄ…zkowe również dla opcji krótkich." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Tryb pracy:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "wymuszenie kompresji" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "wymuszenie dekompresji" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "sprawdzenie integralnoÅ›ci plików skompresowanych" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "wypisanie informacji o plikach .xz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Modyfikatory operacji:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "zachowanie (nieusuwanie) plików wejÅ›ciowych" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "nadpisywanie plików wyjÅ›ciowych i (de)kompresja dowiÄ…zaÅ„" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "zapis na standardowe wyjÅ›cie, nieusuwanie plików wejÅ›ciowych" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "bez synchronizacji plików wyjÅ›ciowych na urzÄ…dzenie przechowujÄ…ce przed usuniÄ™ciem pliku wejÅ›ciowego" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "dekompresja tylko pierwszego strumienia, ciche zignorowanie pozostaÅ‚ych danych wejÅ›ciowych" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "nietworzenie plików rzadkich podczas dekompresji" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".ROZ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "użycie rozszerzenia „.ROZ†dla plików skompresowanych" + +#: src/xz/message.c +msgid "FILE" +msgstr "PLIK" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "odczyt nazw plików do przetworzenia z PLIKU; jeÅ›li PLIK nie zostaÅ‚ podany, nazwy sÄ… czytane ze standardowego wejÅ›cia; muszÄ… być zakoÅ„czone znakiem nowej linii" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "podobnie do --files, ale znakiem koÅ„czÄ…cym musi być NUL" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Podstawowe opcje formatu pliku i kompresji:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMAT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "format pliku do kodowania lub dekodowania; możliwe to „auto†(domyÅ›lny), „xzâ€, „lzmaâ€, „lzip†i „rawâ€" + +#: src/xz/message.c +msgid "NAME" +msgstr "NAZWA" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "typ kontroli spójnoÅ›ci: „none†(ostrożnie!), „crc32â€, „crc64†(domyÅ›lny) lub „sha256â€" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "bez kontroli sprawdzania integralnoÅ›ci przy dekompresji" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "predefiniowane opcje kompresji; domyÅ›lna to 6; przed użyciem wartoÅ›ci 7-9 należy wziąć pod uwagÄ™ wykorzystanie pamiÄ™ci przy kompresji *oraz* dekompresji!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "próba poprawy współczynnika kompresji z użyciem wiÄ™kszej iloÅ›ci czasu procesora; nie wpÅ‚ywa na wymagania pamiÄ™ciowe dekompresora" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "ILE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "użycie maksymalnie ILU wÄ…tków; domyÅ›lnie 0, co oznacza tyle, ile jest rdzeni procesorów" + +#: src/xz/message.c +msgid "SIZE" +msgstr "ROZMIAR" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "rozpoczÄ™cie nowego bloku .xz co ROZMIAR bajtów wejÅ›cia; opcja sÅ‚uży do ustawienia rozmiaru bloku dla kompresji wielowÄ…tkowej" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOKI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "rozpoczÄ™cie nowego bloku .xz po rozdzielonych przecinkiem przedziaÅ‚ach danych nieskompresowanych; opcjonalnie można podać numer Å‚aÅ„cucha filtrów (0-9) ze znakiem „:†przed rozmiarem danych nieskompresowanych" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "przy kompresji, jeÅ›li minęło wiÄ™cej niż CZAS milisekund ostatniego zapisu bloku, a odczyt kolejnych danych byÅ‚by blokujÄ…cy, wszystkie gotowe dane sÄ… zapisywane" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "LIMIT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "ustawienie limitu użycia pamiÄ™ci dla kompresji, dekompresji, dekompresji wielowÄ…tkowej lub wszystkich; LIMIT jest w bajtach, % RAM lub 0 dla limitów domyÅ›lnych" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "jeÅ›li ustawienia kompresji przekraczajÄ… limit użycia pamiÄ™ci, zostanie zgÅ‚oszony błąd zamiast zmniejszania ustawieÅ„" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "ÅaÅ„cuch wÅ‚asnych filtrów do kompresji (alternatywa do używania ustawieÅ„ predefiniowanych):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTRY" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "ustawienie Å‚aÅ„cucha filtrów przy użyciu skÅ‚adni Å‚aÅ„cucha filtrów liblzma; wiÄ™cej informacji z opcjÄ… --filters-help" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "ustawienie dodatkowego Å‚aÅ„cucha filtrów przy użyciu skÅ‚adni Å‚aÅ„cucha filtrów liblzma do użycia w opcji --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "wiÄ™cej informacji o skÅ‚adni laÅ„cuchów filtrów libzma i zakoÅ„czenie" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "OPCJE" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 lub LZMA2; OPCJE to oddzielona przecinkami lista zera lub wiÄ™kszej liczby nastÄ™pujÄ…cych opcji (wartoÅ›ci poprawne; domyÅ›lne):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "PRE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "ustawienie opcji na predefiniowanÄ…" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "rozmiar sÅ‚ownika" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "liczba bitów kontekstu literaÅ‚u" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "liczba bitów pozycji literaÅ‚u" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "liczba bitów pozycji" + +#: src/xz/message.c +msgid "MODE" +msgstr "TRYB" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "tryb kompresji" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "dÅ‚ugość dopasowania" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "dopasowywacz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "maksymalna głębokość szukania; 0=automatyczna (domyÅ›lne)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "Filtr BCJ x86 (32-bitowy lub 64-bitowy)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "Filtr BCJ ARM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "Filtr BCJ ARM-Thumb" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "Filtr BCJ ARM64" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "Filtr BCJ PowerPC (tylko big-endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "Filtr BCJ IA-64 (Itanium)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "Filtr BCJ SPARC" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "Filtr BCJ RISC-V" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "Poprawne OPCJE dla wszystkich filtrów BCJ:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "offset poczÄ…tku konwersji (domyÅ›lnie=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Filtr delta; poprawne OPCJE (poprawne wartoÅ›ci; domyÅ›lne):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "odlegÅ‚ość miÄ™dzy bajtami odejmowanymi od siebie" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Inne opcje:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "pominiÄ™cie ostrzeżeÅ„; dwukrotne podanie pomija też błędy" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "wiÄ™cej informacji; dwukrotne podanie to jeszcze wiÄ™cej" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "ustawienie, że ostrzeżenia nie majÄ… wpÅ‚ywu na status zakoÅ„czenia" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "komunikaty w formacie dla maszyny (przydatne do skryptów)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "wyÅ›wietlenie caÅ‚kowitej iloÅ›ci pamiÄ™ci RAM oraz obecnie aktywnych limitów pamiÄ™ci i zakoÅ„czenie pracy" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "wyÅ›wietlenie krótkiego opisu (tylko podstawowe opcje)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "wyÅ›wietlenie tego dÅ‚ugiego opisu i zakoÅ„czenie" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "wyÅ›wietlenie tego krótkiego opisu i zakoÅ„czenie" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "wyÅ›wietlenie dÅ‚ugiego opisu (także opcje zaawansowane)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "wyÅ›wietlenie numeru wersji i zakoÅ„czenie" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "JeÅ›li nie podano PLIKU lub PLIK to -, czytane jest standardowe wejÅ›cie." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"Błędy prosimy zgÅ‚aszać na adres <%s> (w jÄ™zyku angielskim lub fiÅ„skim).\n" +"Błędy w tÅ‚umaczeniu prosimy zgÅ‚aszać na adres ." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "Strona domowa %s: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "TA WERSJA JEST ROZWOJOWA, NIE PRZEZNACZONA DO UÅ»YTKU PRODUKCYJNEGO." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "ÅaÅ„cuchy filtrów ustawia siÄ™ przy użyciu --filters=FILTRY lub --filters1=FILTRY ... --filters9=FILTRY. Każdy filtr w łaÅ„cuchu może być rozdzielony spacjami lub „--â€. Alternatywnie zamiast Å‚aÅ„cucha filtrów można podać predefiniowane %s." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "ObsÅ‚ugiwane filtry i ich opcje to:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Opcje muszÄ… być parami „nazwa=wartość†rozdzielonymi przecinkami" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Błędna nazwa opcji" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Błędna wartość opcji" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "NieobsÅ‚ugiwane ustawienie predefiniowane LZMA1/LZMA2: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Suma lc i lp nie może przekroczyć 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Nazwa pliku ma nieznane rozszerzenie, pominiÄ™to" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Plik już ma rozszerzenie „%sâ€, pominiÄ™to" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Błędne rozszerzenie nazwy pliku" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Wartość nie jest nieujemnÄ… liczbÄ… caÅ‚kowitÄ…" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Błędny przyrostek mnożnika" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Poprawne przyrostki to „KiB†(2^10), „MiB†(2^20) i „GiB†(2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Wartość opcji „%s†musi być w przedziale [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Dane skompresowane nie mogÄ… być czytane z terminala" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Dane skompresowane nie mogÄ… być zapisywane na terminal" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "SkÅ‚adnia: %s [--help] [--version] [PLIK]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "WyÅ›wietlanie informacji zapisanych w nagłówku pliku .lzma." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Plik jest za maÅ‚y, aby byÅ‚ plikiem .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "To nie jest plik .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Zapis na standardowe wyjÅ›cie nie powiódÅ‚ siÄ™" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Nieznany błąd" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "NieobsÅ‚ugiwane ustawienie predefiniowane" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "NieobsÅ‚ugiwana flaga w ustawieniu predefiniowanym" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Nieznana nazwa opcji" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Wartość opcji nie może być pusta" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Wartość spoza zakresu" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Ta opcja nie obsÅ‚uguje żadnych przyrostków mnożników" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Błędny przyrostek mnożnika (KiB, MiB lub GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Nieznana nazwa filtra" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Ten filtr nie może być używany w formacie .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Nie udaÅ‚o siÄ™ przydzielić pamiÄ™ci" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "ÅaÅ„cuch pusty nie jest dozwolony, jeÅ›li potrzebna jest wartość domyÅ›lna, proszÄ™ spróbować „6â€" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Maksymalna liczba filtrów to cztery" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Brak nazwy filtra" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Błędny Å‚aÅ„cuch filtrów (brak „lzma2†na koÅ„cu?)" diff --git a/cpp/third_party/xz-5.8.3/po/pt.gmo b/cpp/third_party/xz-5.8.3/po/pt.gmo new file mode 100644 index 0000000000000000000000000000000000000000..506bb9612066c31bccbbc3a532c88d01d59f379f GIT binary patch literal 28796 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 X^qjA(ZtV3|cruU^^u9U-tg`, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.8.0-pre1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-03-16 17:37+0000\n" +"Last-Translator: Pedro Albuquerque \n" +"Language-Team: Portuguese \n" +"Language: pt\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" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.5\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: argumento inválido para --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: demasiados argumentos para --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "Em --block-list, falta o tamanho do bloco após filtrar o número da cadeia \"%c:\"" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 só pode ser usado como o último elemento em --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: tipo de formato de ficheiro desconhecido" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: tipo de verificação de integridade não suportado" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Só pode especificar um ficheiro com \"--files\" ou \"--files0\"." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "A variável de ambiente %s contém demasiados argumentos" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "O suporte a compressão foi desactivado ao compilar" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "O suporte a descompressão foi desactivado ao compilar" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "A compressão de ficheiros lzip (.lz) não é suportada" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list é ignorado a não ser que comprima para formato .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Com --format=raw, --suffix=.SUF é requerido, a menos que seja escrito em stdout" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "O número máximo de filtros é quatro" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Erro na opção --filters%s=FILTERS:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "O limite de uso de memória é baixo demais para a configuração de filtro dada." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "cadeia de filtro %u usada por --block-list mas não especificada com --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "O uso de uma predefinição em modo bruto é desencorajado." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "As opções exactas de predefinições podem variar entre versões do programa." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "O formato .lzma tem só suporta o filtro LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "Impossível utilizar LZMA1 com o formato .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "A cadeia de filtragem %u é incompatível com --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "A mudar para o modo de linha única devido a --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Opções não suportadas na cadeia de filtragem %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "A usar até % linhas." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Opções de filtro ou cadeia de filtros não suportadas" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "A descompressão precisará de %s MiB de memória." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Número de linhas reduzido de %s de %s para não exceder o limite de uso de memória de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Número de linhas reduzido de %s para uma. O limite automático de utilização de memória de %s MiB ainda continua excedido. Necessita de %s MiB. A continuar mesmo assim." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "A mudar para o modo de linha única para não exceder o limite de uso de memória de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Ajustado o tamanho de dicionário de LZMA%c de %s MiB para %s MiB para não exceder o limite de uso de memória de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Ajustado o tamanho de dicionário de LZMA%c para --filters%u de %s MiB para %s MiB para não exceder o limite de uso de memória de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Erro ao mudar para a cadeia de filtragem %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Erro ao criar um túnel: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() falhou: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: o ficheiro parece ter sido movido, não será eliminado" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: impossível remover: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: impossível definir o proprietário do ficheiro: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: impossível definir o grupo do ficheiro: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: impossível definir as permissões do ficheiro: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: falha ao sincronizar o ficheiro: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: falha ao sincronizar a pasta do ficheiro: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Erro ao obter as bandeiras de estado da entrada padrão: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: é uma ligação simbólica, a ignorar" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: é uma pasta, a ignorar" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: não é um ficheiro normal, a ignorar" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: o ficheiro tem o bit setuid ou setgid definido, a ignorar" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: o ficheiro tem o bit sticky definido, a ignorar" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: o ficheiro de entrada tem mais de uma ligação absoluta, a ignorar" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Nome de ficheiro vazio, a ignorar" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Erro ao restaurar as bandeiras de estado para a entrada padrão: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Erro ao obter as bandeiras de estado do ficheiro da saída padrão: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: falha ao abrir a pasta: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: o destino não é um ficheiro normal" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Erro ao restaurar a bandeira O_APPEND para a saída padrão: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: falha ao fechar o ficheiro: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: falha na procura ao tentar criar um ficheiro escasso: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: erro de leitura: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: erro ao procurar o ficheiro: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: fim de ficheiro inesperado" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: erro de escrita: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Desactivado" + +# Espaços adicionados para manter alinhamento com mensagens adjacentes -- Rafael +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Total de memória física (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Número de linhas do processador:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Compressão:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Descompressão:" + +# Espaços reduzidos para manter alinhamento com mensagens adjacentes -- Rafael +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Descompressão multi-linha:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Pré-definição para -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Informação do equipamento:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Limites de uso de memória:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Fluxos:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blocos:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Tamanho comprimido:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Tamanho descomprimido:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Proporção:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Verificar:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Espaço do fluxo:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Memória requerida:" + +# Espaço adicionado para promover alinhamento, vide "xz -lvv foo.xz" +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Tamanho em cabeçalhos:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Número de ficheiros:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Fluxo" + +#: src/xz/list.c +msgid "Block" +msgstr "Bloco" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blocos" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "DesvComp" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "DesvDescomp" + +#: src/xz/list.c +msgid "CompSize" +msgstr "TamComp" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "TamDescomp" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "Total" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Proporção" + +#: src/xz/list.c +msgid "Check" +msgstr "Verificar" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "ValVerif" + +#: src/xz/list.c +msgid "Padding" +msgstr "Espaço" + +#: src/xz/list.c +msgid "Header" +msgstr "Cabeçalho" + +#: src/xz/list.c +msgid "Flags" +msgstr "Bandeiras" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "UsoMem" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtros" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Nenhum" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "SemNome-2" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-3" +msgstr "SemNome-3" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-5" +msgstr "SemNome-5" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-6" +msgstr "SemNome-6" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-7" +msgstr "SemNome-7" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-8" +msgstr "SemNome-8" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-9" +msgstr "SemNome-9" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-11" +msgstr "SemNome-11" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-12" +msgstr "SemNome-12" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-13" +msgstr "SemNome-13" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-14" +msgstr "SemNome-14" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-15" +msgstr "SemNome-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: o ficheiro está vazio" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: muito pequeno para um ficheiro .xz válido" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Fluxos Blocos Comprimido Descomprimido Rácio Verif. Nome de ficheiro" + +#: src/xz/list.c +msgid "Yes" +msgstr "Sim" + +#: src/xz/list.c +msgid "No" +msgstr "Não" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Versão mínima do XZ Utils:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s ficheiro\n" +msgstr[1] "%s ficheiros\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Totais:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list só funciona em ficheiros .xz (--format=xz ou --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Tentar \"lzmainfo\" com ficheiros .lzma." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list não suporta a leitura da entrada padrão" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: erro ao ler nomes de ficheiro: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: fim de entrada inesperado ao ler nomes de ficheiros" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: encontrado carácter nulo ao ler nomes de ficheiro; talvez queira usar \"--files0\" em vez de \"--files\"?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Compressão e descompressão com --robot ainda não são suportadas." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Impossível ler dados da entrada padrão ao ler nomes de ficheiro da entrada padrão" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Erro interno (erro)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Impossível estabelecer gestores de sinais" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Sem teste de integridade; a integridade do ficheiro não será verificada" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Tipo de verificação de integridade não suportada; a integridade do ficheiro não será verificada" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Limite de uso de memória alcançado" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Formato de ficheiro não reconhecido" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Opções não suportadas" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Os dados comprimidos estão corrompidos" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Fim de entrada inesperado" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "São necessários %s MiB de memória. O limitador está desactivado." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "São necessários %s MiB de memória. O limite é %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: cadeia de filtros: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Tente \"%s --help\" para mais informações." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Erro ao imprimir o texto de ajuda (erro: %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Uso: %s [OPÇÃO]... FICHEIRO...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Comprimir ou descomprimir FICHEIROs no formato .xz." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Argumentos obrigatórios para opções longas são também obrigatórios para opções curtas." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Modo de operação:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "forçar compressão" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "forçar descompressão" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "testar integridade do ficheiro comprimido" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "listar informação sobre ficheiros .xz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Modificadores de operação:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "manter (não eliminar) ficheiros de entrada" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "forçar substituição de ficheiros de saída e ligações de (des)compressão" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "escrever na saída padrão e não eliminar ficheiros de entrada" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "não sincronizar o ficheiro de saída com o dispositivo de armazenamento antes de remover o ficheiro de entrada" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "descomprimir só o primeiro fluxo e ignoras silenciosamente possíveis dados de entrada restantes" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "não criar ficheiros esparsos ao descomprimir" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "usar o sufixo \".SUF\" em ficheiros comprimidos" + +#: src/xz/message.c +msgid "FILE" +msgstr "FICH" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "ler nomes de ficheiro a processar de FICH; se FICH for omitido, os nomes serão lidos da entrada padrão; os nomes de ficheiro devem terminar com o carácter de nova linha" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "como --files, mas usa o carácter nulo como terminador" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Opções básicas de formato e compressão de ficheiro:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMATO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "formato de ficheiro a codificar/descodificar; os valores possíveis são \"auto\" (pré-definição), \"xz\", \"lzma\", \"lzip\", e \"raw\"" + +#: src/xz/message.c +msgid "NAME" +msgstr "NOME" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "tipo de teste de integridade: 'none' (use com cautela), 'crc32', 'crc64' (pré-definição), ou 'sha256'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "não verificar a integridade ao descomprimir" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "pré-definição de compressão; a pré-definição é 6; ter em conta o uso de memória do compressor *e* descompressor antes de usar 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "tentar melhorar o rácio de compressão usando mais tempo de CPU; não afecta os requisitos de memória do descompressor" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "NÚM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "usa no máximo NÚM linhas; a pré-definição é 1; defina para 0 para usar tantas linhas como núcleos de processadores haja" + +#: src/xz/message.c +msgid "SIZE" +msgstr "TAMANHO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "iniciar novo bloco .xz após cada TAM bytes de entrada; use para definir o tamanho de bloco para compressão com linhas" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOCOS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "iniciar um bloco .xz após os intervalos de dados descomprimidos indicados, separados por vírgulas; optionalmente, especifique umnúmero de cadeia de filtro (0-9) seguido de ':' antes do tamanho descomprimido" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "ao comprimir, se mais de NÚM milissegundos tiverem passado desde o despejo anterior e ler mais dados daentrada bloquearia, todos os dados pendentes serão despejados" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "LIMITE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "definir limite de uso da memória para compressão, decompressão, descompressão em linhas, ou todos; LIMITE em bytes, % de RAM, ou 0 para pré-definições" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "se as configurações de compressão excederem o limite de uso de memória, devolve um erro em vez de reduzir as configurações" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Cadeia de filtragem personalizada para compressão (alternativa às pré-definições):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTROS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "definir a cadeia de filtros usando a sintaxe da cadeia de filtragem liblzma; use --filters-help para mais informação" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "definir cadeias de filtros adicionais usando a sintaxe da cadeia de filtragem liblzma com --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "mostrar mais informação sobre a sintaxe da cadeia de filtragem liblzma e sair" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "OPÇS" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 ou LZMA2; OPÇS é uma lista separada por vírgulas de zero ou mais das seguintes opções (valores válidos; pré-definição):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "PRE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "repor opções numa pré-definição" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "tamanho do dicionário" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "número de bits de contexto literais" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "número de bits de posição literais" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "número de bits de posição" + +#: src/xz/message.c +msgid "MODE" +msgstr "MODO" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "modo de compressão" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "tamanho simpático duma correspondência" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "localizador de correspondências" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "profundidade máxima de procura; 0=automática (pré-definição)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "filtro x86 BCJ (32-bit e 64-bit)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "filtro ARM BCJ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "filtro ARM-Thumb BCJ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "filtro ARM64 BCJ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "Filtro PowerPC BCJ (só big endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "filtro IA-64 (Itanium) BCJ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "Filtro SPARC BCJ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "Filtro RISC-V BCJ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "OPÇS válidas para todos os filtros BCJ:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "desvio inicial para conversões (pré-definição=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Filtro Delta; OPTS válidas (valores válidos; pré-definição):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "distância entre bytes subtraídos uns dos outros" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Outras opções:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "suprimir avisos; especificar duas vezes para suprimir também os erros" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "ser verboso; especificar duas vezes para ainda mais detalhes" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "fazer avisos não afecta o estado da saída" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "usar mensagens analisáveis por máquina (útil para scripts)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "mostra a quantidade total de RAM e os limites de uso de memória actualmente activos e sai" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "mostrar a ajuda curta (lista só as opções básicas)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "mostrar a ajuda longa e sair" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "mostrar esta ajuda curta e sair" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "mostrar a ajuda longa (lista também as opções avançadas)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "mostrar o número da versão e sai" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Sem FICH, ou quando FICH é -, lê da entrada padrão." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Relatar erros em <%s> (em inglês ou finlandês)." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "Página inicial %s: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ESTA É UMA VERSÃO DE DESENVOLVIMENTO NÃO DESTINADA A USO EM PRODUÇÃO." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "As cadeias de filtragem são definidas com --filters=FILTERS ou --filters1=FILTERS ... --filters9=FILTERS. Cada filtro na cadeia pode ser separado por espaços ou '--'. Como alternativa, pode especificar uma pré-definição %s em vez da cadeia de filtragem." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Os filtros suportados e respectivas opções são:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "As opções devem ser pares \"nome=valor\" separados por vírgulas" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: nome de opção inválido" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Valor de opção inválido" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Predefinição LZMA1/LZMA2 não suportada: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "A soma de lc e lp não deve exceder 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: nome de ficheiro com sufixo desconhecido, a ignorar" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: o ficheiro já tem o sufixo \"%s\", a ignorar" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: sufixo de nome de ficheiro inválido" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "O valor não é um inteiro decimal não-negativo" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: sufixo multiplicador inválido" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Sufixos válidos são \"KiB\" (2^10), \"MiB\" (2^20) e \"GiB\" (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "O valor da opção \"%s\" deve estar no intervalo [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Dados comprimidos não podem ser lidos de um terminal" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Dados comprimidos não podem ser escritos num terminal" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Uso: %s [--help] [--version] [FICH]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Mostrar informação no cabeçalho do ficheiro .lzma." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "O ficheiro é muito pequeno para um ficheiro .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Não é um ficheiro .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "A escrita para a saída padrão falhou" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Erro desconhecido" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Pré-definição não suportada" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Bandeira não suportada na pré-definição" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Nome de opção desconhecido" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "O valor da opção não pode estar vazio" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Valor fora do intervalo" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Esta opção não suporta sufixos de multiplicação" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Sufixo multiplicador inválido (KiB, MiB, ou GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Nome de filtro desconhecido" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Impossível utilizar este filtro com o formato .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Falha ao alocar memória" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Não são permitidas cadeias vazias, tente \"6\" se precisa de uma pré-definição" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "O número máximo de filtros é quatro" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Nome de filtro em falta" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Cadeia de filtragem inválida ('lzma2' em falta no fim?)" diff --git a/cpp/third_party/xz-5.8.3/po/pt_BR.gmo b/cpp/third_party/xz-5.8.3/po/pt_BR.gmo new file mode 100644 index 0000000000000000000000000000000000000000..82858f7617876e6fbcea8675aacd016043573bf1 GIT binary patch literal 15660 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/pt_BR.po b/cpp/third_party/xz-5.8.3/po/pt_BR.po new file mode 100644 index 000000000..07b3d73ad --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/pt_BR.po @@ -0,0 +1,1683 @@ +# SPDX-License-Identifier: 0BSD +# +# Brazilian Portuguese translations for xz package +# Traduções em português brasileiro para o pacote xz. +# This file is published under the BSD Zero Clause License. +# Rafael Fontenelle , 2019-2024. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.6.0-pre2\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2024-09-22 23:10-0300\n" +"Last-Translator: Rafael Fontenelle \n" +"Language-Team: Brazilian Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"X-Generator: Gtranslator 46.1\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Argumento inválido para --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Argumentos demais para --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "Em --block-list, está faltando o tamanho do bloco após o número da cadeia de filtros \"%c:\"" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 só pode ser usado como o último elemento em --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Tipo de formato de arquivo desconhecido" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Tipo de verificação de integridade sem suporte" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Somente um arquivo pode ser especificado com \"--files\" ou \"--files0\"." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "A variável de ambiente %s contém argumentos demais" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Suporte a compressão foi desabilitado em tempo de compilação" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Suporte a descompressão foi desabilitado em tempo de compilação" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "A compactação de arquivos lzip (.lz) não é suportada" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list é ignorado a menos que seja compactado para o formato .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Com --format=raw, --suffix=.SUF é exigido, a menos que esteja escrevendo para stdout" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "O número máximo de filtros é quatro" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Erro na opção --filters%s=FILTROS:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "O limite de uso de memória é baixo demais para a configuração de filtro dada." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "cadeia de filtros %u usada por --block-list, mas não especificada com --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "O uso de uma predefinição em modo bruto é desencorajado." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "As opções exatas de predefinições podem variar entre versões do software." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "O formato .lzma possui suporte apenas ao filtro LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 não pode ser usado com o formato .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "A cadeia de filtros %u é incompatível com --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Alternando para o modo de thread única por causa de --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Opções sem suporte na cadeia de filtros %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Usando até % threads." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Opções de filtro ou cadeia de filtros sem suporte" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "A descompressão precisará de %s MiB de memória." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Reduzido o número de threads de %s para %s para não exceder o limite de uso de memória de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Reduzido o número de threads de %s para um. O limite de uso de memória automática de %s MiB ainda está sendo excedido. %s MiB de memória é necessário. Continuando de qualquer maneira." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Alternando para o modo de thread única para não exceder o limite de uso de memória de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Ajustado o tamanho de dicionário de LZMA%c de %s MiB para %s MiB para não exceder o limite de uso de memória de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Tamanho do dicionário LZMA%c ajustado para --filters%u de %s MiB para %s MiB para não exceder o limite de uso de memória de %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Erro ao alterar para a cadeia de filtros %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Erro ao criar um pipe: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() falhou: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: O arquivo parece ter sido movido, não será removido" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Não foi possível remover: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Não foi possível definir o dono do arquivo: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Não foi possível definir o grupo do arquivo: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Não foi possível definir as permissões do arquivo: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Fechamento do arquivo falhou: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Fechamento do arquivo falhou: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Erro ao obter os sinalizadores de status da entrada padrão: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: É um link simbólico, ignorando" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: É um diretório, ignorando" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Não é um arquivo comum, ignorando" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: O arquivo possui o bit setuid ou setgid definido, ignorando" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: O arquivo possui o bit sticky definido, ignorando" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: O arquivo de entrada possui mais de um link físico, ignorando" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Nome de arquivo vazio, ignorando" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Erro ao restaurar os sinalizadores de status para entrada padrão: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Erro ao obter os sinalizadores de status de arquivo da saída padrão: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Fechamento do arquivo falhou: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%s: Não é um arquivo comum, ignorando" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Erro ao restaurar o sinalizador O_APPEND para a saída padrão: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Fechamento do arquivo falhou: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Busca falhou ao tentar criar um arquivo esparso: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Erro de leitura: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Erro ao buscar o arquivo: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Fim de arquivo inesperado" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Erro de escrita: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Desabilitado" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Quantidade total de memória física (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Número de threads de processador:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Compactação:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Descompactação:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Descompactação com várias threads:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Padrão para -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Informações de hardware:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Memory usage limits:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Fluxos:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blocos:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Tamanho compactado:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Tamanho não compactado:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Proporção:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Verificação:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Ajuste do fluxo:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Memória exigida:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Tamanhos nos cabeçalhos:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Número de arquivos:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Fluxo" + +#: src/xz/list.c +msgid "Block" +msgstr "Bloco" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blocos" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "DeslocComp" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "DeslocDescomp" + +#: src/xz/list.c +msgid "CompSize" +msgstr "TamComp" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "TamDescomp" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "TamTotal" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Proporção" + +#: src/xz/list.c +msgid "Check" +msgstr "Verificação" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "ValorVerific." + +#: src/xz/list.c +msgid "Padding" +msgstr "Preench." + +#: src/xz/list.c +msgid "Header" +msgstr "Cabeçalho" + +#: src/xz/list.c +msgid "Flags" +msgstr "Sinalizadores" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "UsoMem" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtros" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Nenhuma" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Incógnito2" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Incógnito3" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Incógnito5" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Incógnito6" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Incógnito7" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Incógnito8" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Incógnito9" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Incógnito11" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Incógnito12" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Incógnito13" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Incógnito14" + +# Não exceder 10 caracteres e espaços não são permitidos -- Rafael +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Incógnito15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: O arquivo está vazio" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Pequeno demais para ser um arquivo .xz válido" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Fluxos Blocos Comprimido Descomprimid Propo Verif Nome de Arquivo" + +#: src/xz/list.c +msgid "Yes" +msgstr "Sim" + +#: src/xz/list.c +msgid "No" +msgstr "Não" + +#: src/xz/list.c +#, fuzzy +#| msgid " Minimum XZ Utils version: %s\n" +msgid "Minimum XZ Utils version:" +msgstr " Versão mínima do XZ Utils: %s\n" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s arquivo\n" +msgstr[1] "%s arquivos\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Totais:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list funciona apenas em arquivos .xz (--format=xz ou --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Tente 'lzmainfo' com arquivos .lzma." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list não possui suporte a leitura da entrada padrão" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Erro ao ler nomes de arquivo: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Fim da entrada inesperado ao ler nomes de arquivos" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Caractere nulo encontrado ao ler nomes de arquivos; talvez você queria usar \"--files0\" em vez de \"--files\"?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Ainda não há suporte a compressão e descompressão com --robot." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Não é possível ler dados da entrada padrão ao ler nomes de arquivos da entrada padrão" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Erro interno (bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Não foi possível estabelecer manipuladores de sinais" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Sem verificação de integridade; não será verificada a integridade do arquivo" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Tipo de verificação de integridade sem suporte; não será verificada a integridade do arquivo" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Limite de uso de memória alcançado" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Formato de arquivo não reconhecido" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Opções sem suporte" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Os dados comprimidos estão corrompidos" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Fim da entrada inesperado" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB de memória é necessário. O limitador está desabilitado." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB de memória é necessário. O limite é %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Cadeia de filtros: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Tente \"%s --help\" para mais informações." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "Usage: %s [OPTION]... [FILE]...\n" +#| "Compress or decompress FILEs in the .xz format.\n" +#| "\n" +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" +"Uso: %s [OPÇÕES]... [ARQUIVO]...\n" +"Comprime e descomprime ARQUIVOs no formato .xz.\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Argumentos obrigatórios para opções longas também o são para opções curtas.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr " Modo de operação:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force compression" +msgstr "Descompactação:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force decompression" +msgstr "Descompactação:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +" Modificadores de opções:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "A escrita para a saída padrão falhou" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --single-stream decompress only the first stream, and silently\n" +#| " ignore possible remaining input data" +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" +" --single-stream descomprime apenas o primeiro fluxo, e ignora de forma\n" +" silenciosa possíveis dados de entrada restantes" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Basic file format and compression options:\n" +msgid "Basic file format and compression options:" +msgstr "" +"\n" +" Opções básicas de formato de arquivo e compressão:\n" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --ignore-check don't verify the integrity check when decompressing" +msgid "don't verify the integrity check when decompressing" +msgstr " --ignore-check não faz a verificação de integridade ao descomprimir" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -0 ... -9 compression preset; default is 6; take compressor *and*\n" +#| " decompressor memory usage into account before using 7-9!" +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" +" -0 ... -9 predefinição de compressão; padrão é 6; leve o uso de\n" +" memória do compressor *e* descompressor em conta\n" +" antes de usar 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -e, --extreme try to improve compression ratio by using more CPU time;\n" +#| " does not affect decompressor memory requirements" +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" +" -e, --extreme tenta melhorar a proporção de compressão usando mais\n" +" tempo de CPU; não afeta os requisitos de memória do\n" +" descompressor" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -T, --threads=NUM use at most NUM threads; the default is 0 which uses\n" +#| " as many threads as there are processor cores" +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" +" -T, --threads=NÚM usa no máximo NÚM threads; o padrão é 0 que usa\n" +" o máximo de threads que há de núcleos de processador" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-size=SIZE\n" +#| " start a new .xz block after every SIZE bytes of input;\n" +#| " use this to set the block size for threaded compression" +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" +" --block-size=TAM\n" +" inicia novo bloco .xz após cada TAM bytes de entrada;\n" +" use isso para definido o tamanho de bloco para\n" +" compressão com threads" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-list=BLOCKS\n" +#| " start a new .xz block after the given comma-separated\n" +#| " intervals of uncompressed data; optionally, specify a\n" +#| " filter chain number (0-9) followed by a ':' before the\n" +#| " uncompressed data size" +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" +" --block-list=BLOCOS\n" +" inicia um novo bloco .xz após os intervalos dados,\n" +" separados por vírgula, de dados descomprimidos;\n" +" opcionalmente, especifique um número de cadeia de\n" +" filtros (0-9) seguido por um ':' antes do tamanho\n" +" dos dados descompactados" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --flush-timeout=TIMEOUT\n" +#| " when compressing, if more than TIMEOUT milliseconds has\n" +#| " passed since the previous flush and reading more input\n" +#| " would block, all pending data is flushed out" +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" +" --flush-timeout=TEMPO-LIMITE\n" +" ao comprimir, se mais de TEMPO-LIMITE milissegundos\n" +" tiverem passado desde a liberação anterior e a leitura\n" +" de mais entrada bloquearia, todos os dados pendentes\n" +" serão liberados" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --no-adjust if compression settings exceed the memory usage limit,\n" +#| " give an error instead of adjusting the settings downwards" +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" +" --no-adjust se configurações de compressão exceder o limite\n" +" de uso de memória, fornece um erro em vez de\n" +" ajustar as configurações para baixo" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Custom filter chain for compression (alternative for using presets):" +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" +"\n" +" Cadeia de filtros personalizada para compressão (alternativa à predefinição):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " --filters=FILTERS set the filter chain using the liblzma filter string\n" +#| " syntax; use --filters-help for more information" +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" +"\n" +" --filters=FILTROS define a cadeia de filtros usando a sintaxe de filtro\n" +" do liblzma; use --filters-help para mais informações" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters1=FILTERS ... --filters9=FILTERS\n" +#| " set additional filter chains using the liblzma filter\n" +#| " string syntax to use with --block-list" +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" +"--filters1=FILTROS ... --filters9=FILTROS\n" +" define cadeias de filtros adicionais usando a sintaxe\n" +" de filtro liblzma para usar com --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters-help display more information about the liblzma filter string\n" +#| " syntax and exit." +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" +" --filters-help exibe mais informações sobre a sintaxe de filtro liblzma\n" +" e sai." + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Number of processor threads:" +msgid "number of position bits" +msgstr "Número de threads de processador:" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "compression mode" +msgstr "Descompactação:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +" Outras opções:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -Q, --no-warn make warnings not affect the exit status" +msgid "make warnings not affect the exit status" +msgstr " -Q, --no-warn faz os avisos não afetarem o status de saída" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr " --robot usa mensagens analisáveis por máquina (útil p/ scripts)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --info-memory display the total amount of RAM and the currently active\n" +#| " memory usage limits, and exit" +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" +" --info-memory exibe a quantidade total de RAM e os limites de uso\n" +" de memória atualmente ativos e sai" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version exibe o número de versão e sai" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"Sem ARQUIVO, ou quando ARQUIVO é -, lê da entrada padrão.\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"Relate erros para <%s> (em inglês ou finlandês).\n" +"Relate erros de tradução para .\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "Site do %s: <%s>\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ESSA É UMA VERSÃO DE DESENVOLVIMENTO, NÃO DESTINADA PARA USO EM PRODUÇÃO." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "" +#| "Filter chains are set using the --filters=FILTERS or\n" +#| "--filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain\n" +#| "can be separated by spaces or '--'. Alternatively a preset <0-9>[e] can be\n" +#| "specified instead of a filter chain.\n" +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" +"As cadeias de filtros são definidas usando as opções --filters=FILTROS ou\n" +"--filters1=FILTROS ... --filters9=FILTROS. Cada filtro na cadeia pode ser\n" +"separado por espaços ou \"--\". Alternativamente, uma predefinição <0-9>[e]\n" +"pode ser especificada em vez de uma cadeia de filtros.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Os filtros suportados e suas opções são:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be 'name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s: As opções devem ser pares \"nome=valor\" separados por vírgulas" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Nome de opção inválido" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s: Valor de opção inválido" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Predefinição LZMA1/LZMA2 sem suporte: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "A soma de lc e lp não deve exceder 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: O nome de arquivo tem um sufixo desconhecido, ignorando" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: O arquivo já tem o sufixo \"%s\", ignorando" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Sufixo de nome de arquivo inválido" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%s: O valor não é um inteiro integral decimal" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Sufixo multiplicador inválido" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Sufixos válidos são \"KiB\" (2^10), \"MiB\" (2^20) e \"GiB\" (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "O valor da opção \"%s\" deve estar no intervalo [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Dados comprimidos não podem ser lidos de um terminal" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Dados comprimidos não podem ser escrito para um terminal" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" +"Uso: %s [--help] [--version] [ARQUIVO]...\n" +"Mostra informações armazenadas no cabeçalho do arquivo .lzma" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Show information stored in the .lzma file header." +msgstr "" +"Uso: %s [--help] [--version] [ARQUIVO]...\n" +"Mostra informações armazenadas no cabeçalho do arquivo .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Arquivo é pequeno demais para ser um arquivo .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Não é um arquivo .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "A escrita para a saída padrão falhou" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Erro desconhecido" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "Opções sem suporte" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "Opções de filtro ou cadeia de filtros sem suporte" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s: Nome de opção inválido" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s: Sufixo multiplicador inválido" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s: Tipo de formato de arquivo desconhecido" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "LZMA1 não pode ser usado com o formato .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "O número máximo de filtros é quatro" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -z, --compress force compression\n" +#~ " -d, --decompress force decompression\n" +#~ " -t, --test test compressed file integrity\n" +#~ " -l, --list list information about .xz files" +#~ msgstr "" +#~ " -z, --compress força a compressão\n" +#~ " -d, --decompress força a descompressão\n" +#~ " -t, --test testa a integridade do arquivo comprimido\n" +#~ " -l, --list lista informações sobre arquivos .xz" + +#~ msgid "" +#~ " -k, --keep keep (don't delete) input files\n" +#~ " -f, --force force overwrite of output file and (de)compress links\n" +#~ " -c, --stdout write to standard output and don't delete input files" +#~ msgstr "" +#~ " -k, --keep mantém (não exclui) os arquivos de entrada\n" +#~ " -f, --force força a sobrescrita do arquivo de entrada e a \n" +#~ " (des)compressão de links\n" +#~ " -c, --stdout escreve a entrada padrão e não exclui os arquivos\n" +#~ " de entrada" + +#~ msgid "" +#~ " --no-sparse do not create sparse files when decompressing\n" +#~ " -S, --suffix=.SUF use the suffix '.SUF' on compressed files\n" +#~ " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~ " omitted, filenames are read from the standard input;\n" +#~ " filenames must be terminated with the newline character\n" +#~ " --files0[=FILE] like --files but use the null character as terminator" +#~ msgstr "" +#~ " --no-sparse não cria arquivos esparsos ao descomprimir\n" +#~ " -S, --suffix=.SUF usa o sufixo \".SUF\" em arquivos comprimidos\n" +#~ " --files[=ARQUIVO]\n" +#~ " lê nomes de arquivos para processar de ARQUIVO;\n" +#~ " se ARQUIVO for omitido, nomes de arquivos são\n" +#~ " lidos da entrada padrão; nomes de arquivos devem\n" +#~ " terminar com o caractere de nova linha\n" +#~ " --files0[=ARQUIVO]\n" +#~ " similar a --files, mas usa o caractere nulo como\n" +#~ " terminador" + +#~ msgid "" +#~ " -F, --format=FMT file format to encode or decode; possible values are\n" +#~ " 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'\n" +#~ " -C, --check=CHECK integrity check type: 'none' (use with caution),\n" +#~ " 'crc32', 'crc64' (default), or 'sha256'" +#~ msgstr "" +#~ " -F, --format=FMT formato de arquivo para codificar ou decodificar;\n" +#~ " valores possíveis são\n" +#~ " \"auto\" (padrão), \"xz\", \"lzma\", \"lzip\" e \"raw\"\n" +#~ " -C, --check=VERIF tipo de verificação de integridade: \"none\" (cuidado!),\n" +#~ " \"crc32\", \"crc64\" (padrão) ou \"sha256\"" + +#, no-c-format +#~ msgid "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " --memlimit-mt-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " set memory usage limit for compression, decompression,\n" +#~ " threaded decompression, or all of these; LIMIT is in\n" +#~ " bytes, % of RAM, or 0 for defaults" +#~ msgstr "" +#~ " --memlimit-compress=LIMITE\n" +#~ " --memlimit-decompress=LIMITE\n" +#~ " --memlimit-mt-decompress=LIMITE\n" +#~ " -M, --memlimit=LIMITE\n" +#~ " define o limite de uso de memória para compressão,\n" +#~ " descompressão, compactação em threads ou todas essas;\n" +#~ " LIMITE é em bytes, % de RAM ou 0 para padrões" + +#~ msgid "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n" +#~ " --lzma2[=OPTS] more of the following options (valid values; default):\n" +#~ " preset=PRE reset options to a preset (0-9[e])\n" +#~ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM number of literal context bits (0-4; 3)\n" +#~ " lp=NUM number of literal position bits (0-4; 0)\n" +#~ " pb=NUM number of position bits (0-4; 2)\n" +#~ " mode=MODE compression mode (fast, normal; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM maximum search depth; 0=automatic (default)" +#~ msgstr "" +#~ "\n" +#~ "--lzma1[=OPÇÕES] LZMA1/LZMA2; OPÇÕES é uma lista separada por vírgula de\n" +#~ "--lzma2[=OPÇÕES] zero ou + das opções abaixo (valores válidos, padrão):\n" +#~ " preset=PRE redefine opções para predefinição (0-9[e])\n" +#~ " dict=NÚM tam. de dicionário (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NÚM núm. de bits de contexto literal (0-4; 3)\n" +#~ " lp=NÚM núm. de bits de posição literal (0-4; 0)\n" +#~ " pb=NÚM núm. de bits de posição (0-4; 2)\n" +#~ " mode=MODO modo de compressão (fast, normal; normal)\n" +#~ " nice=NÚM tam. de nice de correspondência (2-273; 64)\n" +#~ " mf=NOME localizador de correspondência\n" +#~ " (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM máximo de profundidade de pesquisa;\n" +#~ " 0=automatic (padrão)" + +#~ msgid "" +#~ "\n" +#~ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~ " --arm[=OPTS] ARM BCJ filter\n" +#~ " --armthumb[=OPTS] ARM-Thumb BCJ filter\n" +#~ " --arm64[=OPTS] ARM64 BCJ filter\n" +#~ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~ " --sparc[=OPTS] SPARC BCJ filter\n" +#~ " --riscv[=OPTS] RISC-V BCJ filter\n" +#~ " Valid OPTS for all BCJ filters:\n" +#~ " start=NUM start offset for conversions (default=0)" +#~ msgstr "" +#~ "\n" +#~ " --x86[=OPÇÕES] filtro BCJ x86 (32 bits e 64 bits)\n" +#~ " --arm[=OPÇÕES] filtro BCJ ARM\n" +#~ " --armthumb[=OPÇÕES] filtro BCJ ARM-Thumb\n" +#~ " --arm64[=OPÇÕES] filtro BCJ ARM64\n" +#~ " --powerpc[=OPÇÕES] filtro BCJ PowerPC (big endian apenas)\n" +#~ " --ia64[=OPÇÕES] filtro BCJ IA-64 (Itanium)\n" +#~ " --sparc[=OPÇÕES] filtro BCJ SPARC\n" +#~ " --riscv[=OPÇÕES] filtro BCJ RISC-V\n" +#~ " OPÇÕES válidas para todos os filtros BCJ:\n" +#~ " start=NUM deslocamento inicial para conversões\n" +#~ " (padrão=0)" + +#~ msgid "" +#~ "\n" +#~ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" +#~ " dist=NUM distance between bytes being subtracted\n" +#~ " from each other (1-256; 1)" +#~ msgstr "" +#~ "\n" +#~ " --delta[=OPÇÕES] filtro delta; OPÇÕES válidas (valores válidos, padrão):\n" +#~ " dist=NÚM distância entre bytes sendo subtraído\n" +#~ " de cada um (1-256; 1)" + +#~ msgid "" +#~ " -q, --quiet suppress warnings; specify twice to suppress errors too\n" +#~ " -v, --verbose be verbose; specify twice for even more verbose" +#~ msgstr "" +#~ " -q, --quiet suprime avisos, use duas vezes para suprimir erros também\n" +#~ " -v, --verbose ser detalhado; use duas vezes para ainda mais detalhes" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help exibe a ajuda curto (lista apenas as opções básicas)\n" +#~ " -H, --long-help exibe essa ajuda longa e sai" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help exibe essa ajuda curta e sai\n" +#~ " -H, --long-help exibe a ajuda longa (lista também as opções avançadas)" + +#~ msgid "Failed to enable the sandbox" +#~ msgstr "Falha ao habilitar o sandbox" + +#~ msgid "Sandbox is disabled due to incompatible command line arguments" +#~ msgstr "Sandbox está desabilitado em razão de argumentos de linha de comando incompatíveis" + +#~ msgid "Sandbox was successfully enabled" +#~ msgstr "Sandbox foi habilitado com sucesso" + +# Espaços adicionados para manter alinhamento com mensagens adjacentes -- Rafael +#~ msgid "Memory usage limit for compression: " +#~ msgstr "Limite de uso de memória para compressão: " + +#~ msgid " Streams: %s\n" +#~ msgstr " Fluxos: %s\n" + +#~ msgid " Blocks: %s\n" +#~ msgstr " Blocos: %s\n" + +#~ msgid " Ratio: %s\n" +#~ msgstr " Proporção: %s\n" + +#~ msgid " Check: %s\n" +#~ msgstr " Verificação: %s\n" + +#~ msgid "" +#~ " Streams:\n" +#~ " Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding" +#~ msgstr "" +#~ " Fluxos:\n" +#~ " Fluxo Blocos DeslocComp DeslocDescomp TamanhoComp TamanhoDescomp Propo Verif Ajuste" + +#~ msgid "" +#~ " Blocks:\n" +#~ " Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check" +#~ msgstr "" +#~ " Blocos:\n" +#~ " Fluxo Bloco DeslocComp DeslocDescomp TamanhoTotal TamanhoDecomp Propo Verif" + +#~ msgid " CheckVal %*s Header Flags CompSize MemUsage Filters" +#~ msgstr " ValVerif %*s Cabeç Sinaliz TamComp UsoMem Filtros" + +#~ msgid "The selected match finder requires at least nice=%" +#~ msgstr "O localizador de correspondência selecionado requer pelo menos nice=%" diff --git a/cpp/third_party/xz-5.8.3/po/quot.sed b/cpp/third_party/xz-5.8.3/po/quot.sed new file mode 100644 index 000000000..eb0e08dad --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/quot.sed @@ -0,0 +1,17 @@ +# Sed script that converts quotations, by replacing ASCII quotation marks +# with Unicode quotation marks. +# +# Copyright (C) 2001 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 file is offered as-is, without any warranty. +# +# Written by Bruno Haible , 2001. +# +s/"\([^"]*\)"/“\1â€/g +s/`\([^`']*\)'/‘\1’/g +s/ '\([^`']*\)' / ‘\1’ /g +s/ '\([^`']*\)'$/ ‘\1’/g +s/^'\([^`']*\)' /‘\1’ /g +s/“â€/""/g diff --git a/cpp/third_party/xz-5.8.3/po/remove-potcdate.sed b/cpp/third_party/xz-5.8.3/po/remove-potcdate.sed new file mode 100644 index 000000000..8c70dfbf1 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/remove-potcdate.sed @@ -0,0 +1,25 @@ +# Sed script that removes the POT-Creation-Date line in the header entry +# from a POT file. +# +# Copyright (C) 2002 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 any warranty. +# +# The distinction between the first and the following occurrences of the +# pattern is achieved by looking at the hold space. +/^"POT-Creation-Date: .*"$/{ +x +# Test if the hold space is empty. +s/P/P/ +ta +# Yes it was empty. First occurrence. Remove the line. +g +d +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/cpp/third_party/xz-5.8.3/po/ro.gmo b/cpp/third_party/xz-5.8.3/po/ro.gmo new file mode 100644 index 0000000000000000000000000000000000000000..0c8bdccbe18406a1b2944915ed7e46156c1b7b9f GIT binary patch literal 30418 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 eum#s?Ql>a+h1A, 2022 - 2025. +# +# Cronologia traducerii fiÈ™ierului „xzâ€: +# Traducerea iniÈ›ială, făcută de R-GC, pentru versiunea xz 5.2.5. +# Actualizare a traducerii pentru versiunea 5.2.6 (nepublicată în TP), făcută de R-GC, 2022. +# Actualizare a algoritmului formelor de plural (de la „trei†la „patru†experimental). +# Actualizare a traducerii pentru versiunea 5.4.0-pre1, făcută de R-GC, noi-2022. +# Actualizare a traducerii pentru versiunea 5.4.0-pre2, făcută de R-GC, dec-2022. +# Actualizare a traducerii pentru versiunea 5.4.3, făcută de R-GC, mai-2023. +# Actualizare a traducerii pentru versiunea 5.4.4-pre1, făcută de R-GC, iul-2023. +# Actualizare a traducerii pentru versiunea 5.6.0-pre1, făcută de R-GC, feb-2024. +# Actualizare a traducerii pentru versiunea 5.6.0-pre2, făcută de R-GC, feb-2024. +# Actualizare a traducerii pentru versiunea 5.7.1-dev1, făcută de R-GC, ian-2025. +# Actualizare a traducerii pentru versiunea 5.8.0-pre1, făcută de R-GC, mar-2025. +# Actualizare a traducerii pentru versiunea Y, făcută de X, Z(luna-anul). +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.8.0-pre1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-03-09 19:21+0100\n" +"Last-Translator: Remus-Gabriel Chelu \n" +"Language-Team: Romanian \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n==1) ? 0 : (n==2) ? 1 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 2 : 3);\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.5\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Argument nevalid pentru opÈ›iunea „--block-listâ€" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Prea multe argumente pentru opÈ›iunea „--block-listâ€" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "ÃŽn „--block-listâ€, dimensiunea blocului lipseÈ™te după numărul lanÈ›ului de filtrare „%câ€:" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 poate fi folosit doar ca ultimul element din opÈ›iunea „--block-listâ€" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Tip de format de fiÈ™ier necunoscut" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Tip de verificare a integrității neacceptat" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Numai un fiÈ™ier poate fi specificat cu „--files†sau „--files0â€." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Variabila de mediu „%s†conÈ›ine prea multe argumente" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Suportul de comprimare a fost dezactivat în timpul construirii" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Suportul de decomprimare a fost dezactivat în timpul construirii" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Comprimarea fiÈ™ierelor lzip (.lz) nu este acceptată" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "opÈ›iunea „--block-list†este ignorată dacă nu se comprimă în formatul .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Cu opÈ›iunea „--format=rawâ€, este necesară opÈ›iunea „--suffix=.SUFâ€, cu excepÈ›ia cazului în care se scrie la ieÈ™irea standard" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Numărul maxim de filtre este patru" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Eroare în opÈ›iunea „--filters%s=FILTREâ€:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Limita de utilizare a memoriei este prea mică pentru configurarea dată filtrului." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "lanÈ›ul de filtre %u este utilizat de „--block-listâ€, dar nu este specificat cu „--filters%u=â€" + +# Notă: +# cu toate că sunt împotriva americanismelor, am preferat folosirea cuvîntului american, „românizatâ€, pentru a avea o traducere fluidă, fără construcÈ›ii încărcate È™i inecesare... +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Utilizarea unei presetări în modul brut este descurajată." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "OpÈ›iunile exacte ale presetărilor pot varia între versiunile de software." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Formatul .lzma acceptă numai filtrul LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 nu poate fi utilizat cu formatul .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "LanÈ›ul de filtre %u este incompatibil cu opÈ›iunea „--flush-timeoutâ€" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Se trece la modul cu un singur fir de execuÈ›ie datorită opÈ›iunii „--flush-timeoutâ€" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "OpÈ›iuni neacceptate în lanÈ›ul de filtre %u" + +# NOTÄ‚: +# - să intru în contact cu dezvoltatorii, pentru ai ruga să introducă a doua formă de plural +# (necesară cel puÈ›in pentru limba română): +# „Se utilizează până la % de fire.†+# **** +# construcÈ›ie necesară pentru maÈ™ini cu +# procesoare/nuclee > 10 +# === +# cred că deja au apărut astfel de „monÈ™trii†+#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Se utilizează până la % fire de execuÈ›ie." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "LanÈ› de filtre sau opÈ›iuni de filtrare neacceptate" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Decomprimarea va avea nevoie de %sMio de memorie." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Numărul de fire de execuÈ›ie a fost redus de la %s la %s pentru a nu se depăși limita de utilizare a memoriei de %sMio" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "S-a redus numărul de fire de execuÈ›ie de la %s la unul. Limita automată de utilizare a memoriei de %sMio este încă depășită. Sunt necesari %sMio de memorie. Se continuă în ciuda acestui lucru." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "S-a trecut la modul cu un singur-fir de execuÈ›ie pentru a nu se depăși limita de utilizare a memoriei de %sMio" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "S-a ajustat dimensiunea dicÈ›ionarului LZMA%c de la %sMio la %sMio pentru a nu se depăși limita de utilizare a memoriei de %sMio" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "S-a ajustat dimensiunea dicÈ›ionarului LZMA%c pentru „--filters%u†de la %sMio la %sMio pentru a nu depăși limita de utilizare a memoriei de %sMio" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Eroare la schimbarea lanÈ›ului de filtrare %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Eroare la crearea unei conducte: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() a eÈ™uat: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: FiÈ™ierul pare să fi fost mutat, nu eliminat" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Nu se poate elimina: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Nu se poate configura proprietarul fiÈ™ierului: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Nu se poate configura grupul proprietar al fiÈ™ierului: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Nu se pot configura permisiunile fiÈ™ierului: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Sincronizarea fiÈ™ierului a eÈ™uat: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Sincronizarea directorului fiÈ™ierului a eÈ™uat: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Eroare la obÈ›inerea indicatorilor de stare a fiÈ™ierului de la intrarea standard: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Este o legătură simbolică, se omite" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Este un director, se omite" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Nu este un fiÈ™ier obiÈ™nuit, se omite" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: FiÈ™ierul are activaÈ›i biÈ›ii «setuid» sau «setgid», se omite" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: FiÈ™ierul are activat bitul lipicios(sticky), se omite" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: FiÈ™ierul de intrare are mai mult de o legătură dură, se omite" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Numele fiÈ™ierului este gol, se omite" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Eroare la restabilirea indicatorilor de stare la intrarea standard: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Eroare la obÈ›inerea indicatorilor de stare a fiÈ™ierului de la ieÈ™irea standard: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Deschiderea directorului a eÈ™uat: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: DestinaÈ›ia nu este un fiÈ™ier obiÈ™nuit" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Eroare la restabilirea indicatorului O_APPEND la ieÈ™irea standard: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: ÃŽnchiderea fiÈ™ierului a eÈ™uat: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Căutarea a eÈ™uat când se încerca crearea unui fiÈ™ier dispers(sparse): %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Eroare de citire: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Eroare la explorarea fiÈ™ierului: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: SfârÈ™it neaÈ™teptat al fiÈ™ierului" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Eroare de scriere: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Dezactivat" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Cantitatea totală de memorie fizică (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Numărul de fire de execuÈ›ie ale procesorului:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Comprimare:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Decomprimare:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Decomprimare cu multiple-fire de execuÈ›ie:" + +# R-GC, scrie: +# ATENÈšIE: +# este vorba de: +# T0 = momentul 0, È™i nu de: +# TO = la, către. pe, în... +# **** +# probabil tipul de literă folosit de mine în Poedit, să +# nu diferenÈ›ieze prea mult O de 0... +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Implicit pentru -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "InformaÈ›ii despre componentele maÈ™inii:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Limitele de utilizare a memoriei:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Fluxuri:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Blocuri:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Dimensiune comprimată:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Dimensiune decomprimată:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Raport:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Verificare:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Completare flux:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Memorie necesară:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Dim. în antete:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Numărul de fiÈ™iere:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Flux" + +#: src/xz/list.c +msgid "Block" +msgstr "Bloc" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Blocuri" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "PoziÈ›ieComprim" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "PoziÈ›ieDecomprim" + +#: src/xz/list.c +msgid "CompSize" +msgstr "DimComp" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "DimDecomp" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "DimTotală" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Raport" + +#: src/xz/list.c +msgid "Check" +msgstr "Verificare" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "ValVerificare" + +#: src/xz/list.c +msgid "Padding" +msgstr "Completare" + +#: src/xz/list.c +msgid "Header" +msgstr "Antet" + +#: src/xz/list.c +msgid "Flags" +msgstr "Indicatori" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "UtilizareMem" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filtre" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Nici una" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Necunos-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Necunos-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Necunos-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Necunos-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Necunos-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Necunos-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Necunos-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Necunos-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Necunos-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Necunos-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Necunos-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Necunos-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: FiÈ™ierul este gol" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Prea mic pentru a fi un fiÈ™ier .xz valid" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Fluxuri Blocuri Comprimare Decomprimare Raport Verificare Nume fiÈ™ier" + +#: src/xz/list.c +msgid "Yes" +msgstr "Da" + +#: src/xz/list.c +msgid "No" +msgstr "Nu" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Versiunea minimă XZ Utils:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "un fiÈ™ier\n" +msgstr[1] "două fiÈ™iere\n" +msgstr[2] "%s fiÈ™iere\n" +msgstr[3] "%s de fiÈ™iere\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Totaluri:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "„--list†funcÈ›ionează numai pe fiÈ™ierele .xz („--format=xz†sau „--format=autoâ€)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "ÃŽncercaÈ›i «lzmainfo» cu fiÈ™iere .lzma ." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "„--list†nu acceptă citirea de la intrarea standard" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Eroare la citirea numelor de fiÈ™iere: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: SfârÈ™it neaÈ™teptat al intrării la citirea numelor de fiÈ™iere" + +# Adaptînd sugestia făcută de Daniel Șerbănescu asupra traducerii cuvîntului „nullâ€, am modificat +# traducerea de la:„Caracter nul găsit...â€, la: +# „Caracter nul(null) găsit...†+# Sugestia făcută de el în baza obiecÈ›iei că în pagina web, «dexonline» definiÈ›ia cuvîntului nul, este un pic ambiguă; nu are o bază prea solidă, +# din următoarele motive: +# - pagina în cauză e construită, alimentată È™i menÈ›inută de persoane voluntare, precum noi ca traducători de software. +# - intrările pentru definiÈ›ia cuvîntului „nulâ€, sînt extrase din dicÈ›ionare de uz general; niciuna dintre ele, nu a ieÈ™it dintr-un dicÈ›ionar tehnic, cu atît mai puÈ›in unul de informatică. +# - utilizatorul software-ului «xz», direct de la linia de comandă, mă îndoiesc că va fi un utilizator ce nu este familiarizat cu nomenclatura din informatică (pentru restul utilizatorilor, acest mesaj nu va fi vizibil, pentru că-l vor utiliza din spatele unui software „IGU†«InterfațăGrafică(de)Utilizator» +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Caracter nul(null) găsit la citirea numelor de fiÈ™iere; poate aÈ›i vrut să utilizaÈ›i „--files0†în loc de „--filesâ€?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Comprimarea È™i decomprimarea cu „--robot†nu sunt încă acceptate." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Nu se pot citi date de la intrarea standard atunci când se citesc numele de fiÈ™iere de la intrarea standard" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Eroare internă (bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Nu se pot stabili gestionarii de semnal" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Fără verificare a integrității; nu se verifică integritatea fiÈ™ierului" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Tip neacceptat de verificare a integrității; nu se verifică integritatea fiÈ™ierului" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Limita de utilizare a memoriei a fost atinsă" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Formatul fiÈ™ierului nu este recunoscut" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "OpÈ›iuni neacceptate" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Datele comprimate sunt corupte" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "SfârÈ™it neaÈ™teptat al intrării" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "Se necesită %sMio de memorie. Limitarea este dezactivată." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "Se necesită %sMio de memorie. Limita este de %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: LanÈ› de filtre: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "ÃŽncercaÈ›i «%s --help» pentru mai multe informaÈ›ii." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Eroare la afiÈ™area textului de ajutor (cod de eroare %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Utilizare: %s [OPÈšIUNE]... [FIȘIER]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Comprimă sau decomprimă FIȘIER(e) în formatul .xz ." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Argumentele obligatorii pentru opÈ›iunile lungi sunt de asemenea obligatorii pentru opÈ›iunile scurte." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Mod de operare:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "forÈ›ează comprimarea" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "forÈ›ează decomprimarea" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "testează integritatea fiÈ™ierului comprimat" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "listează informaÈ›ii despre fiÈ™ierele .xz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Modificatori operaÈ›ie:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "păstrează (nu È™terge) fiÈ™ierele de intrare" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "forÈ›ează suprascrierea fiÈ™ierului de ieÈ™ire È™i (de)comprimă legăturile" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "scrie la ieÈ™irea standard È™i nu È™terge fiÈ™ierele de intrare" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "nu sincronizează fiÈ™ierul de ieÈ™ire cu dispozitivul de stocare înainte de a elimina fiÈ™ierul de intrare" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "decomprimă doar primul flux È™i ignoră în tăcere posibilele date de intrare rămase" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "nu creează fiÈ™iere disperse când decomprimă" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "utilizează sufixul „.SUF†pentru fiÈ™ierele comprimate" + +#: src/xz/message.c +msgid "FILE" +msgstr "FIȘIER" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "citeÈ™te numele fiÈ™ierelor de procesat din FIȘIER; dacă FIȘIER este omis, numele de fiÈ™iere sunt citite de la intrarea standard; numele de fiÈ™iere trebuie să fie terminate cu caracterul de linie nouă" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "ca „--filesâ€, dar foloseÈ™te caracterul null ca terminator" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Formatul de bază al fiÈ™ierului È™i opÈ›iunile de comprimare:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMAT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "formatul de fiÈ™ier pentru codificare sau decodificare; valorile posibile sunt „auto†(implicit), „xzâ€, „lzmaâ€, „lzip†și „rawâ€" + +#: src/xz/message.c +msgid "NAME" +msgstr "NUME" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "tip de verificare a integrității: „none†(utilizaÈ›i cu precauÈ›ie), „crc32â€, „crc64†(implicit) sau „sha256â€" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "nu se efectuează verificarea integrității la decomprimare" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "presetare comprimare; valoarea implicită este 6; luaÈ›i în considerare memoria utilizată de instrumentul de comprimare *È™i* de instrumentul de decomprimare, înainte de a utiliza presetările 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "încearcă să îmbunătățească raportul de comprimare folosind mai mult timp CPU-ul; nu afectează cerinÈ›ele de memorie ale instrumentului de decomprimare" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "NUMÄ‚R" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "utilizează cel mult NUMÄ‚R fire de execuÈ›ie; valoarea implicită este 0, care utilizează atâtea fire de execuÈ›ie câte nuclee există în procesor" + +#: src/xz/message.c +msgid "SIZE" +msgstr "DIM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "începe un nou bloc .xz după fiecare DIM octeÈ›i de intrare utilizaÈ›i acest lucru pentru a stabili dimensiunea blocului pentru comprimarea cu fire de execuÈ›ie" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOCURI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "începe un nou bloc .xz după intervalele specificate separate prin virgule, de date necomprimate; opÈ›ional, specificaÈ›i un număr de lanÈ› de filtrare (0-9) urmat de „:†înainte de dimensiunea datelor necomprimate" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "la comprimare, dacă au trecut mai mult de NUMÄ‚R de milisecunde de la curățarea anterioară È™i citirea mai multor intrări s-ar bloca, toate datele în aÈ™teptare sunt eliminate" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "LIMITA" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "stabileÈ™te limita de utilizare a memoriei pentru comprimare, decomprimare, decomprimare cu fire sau toate acestea; LIMITA este în octeÈ›i, % din RAM sau 0 pentru valorile implicite" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "dacă valorile de comprimare depășesc limita de utilizare a memoriei, dă o eroare în loc să reducă val. stabilite" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "LanÈ› de filtrare personalizat pentru comprimare (alternativă la utilizarea presetărilor):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTRE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "defineÈ™te lanÈ›ul de filtre folosind sintaxa È™irului de filtre liblzma; utilizaÈ›i „--filters-help†pentru mai multe informaÈ›ii" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "defineÈ™te lanÈ›uri de filtre suplimentare folosind sintaxa È™irului de filtre liblzma pentru a fi utilizate cu opÈ›iunea „--block-listâ€" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "afiÈ™ează mai multe informaÈ›ii despre sintaxa È™irului de filtre liblzma È™i iese" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "OPÈšI" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 sau LZMA2; OPÈšI este o listă separată prin virgule, de niciuna sau de mai multe dintre următoarele opÈ›iuni (între paranteze: valorile valide, È™i cele implicite)" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "PRE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "restabileÈ™te opÈ›iunile la o presetare" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "dimensiunea dicÈ›ionarului" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "numărul de biÈ›i de context literal" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "numărul de biÈ›i de poziÈ›ie literală" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "numărul de biÈ›i de poziÈ›ie" + +#: src/xz/message.c +msgid "MODE" +msgstr "MOD" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "modul de comprimare" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "lungimea „drăguță†a unei potriviri" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "găsitor de potriviri" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "adâncimea maximă de căutare; 0=automată (valoarea implicită)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "filtru BCJ x86 (32-biÈ›i È™i 64-biÈ›i)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "filtru BCJ ARM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "filtru BCJ ARM-Thumb" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "filtru ARM64 BCJ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "filtru BCJ PowerPC (numai big endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "filtru BCJ IA-64 (Itanium)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "filtru BCJ SPARC" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "filtru BCJ RISC-V" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "OPÈšIUNI valide pentru toate filtrele BCJ:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "poziÈ›ia de pornire a conversiilor (implicit=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Filtru delta; OPÈšI valabile (valori valabile; implicit):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "distanÈ›a dintre octeÈ›i fiind dedusă scăzând un octet din celălalt" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Alte opÈ›iuni:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "suprimă avertismentele; specificaÈ›i-o de două ori pentru a suprima È™i erorile" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "descriere detaliată; specificaÈ›i-o de două ori pentru È™i mai multe detalii" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "face ca avertismentele să nu afecteze starea de ieÈ™ire" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "utilizează mesaje analizabile de maÈ™ină (utile pentru scripturi)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "afiÈ™ează cantitatea totală de memorie RAM È™i limitele de utilizare a memoriei active în prezent, È™i iese" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "afiÈ™ează ajutorul scurt (enumeră doar opÈ›iunile de bază)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "afiÈ™ează acest ajutor lung(detaliat) È™i iese" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "afiÈ™ează acest scurt mesaj de ajutor, È™i iese" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "afiÈ™ează mesajul detaliat de ajutor (afiÈ™ează È™i opÈ›iunile avansate)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "afiÈ™ează numărul versiunii, È™i iese" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Fără FIȘIER, sau când FIȘIER este „-â€, citeÈ™te de la intrarea standard." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"RaportaÈ›i erorile la <%s> (în engleză sau finlandeză).\n" +"RaportaÈ›i erorile de traducere la " + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "Pagina principală a %s: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ACEASTA ESTE O VERSIUNE DE DEZVOLTARE, NEDESTINATÄ‚ UTILIZÄ‚RII ÃŽN PRODUCÈšIE." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "LanÈ›urile de filtre sunt definite cu ajutorul opÈ›iunilor „--filters=FILTRE†sau „--filters1=FILTRE ... --filters9=FILTREâ€. Fiecare filtru din lanÈ› poate fi separat prin spaÈ›ii sau „--â€. Alternativ, se poate specifica o presetare %s în locul unui lanÈ› de filtre." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Filtrele acceptate È™i opÈ›iunile acestora sunt:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "OpÈ›iunile trebuie să fie perechi „nume=valoare†separate prin virgule" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Nume de opÈ›iune nevalid" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Valoare nevalidă a opÈ›iunii" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Presetare LZMA1/LZMA2 neacceptată: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Suma de lc È™i lp nu trebuie să depășească 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Numele fiÈ™ierului are un sufix necunoscut, se omite" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: FiÈ™ierul are deja sufixul „%sâ€, se omite" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Sufixul numelui de fiÈ™ier nu este valid" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Valoarea nu este un număr întreg zecimal nenegativ" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Sufix multiplicator nevalid" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Sufixele valide sunt „KiB†(2^10), „MiB†(2^20) È™i „GiB†(2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Valoarea opÈ›iunii „%s†trebuie să fie în intervalul [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Datele comprimate nu pot fi citite de pe un terminal" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Datele comprimate nu pot fi scrise pe un terminal" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Utilizare: %s [--help] [--version] [FIȘIER]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "AfiÈ™ează informaÈ›iile stocate în antetul fiÈ™ierului .lzma ." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Prea mic pentru a fi un fiÈ™ier .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Nu este un fiÈ™ier .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Scrierea la ieÈ™irea standard a eÈ™uat" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Eroare necunoscută" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Presetare neacceptată" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Fanion neadmis în presetare" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Nume de opÈ›iune necunoscut" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Valoarea opÈ›iunii nu poate fi vidă" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Valoare în afara intervalului" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Această opÈ›iune nu acceptă sufixe de multiplicare" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Sufix multiplicator nevalid (KiB, MiB, sau GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Nume de filtru necunoscut" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Acest filtru nu poate fi utilizat în formatul .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Alocarea memoriei a eÈ™uat" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Șirul vid nu este permis, încercaÈ›i „6†dacă este necesară o valoare implicită" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Numărul maxim de filtre este patru" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "LipseÈ™te numele filtrului" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "LanÈ› de filtre nevalid (lipseÈ™te, „lzma2â€, la sfârÈ™it?)" diff --git a/cpp/third_party/xz-5.8.3/po/sr.gmo b/cpp/third_party/xz-5.8.3/po/sr.gmo new file mode 100644 index 0000000000000000000000000000000000000000..979a12df0c607f81cddcea580692232631134086 GIT binary patch literal 36503 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 Ol@91FlM6a*#{UOZ=`;)g literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/sr.po b/cpp/third_party/xz-5.8.3/po/sr.po new file mode 100644 index 000000000..8c4d98726 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/sr.po @@ -0,0 +1,1264 @@ +# SPDX-License-Identifier: 0BSD +# +# Serbian translation of xz. +# This file is published under the BSD Zero Clause License. +# МироÑлав Ðиколић , 2020-2025. +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-02-03 07:28+0100\n" +"Last-Translator: МироÑлав Ðиколић \n" +"Language-Team: Serbian <(nothing)>\n" +"Language: sr\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" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.5\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: ÐеиÑправан аргумент за „--block-list“" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Превише аргумената за „--block-list“" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "У „--block-list“, величина блока недоÑтаје након ланца филтера број „%c:“" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 Ñе може кориÑтити Ñамо као поÑледњи елемент у „--block-list“-у" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Ðепозната врÑта формата датотеке" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Ðеподржана врÑта провере целовитоÑти" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Само једну датотеку можете навеÑти Ñа „--files“ или „--files0“." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Променљива окружења „%s“ Ñадржи превише аргумената" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Подршка запакивања је иÑкључена у време изградње" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Подршка раÑпакивања је иÑкључена у време изградње" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Запакивање „lzip“ датотека (.lz) није подржано" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "„--block-list“ Ñе занемарује оÑим ако Ñе пакује у „.xz“ формат" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Са „--format=raw“, „--suffix=.SUF“ је потребно оÑим ако Ñе пише на Ñтандардни излаз" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Ðајвећи број филтера је четири" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Грешка у опцији „--filters%s=ФИЛТЕРИ“:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Ограничење коришћења меморије је премало за дато подешавање филтера." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "ланац филтера „%u“ је коришћен од „--block-list“ али није наведен Ñа „--filters%u=“" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Коришћење претподешавања у Ñировом режиму је обеÑхрабрујуће." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Тачне опције претподешавања Ñе могу разликовати од издања до издања Ñофтвера." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Формат „.lzma“ подржава Ñамо „LZMA1“ филтер" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "Ðе можете кориÑтити „LZMA1“ Ñа „.xz“ форматом" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Ланац филтера „%u“ није ÑаглаÑан Ñа „--flush-timeout“" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Пребацујем Ñе на режим једне нити због „--flush-timeout“" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Ðеподржане опције у ланцу филтера %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "КориÑтим до % нити." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Ðеподржан ланац филтера или опције филтера" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "За раÑпакивање ће бити потребно %s MiB меморије." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Број нити је Ñмањен Ñа %s на %s да Ñе не би прекорачило ограничење коришћења меморије од %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Број нити је Ñмањен Ñа %s на једну. ÐутоматÑко ограничење коришћења меморије од %s MiB је ипак премашено. %s MiB меморије је потребно. Ипак наÑтављам." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Прелазим на режим једне нити да Ñе не би прекорачило ограничење коришћења меморије од %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Величина „LZMA%c“ речника је промењена Ñа %s на %s да Ñе неби прекорачило ограничење коришћења меморије од %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Величина „LZMA%c“ речника је промењена за „--filters%u“ Ñа %s MiB на %s MiB да Ñе не прекорачи ограничење коришћења меморије од %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Грешка промене на ланац филтера „%u“: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Грешка Ñтварања Ñпојке: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: „poll()“ није уÑпело: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Изгледа да је датотека премештена, не уклањам" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Ðе могу да уклоним: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Ðе могу да поÑтавим влаÑника датотеке: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Ðе могу да поÑтавим групу датотеке: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Ðе могу да поÑтавим овлашћења датотеке: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: УÑклађивање датотеке није уÑпело: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: УÑклађивање директоријума датотеке није уÑпело: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Грешка добављања заÑтавица Ñтања датотеке Ñа Ñтандардног улаза: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: ЈеÑте Ñимболичка веза преÑкачем" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: ЈеÑте директоријум, преÑкачем" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Ðије обична датотека, преÑкачем" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Датотека има поÑтављен „setuid“ или „setgid“ бит, преÑкачем" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Датотека има поÑтављен лепљиви бит, преÑкачем" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Улазна датотека има више од једне чврÑте везе, преÑкачем" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Празан назив датотеке, преÑкачем" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Грешка повраћаја заÑтавица Ñтања на Ñтандардни улаз: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Грешка добављања заÑтавица Ñтања датотеке Ñа Ñтандардног излаза: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Отварање директоријума није уÑпело: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: Одредиште није обична датотека" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Грешка повраћаја заÑтавице „O_APPEND“ на Ñтандардни излаз: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Затварање датотеке није уÑпело: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Премотавање није уÑпело приликом покушаја прављења оÑкудне датотеке: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Грешка читања: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Грешка приликом претраге датотеке: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Ðеочекиван крај датотеке" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Грешка пиÑања: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "ИÑкључено" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Укупна количина физичке меморије (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Број нити процеÑора:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Запакивање:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "РаÑпакивање:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Вишенитно раÑпакивање:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "ОÑновно за „-T0“:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "О хардверу:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Ограничење коришћења меморије:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Токови:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Блокови:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Величина Ñажетог:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Величина неÑажетог:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "ОдноÑ:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Провери:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Попуна тока:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Потребна меморија:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Величине у заглављима:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Број датотека:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Ток" + +#: src/xz/list.c +msgid "Block" +msgstr "Блок" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Блокови" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "ПомерЗапак" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "ПомерÐÑжтог" + +#: src/xz/list.c +msgid "CompSize" +msgstr "ВлчнаЗапак" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "ВлчнаÐÑжтог" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "УкупнаВлчна" + +#: src/xz/list.c +msgid "Ratio" +msgstr "ОдноÑ" + +#: src/xz/list.c +msgid "Check" +msgstr "Провери" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "ПровериВредн" + +#: src/xz/list.c +msgid "Padding" +msgstr "Попуна" + +#: src/xz/list.c +msgid "Header" +msgstr "Заглавље" + +#: src/xz/list.c +msgid "Flags" +msgstr "ЗаÑтавице" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "КоришћМемор" + +#: src/xz/list.c +msgid "Filters" +msgstr "Филтери" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Ðишта" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Ðезнано-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Ðезнано-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Ðезнано-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Ðезнано-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Ðезнано-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Ðезнано-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Ðезнано-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Ðезнано-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Ðезнано-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Ðезнано-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Ðезнано-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Ðезнано-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Датотека је празна" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Премало је да би било иÑправна „.xz“ датотека" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Токови Блокови Запаковано РаÑпаковано ÐžÐ´Ð½Ð¾Ñ ÐŸÑ€Ð¾Ð²ÐµÑ€Ð° Датотека" + +#: src/xz/list.c +msgid "Yes" +msgstr "Да" + +#: src/xz/list.c +msgid "No" +msgstr "Ðе" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Ðајмање издање XZ помагала:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s датотека\n" +msgstr[1] "%s датотеке\n" +msgstr[2] "%s датотека\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Укупно:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "„--list“ ради Ñамо над „.xz“ датотекама (--format=xz или --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Пробајте „lzmainfo“ Ñа „.lzma“ датотекама." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "„--list“ не подржава читање Ñа Ñтандардног улаза" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Грешка читања назива датотека: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Ðеочекивани крај улаза приликом читања назива датотека" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Ðађох ништаван знак приликом читања назива датотека; можда Ñте хтели да кориÑтите „--files0“ умеÑто „--files“?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Запакивање и раÑпакивање Ñа „--robot“ није још подржано." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Ðе могу да читам податке Ñа Ñтандардног улаза приликом читања назива датотека Ñа Ñтандардног улаза" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Унутрашња грешка (бубица)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Ðе могу да уÑпоÑтавим руковаоце Ñигналом" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Ðема провере целовитоÑти; не проверавам целовитоÑÑ‚ датотеке" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Ðеподржана врÑта провере целовитоÑти; не проверавам целовитоÑÑ‚ датотеке" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Ограничење коришћења меморије је доÑтигнуто" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Ðије препознат формат датотеке" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Ðеподржане опције" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Запаковани подаци Ñу оштећени" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Ðеочекиван крај улаза" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB меморије је потребно. Ограничавач је онемогућен." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB меморије је потребно. Ограничење је %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Ланац филтера: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Пробајте „%s --help“ за више података." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Грешка иÑпиÑивања текÑта помоћи (код грешке %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Коришћење: %s [ОПЦИЈÐ]... [ДÐТОТЕКÐ]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Пакује или раÑпакује ДÐТОТЕКЕ у „.xz“ формату." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Обавезни аргументи за дуге опције Ñу такође обавезни и за кратке опције." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Режим рада:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "приморава запакивање" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "приморава раÑпакивање" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "иÑпробава целовитоÑÑ‚ запаковане датотеке" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "иÑпиÑује информације о „.xz“ даттотекама" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Измењивачи рада:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "задржава (не брише) улазне датотеке" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "приморава препиÑивање излазне датотеке и (раÑ)пакује везе" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "пише на Ñтандардни излаз и не брише улазне датотеке" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "не уÑклађује излазну датотеку Ñа Ñмештајним уређајем пре уклањања улазне датотеке" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "раÑпакује Ñамо први ток, и тихо занемарује могуће преоÑтале улазне податке" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "не Ñтвара привидне датотеке када раÑпакује" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "кориÑти ÑÑƒÑ„Ð¸ÐºÑ â€ž.SUF“ на запакованим датотекама" + +#: src/xz/message.c +msgid "FILE" +msgstr "ДÐТОТЕКÐ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "чита називе датотека процеÑу из ДÐТОТЕКÐ; ако је ДÐТОТЕКРизоÑтављено, називи датотека Ñе читају Ñа Ñтандардног улаза; називи датотека Ñе морају завршавати знаком новог реда" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "иÑто као „--files“ али кориÑти знак ништице као окончавач" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "ОÑновне опције формата датотеке и запакивања:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "ФОРМÐТ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "формат датотеке за шифровање или дешифровање; могуће вредноÑти Ñу „auto“ (оÑновно), xz, lzma, lzip, и raw" + +#: src/xz/message.c +msgid "NAME" +msgstr "ÐÐЗИВ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "врÑта провере целовитоÑти: „none“ (кориÑтите уз опрез), „crc32“, „crc64“ (оÑновно), или „sha256“" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "не потврђује проверу целовитоÑти приликом раÑпакивања" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "претподешавање запакивања; оÑновно је 6; узмите у обзир коришћење меморије запакивања *и* раÑпакивања пре него ли употребите 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "покушава да побољша Ð¾Ð´Ð½Ð¾Ñ Ð·Ð°Ð¿Ð°ÐºÐ¸Ð²Ð°ÑšÐ° кориÑтећи више времена процеÑора; не утиче на потребе меморије раÑпакивача" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "БРОЈ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "кориÑти највише БРОЈ нити; оÑновно је 0 за коришћење онолико нити колико има језгара процеÑора" + +#: src/xz/message.c +msgid "SIZE" +msgstr "ВЕЛИЧИÐÐ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "започиње нови „.xz“ блок након Ñвака ВЕЛИЧИÐРбајта улаза; кориÑтите ово да поÑтавите величину блока за нитирано запакивање" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "БЛОКОВИ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "започиње нови „.xz“ блок након датих зарезом одвојених интервала неÑажетих података; изборно, наводи број ланца филтера (0-9) за којим Ñледе „:“ пре величине неÑажетих података" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "приликом запакивања, ако је прошло више од ВРЕМЕ_ИСТЕКРмилиÑекунди до претходног убацивања и читања још улаза блокираће, Ñви подаци на чекању Ñе иÑтиÑкују ван" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "ОГРÐÐИЧЕЊЕ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "поÑтавља ограничење коришћења меморије за запакивање, раÑпакивање, раÑпакивање нити или за Ñве ово; ОГРÐÐИЧЕЊЕ је у бајтовима, % РÐМ-а или 0 за оÑновно" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "ако подешавања запакивања пређу ограничење коришћења меморије, даје грешку умеÑто дотеривања подешавања" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Произвољни ланац филтера за запакивање (алтернатива за коришћење предподешавања):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "ФИЛТЕРИ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "поÑтавља ланац филтера кориÑтећи ÑинтакÑу ниÑке „liblzma“ филтера; кориÑтите „--filters-help“ за више информација" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "поÑтавља додатне ланце филтера кориÑтећи ÑинтакÑу ниÑке „liblzma“ филтера за коришћење Ñа „--block-list“" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "приказује више информација о ÑинтакÑи ниÑке „liblzma“ филтера и излази" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "ОПЦИЈЕ" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 или LZMA2; ОПЦИЈЕ је зарезом раздвојен ÑпиÑак нула или више Ñледећих опција (иÑправне вредноÑти; оÑновно):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "ПРЕ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "враћа опције на предподешеноÑÑ‚" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "величина речника" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "број битова контекÑта литерала" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "број битова положаја литерала" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "број битова положаја" + +#: src/xz/message.c +msgid "MODE" +msgstr "РЕЖИМ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "режим запакивања" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "фина дужина поклапања" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "поклапа налазача" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "највећа дубина претраге; 0=аутоматÑки (оÑновно)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ филтер (32-бита и 64-бита)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ филтер" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BCJ филтер" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ филтер" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ филтер (Ñамо велика крајноÑÑ‚)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (Itanium) BCJ филтер" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ филтер" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ филтер" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "ИÑправне ОПЦИЈЕ за Ñве BCJ филтере:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "померај почетка за претварање (оÑновно=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Делта филтер; иÑправне ОПЦИЈЕ (иÑправне вредноÑти; оÑновно):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "раÑтојање између бајтова који Ñу одузети један од другог" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "ОÑтале опције:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "потиÑкује упозорења; наведите два пута да би потиÑкивао и грешке" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "бива опширан; наведите два пута за још више опширноÑти" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "чини да упозорења не делују на Ñтање излаза" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "кориÑти поруке обрадиве рачунаром (кориÑно за Ñкрипте)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "приказује укупан Ð¸Ð·Ð½Ð¾Ñ Ð ÐМ-а и тренутно ограничење коришћења активне меморије, и излази" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "приказује кратку помоћ (иÑпиÑује Ñамо оÑновне опције)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "приказује ову опширну помоћ и излази" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "приказује ову кратку помоћ и излази" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "приказује дугу помоћ (иÑпиÑује такође и напредне опције)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "приказује број издања и излази" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Без ДÐТОТЕКЕ, или када је ДÐТОТЕКР-, чита Ñтандардни улаз." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Грешке пријавите на <%s> (на енглеÑком или финÑком)." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "„%s“ матична Ñтраница: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ОВО ЈЕ РÐЗВОЈÐО ИЗДÐЊЕ И ÐИЈЕ ÐÐМЕЊЕÐО ЗРПРОФЕСИОÐÐЛÐУ УПОТРЕБУ." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Ланци филтера Ñу поÑтављени Ñа опцијама „--filters=ФИЛТЕРИ“ или „--filters1=ФИЛТЕРИ“ ... „--filters9=ФИЛТЕРИ“. Сваки филтер у ланцу Ñе може одвојити размацима или „--“. Или предподешеноÑÑ‚ „%s“ Ñе може навеÑти умеÑто ланца филтера." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Подржани филтери и њихове опције Ñу:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Опције морају бити парови „назив=вредноÑт“ раздвојени зарезима" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: ÐеиÑправан назив опције" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "ÐеиÑправна вредноÑÑ‚ опције" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Ðеподржано претподешавање „LZMA1/LZMA2“: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Збир „lc“ и „lp“ не Ñме премашити 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Ðазив датотеке има непознат ÑуфикÑ, преÑкачем" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Датотека већ има ÑÑƒÑ„Ð¸ÐºÑ â€ž%s“, преÑкачем" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: ÐеиÑправан ÑÑƒÑ„Ð¸ÐºÑ Ð½Ð°Ð·Ð¸Ð²Ð° датотеке" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "ВредноÑÑ‚ није не-негативан децимални цео број" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: ÐеиÑправан ÑÑƒÑ„Ð¸ÐºÑ ÑƒÐ¼Ð½Ð¾Ð¶Ð°Ð²Ð°Ñ‡Ð°" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "ИÑправни ÑуфикÑи Ñу KiB (2^10), MiB (2^20), и GiB (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "ВредноÑÑ‚ опције „%s“ мора бити у опÑегу [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Запаковани подаци Ñе не могу читати из терминала" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Запаковани подаци Ñе не могу пиÑати на терминал" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Коришћење: %s [--help] [--version] [ДÐТОТЕКÐ]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Приказује информације Ñмештене у заглављу „.lzma“ датотеке." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Датотека је премала да би била „.lzma“ датотека" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Ðије „.lzma“ датотека" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "ПиÑање на Ñтандардни излаз није уÑпело" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Ðепозната грешка" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Ðеподржано предподешавање" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Ðеподржана заÑтавица у предподешавању" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Ðепознат назив опције" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "ВредноÑÑ‚ опције не може бити празна" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "ВредноÑÑ‚ је ван опÑега" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Ова опција не подржава никакве ÑуфикÑе умножавача" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "ÐеиÑправан ÑÑƒÑ„Ð¸ÐºÑ ÑƒÐ¼Ð½Ð¾Ð¶Ð°Ð²Ð°Ñ‡Ð° (KiB, MiB, или GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Ðепознат назив филтера" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Филтер Ñе не може кориÑтити у „.xz“ формату" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Додела меморије није уÑпела" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Празна ниÑка није дозвољена, пробајте 6 ако је оÑновна вредноÑÑ‚ потребна" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Ðајвећи број филтера је четири" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "ÐедоÑтаје назив филтера" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "ÐеиÑправан ланац филтера („lzma2“ недоÑтаје на крају?)" diff --git a/cpp/third_party/xz-5.8.3/po/stamp-po b/cpp/third_party/xz-5.8.3/po/stamp-po new file mode 100644 index 000000000..9788f7023 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/stamp-po @@ -0,0 +1 @@ +timestamp diff --git a/cpp/third_party/xz-5.8.3/po/sv.gmo b/cpp/third_party/xz-5.8.3/po/sv.gmo new file mode 100644 index 0000000000000000000000000000000000000000..93c65cb07b4d799dd3550523065867fe1889096d GIT binary patch literal 28399 zcmb`P3w&Hxedlk;3k-x15(w`bh$1=h2>F>rj!9%&wiR2Fv1BI%Lb%dgNfXW78RpK& zR?3D~0vi?xEfCsW3fp2s3xxnJF0h3xhzQ6kHAb1eh=RVruh2T1h zKCcD)!PkLXz>k9GfWP*5)?g>kG1$xX%fKgtcY;0OXZ`gr z!6$Kj-uXdrF}MkQ8h8V!dbfj*1mElLe*#>`^{+s^@50B@1{?%01nc1A!PkOM1m6Yn zir_Qg6Tt6-A$aQJ99{^{aXk#G{X0R;^9$f0_F2z?(tUKL%1I_%yfy z{2r+HoX;OU-wZwqybjcO6YvV~7H}i@VQ?GxOYk&sBZJoaE(6a3>)^TI%^=GayasH6 zN5L}qScn&bH-lP-H-Vz#Tfo!7&-wfR0G`S9H^315J~$4Z$)c#+&K{eDQ97{Vh=QKRa~ey96BK`U+6Ib~C8@cY+TCzX9$7e+=sRh6{pVEjSHo zzOMu|&o_YU!FPZf&o@DqJh&Si0#A90TaO(eOBz(bt>8;Q(f2M;^#2Vge!1YO&=ed4 zMct?xCU`l*5H zrv+-hw}V>8FN5NfAA=g#lP+@i_kyQ${ammQoBRyC18RIP0`6_a?>8Uq>4+sAWl-~G=$1j7b|09pT^r*q={zE-J8r1tQ@OX*G%^t7x zIO1`_ga3dqs~WiSL^1*-j>pyu;6 z5ET*p9J~rVhed+a!2~!6z5vuZd;nCxzW|59GZ2!^;670N{$fyka};C*&VWxriKzeEz(<0g2OkCg6G)ZdUQpxer?YFpH-UQ3y`Y|-&!j_e3`BH-Iw-#Q zLs0ZN20j}69H@1;8&vx<5$?x;z2Fi=_K1^g)(f!A$wdg^aLt?$2ruLmECkZAnx2E{Kw0DpE0Jb0xW_iwIp z`o3?-(d8OY>r??HuQ!2`%NKy>gD(Zu&zn4c1l0S!2Wp&;*zWK$Q0oLDBI5H~`)Zo(tXyYTh3OQHjBCz$btgBILp$P;`F|7=mq32w-`@wR5_}vy4Se_>=RceSp2hWkQ2pNks-G5kJ9sPjQt-SHNAEX) zr*nN5sP+7qzy7tyQ?7RFbS8KK&(8w)f&<`#!RLby0dEEM-rGUF_l=N)KMV&*|sOK+*3ukM9FT_aA`gfWHD^(O}Ie zx)9t0J`S7&d38_+`@j!?PX)gVif_&wbM1D3JzT#CTnD}tybAmx2x|xDjXV8w5IlqH zXL@`tC_2xATK^-U=6xr4FZf+h`r+&Qojv%8$9ur@xc_gU*5TY|xbZ#?)Ov3QHIJLX z0q~{ZdhoA7$@>q%hk>UaaO-zA_x?8rS|Sp!)k3_%!fmpy+VHwQgNEf$C=~sPSG6UIiWmF9q)aZva07?g#sy>G=Bv z;6|?B1M2?w!3)7luXA*LHrUVg%fJEfI4FMo0r+sRheZ%yZ3Hg?2SLqq20RaZC3r6Q zW`F%Y@UdKf2Glt321T!5_~)lT+sWtSJ@$Bfn#apM?f@mvqaF`=yuss~$LD#x$>U2v z$;m4~jraW?zXv{w>qo+TYr!7y3E((53|2wW;XVHOw?R~W@X+TtJ{<)mr&Vw-_&QK@ z{Wd7RI1l2hpX|dVMSSAg-rDRD3W4YMtK(z8w4@NSDE$$gTHV z!7I5w4r)C2fO^kmQ_haw3_h9b?}A#_Q>UFC=>s=&y${rUUkqyf{{j@h{1!~W&1Gyo zcoYNt%P1QtqK!VEqI{h4-zaM+ zZ=>h~Iqmb0{CzIvF1vEJhNTY<`0EV5!57g@w1gD)xtG6+wOj=LgwmkgPSNKQ2f=ah zyA;vp)s**9eopx_iat9jkluW}w}Ox_IE6mn1hy!@rDUJ~$(P$GKcM^_<#Nh6CHp*_ zFA)XR5d4Y1`72QR;=fY9M_EhJ=kt`SDQ(I%l;2SPl(LSZ&n)FC$|oq<=fVEVzk;a6 z;HQ-HDX*bO2J~rCo<|YSOK&}!l6}Othbf=)H%2)v&1AN=(%z`H5GM|lP1RLY|%Kcl>y@_#7DDEdq|2)+RJ zQ~nd>E0iBovd>xB7x34Vb0{I@wUhpKR?20RcT?U>(dVBXm|i-U?*}QL^!NS!Gz}=KDQ=U(`hw>jO`fQ>s**B;Ep2PPy z`fE(E>Es8&YcKZqehEIqe}5tPQOd_C52c(*c{`=}`3HY-#N)fbn<@X9aua1AMV|^~ zn6gV3eEv7(ag?K!GUX2`ucYYnZw`WYdK7%qfBy@QV;=W|U#BekYe7sojXC{y@N1MO zQuO&gMRVAkIJ^Sf1T*fTlqp9jJGdvkq0bu1@AzEDJ;@$j8vhC4_hFA2YPv_xaXn%TAgB?+l)LRUvR$rh__uVvZ zg)N4se#6;jz1=uzjr!pvZl1J8BW~6zXECA&1ksH*mh;arr4 zy*+7fn6_tTDo56Z>3pTppq;(Rs;UaqX;;c2ujSh;-=;mc(PhdFRnFO zi=Fo{;945C>Wpb24yWQc3AIq=bw&qUwc@xmXB&Q$gzaQLVMR_ji53hrJr`9H5kb5% z7>*>3cFV1{CJ3*_EDL?r6Ls4x!>GypviXf93sIHXN6p!GEl%K=dRQt=RqNC9rD`Q@ z`JP>+Y+?MUx}MeA)mEiZtuQV}_^zk*hH-#q=um%)aujH%aoAfbX};+| zZ&*pv7Q7`LklpRQ(&jPVh?9&Z^XY`kWZ;0>#$xfDV<$W-yP9rjt>&V2RS%~bWebiD z(?--}C>lqn>0&ZH*Q_U%n^wM<0p=3FY!DMGnyJ_2L!GSGp+~Zq^MkSP3WiX%v=%{R z*ahN6p<|H#BR6$~`d|_tX|TXClZX6_O>Z=^t$b85=3RY>d=n=SZq)T=ErM4U8(Dv8 zyV0mO^{z_Nif5aZ)*=iLPtSKMUBk_I**Y}p)oS0`A{B~rmBy;fCJ0g)frJ;*aJpV= zH2LCJO4PPV+kk?S$xK+T$4=GxQFXYkS+9j@D@w`|N1Joj=5W0^pCYQ&MgF)x#eHEP zY-pWtgSKd^{4#2{>T84kiG#a>fpFTyoVF|m%!@p;a57C%+6v=pY@%IBxLN8eKaWY~MG&WA8+;J>sG9vL-7&WIa2K!Rk3}m(oId)cs983jaBu zU&P&Fv~ryBdbn$3-!PJp*g|#Ky+5zd8rnc%LoF*zXoI)4k3yKMh7aIgsqR-+Ka6a) zP|tA4N$Mkx)AeSv-Ec$pU5V|OS0gr`bYK`Y%#O}jj9Z<_ zs6I?ky{Xc$RYnH;t2eF9+?Tvn*DEtgKaAjIUR?-lOtmXj7`%erD~yogB18y=6Fq0i zO>{DvYY=@1btKW0|AYepaoVPMq=DjA3QO+H7fB87#~`{J9Il|k6N#XgOXlqavA?@( zy=f-G#5?((9MFxbSknZ3tJnYI`zI&DK4%N~+m6$%EQB@GV7<2+49iV2+R7m)*lzbA zZ8fD{Gk39Ctsj=pgnbNqw_uHD;1S=e-rJ6?Dzk{of%6nG{mHCX(Oo3&X`3DOwPa>h zD+(KxhO@Bl$!y%R2e~mt_*!jT^lCKA-<4Xt(CY(fTW`1U*$RzKMY|EFJ?S^0C2}}?^;ujOR>~f+#;p~;1kzSB z&Wcq@4xD+qA=X3&IgyO8aBQ41xt^)E)47tQjA?W=!j(kYkrppHT2XWC=(a##v#ZW# ztl_; zY|J(sXfiE1%v$3+Rc0!*F1VkWz&VQaXH&JE1GKU289N+P8y z>6RUY9vjaCvH{I%DG2V0eD8ZIEO z#Mri6aZbR+NUx$}n0Kz>)9pGe05%o$xY_qz(gp(>wg+DUgWP>q=PJ?ll zubFYtV6gwdaIilrD<~7}#|Ss~?=e)o`>-3s$*gSyV1r$iBw*2Ang|LUL*zLchG( zZTFm@RcKomFx=rCYu4?cnO+Q)JowO-mglz14jH?P+65DE)byNYE@V@c=qr+p9;UPS#k@2x`Y6E*4=bZXH$>F|E(E%%Xd(NZeV2t=*@_ zSFIGAzzeF=wok%)G&NBWwoTSqzR$_chPG7t}us-*?g-CpM`c4P#i zIfnMTV0U4!>0)%ZzdS+6iY{DS%AD`~%9BHSH^1j+UA$LXzdn0hTEC(5bz|r2rq0*R z`PWX>PR-8KEqT35^KX~s-!A7{XKjsvpJon@XE*cZi&e6vRkT^Q%3r(bq+Pvfe}sN2 zFmKo6)tdNwYSs0ko_1GLCkkD+6#Ww;=l0tL{O-fXo5Q0yhR<@$bG^QJIpVu^G1uey zuL%k@G3saq-R`bn>OFJanL#r;Y(`sFgDAi>P8K$Wd&? z-yfS>lhl(^63=4xh$rAWRS4ob0>({W*Xth7t#*=<`4N6)n{2M*@L4_8YI|L%zt=zT zrq;64kb?`}YaIvIxLA!-7~3G}I>g+OV4K37B5rm7mxW~&KgujltE^3+^^(*rc4gZF zi!Ez))xNaOMX2)auWe)d1I38*e&k>irgb}GA0rN)i9W)mf?=lWX}pzvowjLZ z+C@KOdB3KNe5F7eR$0x=r|Y`mI6IG%Xmne)hOKBm);7c1!5J4bn2QU}F1Nbe7KDJ% z*)$wS2y-ficnSn-DwmcnzaZ#%$u7h!>oS8MND$220mnM2On8g!s0(_BjXGnN0pq9& z;a6`iPOo5Juq^V+b=s(6sg~>EFq(pdrW304=J)p6Gx|VJx`=H&V$2&KskHKrG)UX_ zSd61jn=C}2n%1qasJsv*@+Q3oS=-gl?T3mDEwrvKr!0QEYO9tEO&H~YVB)?uEH#^M zH=B++SZaw+7ya!FICW%PF$u3-GM`scx~vY1-kIs@&kHjuR$$)_-(`-$)M5)Y;at_U zJ=L-Uu(ETlwcQHqOr;r=opbHanF^;&sf#Oj*o8HxcG3%@`F@8oH^Z+ zH!2^x94|;1JR4@`oYupx1q>BJWO9uB`#S{!=l3`nZc2}tQ7ckc<6`h@vu^B2G!2M@W_P4m*l0_2aR_~~ zLzQ*5J7=ms8dHod*&&OB+}1MduFNqszGj&hW*cQ^XzgTekj*7qDyXY7QzO7MMW-Z*tZA|ot}cu-nYtfH&Hp-9w>%O z5<%B_XEnOBgJJQDz0nD{Ws25^3M1|PWaX6Eh5Sb4uGP;gd322BuB6lE{7tIaUiF1GQp&X?QU0Ins@5OJ_`*ut4EZ0o|bI45k16kTw` z)mTl`T=y;Q6u--pu@H2rK%xAhsWQ-3~!LOC;V_bLi(6 zZQH=wK>H;*aJjZv?)QmgSsmL6+D1RX7`JjI&DhL*9soJAv)?8GR4n?I@wtoOFw|o zt)SJYkL@Ias4aOGpmR9|Xb5SEPUw>(S$tx>p@xTn)R&aCVu26Tkb-IulgBe{gq!iD z)6GhQ(@Sfj_dDM{?3HuhtL%pYGl*hoV7_~H7j3;xYRqV22~L_(jTl`e#S2KvsU=Z0 zA`4UD1EYiW8dh+jQnyn)PK(UiOV!EXc@a|n)Zu!Y16$*JJOX5$3?Hi_wv?b-%!;+d zLI=)VYw@$34sW+*vWxbt%bXp#Y)fI67xr!3P*U=l+HBdRuWN(-&H9a4qS8pYbjSz3 zLxL!q`!DTZU&6gwzs5xqOQR{dYo+bP6ibu!LF!!9YR^ZU<@DE^vupN`mkuy#Z9Gal zIf)t!HwgZuG+}BQ`@M?~2IL4U` zuP8U`l`;dv!MJLctw6P(#dtc+lG!%vTbd-II2cZFOsjl`D_V_Gx^R{3Z@t-X7yW76 zsXiE{3u{J4Mu$6dTi-vhMj=y}wKU1Te$b9IpT>Tol590Af=1eQaB^4avQ9mXcP4I@ zhUEpajDz82jB(BWD!cA#X%_(}vf`44U8dVOz;R!<^(Em2+rss0x30O?C^s1T&@Aq< zQ9uHiOR@1z*Gy%tqz(FMzdI&t($Q>xo$0s2js2Us?=DK)>-G6sL}t%mSX#es{lGf@ zuJ+HeJrzzSQ3A6$-&{JnkoJe$$z)nOnxyhj*ie5l8tM3<|sWZN;PP%k_-fer;Jb%|N?UR*KiLX?KQVbEd zHRaxSUiim7DSy_5bM*#lFkCv$BDnYFjbLR`PfO%wk?tc?D-nisX`eOc*iY1z$SjEdHV#}=zEJ@j`l$D~IP!(G)d$FL2M`Aj^IU3+AHVT=6wV346@n+#E z4_(&k5UrPvHyY@8KV?Rt+<_HRwGSbgi94J>kqJbxwv9WTj~ZAohPDuL;$tTQnZS^H zI5>B99T$@~|aD~_nrbMyr!3f$`X{+RQ z&0`3gxU)RMu~<5eLnD^5Y7_I#%0h8Pdbd2GVKSeH$^!vO* zjO5KUQ3ZC)X|uMWkr?RnS<`5q1Wz}X4!ID46m8Ok-W~s^l4Ol$+AOuY#eY&3Y7L*s zlN5E(mDcJMAv|pFwViaH*$V4tJ!A~eEZCfuVek}QXUSZCE7z57UEvd4wTdXI?gZDu zP4Zs|x@R}8R(dOT(}lCD@w}U{j!1f@OI6|mtdF~wZ^j7eJ393EL|3UT|2=0fqqo_E zltp9>%zmeSRu+VC)*cpYEFJUhgZnuiTZa4jdUPyiz1z2deOHX9I1D>^V-=BuS&RY+ zvgtgR=B^a;V}spIlI`J**;!Ku(B3U;SZ806vm1IK?c_FgWy%J2^gI~ku12gxS(b$5 zR-!DqeOjPq+^OMM(S&aWKZc3iCWc{#O*Lbb(+aNL>xC}JzAylP3o&n&d0Q?jWrZ0n zUeR?^?k@aNxaUoLInL)DS@h)qoa(3o(;^i8g*I*jES2vh)aI6r7}j9!P@Qbr;&^Q8 zc@y#1f_7_S!;>}%za@}stJQBrB-4l z`R5#VZI^Z{zA3e?n1AlYvSw1NQ;V~+txCCTScAb(qRpNQenB4dMx2Ds7l+?RNVAYo z>&PSVR1j1qQ!*GeEv>fL@IFVgv$MXMDQ)HP$fTGfA7!e*q(zyv#om>AfutzJW~!pJ zGP%|nq$nIxHt5*UlTk48@*<0LeQ6h6_G!hNHQ%zrGmuxE5b9&b;htIstDi+;^Chy@l zW1_y9uB^`7($QMW+;8VE@NS~9=D86@SRumqzb$^xverHcS8ql#m;_7^zq-wHov&o32oVR6cCUMA;aY=*G3lVJ*Eu(N) z7?W6kl@7WHqDg7Qd3*QUuz+Z<3Y=3&%FR@=yb(*7Wz?o7)x&+bMLIQ+6#FdGY@riVHi`rpIV^Unx*dDKXmY~mdAGTjU|pnHo^H5mnr?r1C~DrA z2U;tk4O1?@PD$U7SL}Z5g6+v!R7XYoRNu=(pfrQz0vJz@^tN!tKNM} zx9lDc#`$3nNfzYYqvtwX5tC1}tL;xZ9co}&EofTrYH0N_&kV3bD4*EN4R(M!u6FC> z#CNe7DRnl9i*99hhwR>Y+ktiMp4?M&sl7JG8!PyRqJtT(Vwd(dqN9F~$(#tVNOzQ> zuzq{7Aa!I6PH@O#MN;H3PQiWmO^amdSeeY=GPRMXAbvf zTLMy;$8$%V3*(`FDiD3a5-6crY#$t2I(kI^TY)hQ2NcpRPTXvNO!%89DM}Jy?Mi1} zxjldwE_Xn4ooeTddXmft)vK5F^R zR%PhW#PCkioRLG9=e$=LjT1v-nA)+O5=mSXANKJ{&x&t*QFPle8?aedTfZg?GFqwL z2sc=wb6icd(UHzJ!G!Is#j=1L+aFR?*x12+@_Xxq`&~uV&ipGe7VnqsSMS>WJ4a3W z6#l58nRTocH?^N45TVrP2o}%eeYsVfz~!Mc)``StZDdJ&?&!dR*l#k&Oou3nGTF>I zqo%>K(U#+yte}1f=?_A1p=`jWNIK5S3I|2wos-e;Xh`nZn63TE8ZCrw{O<(%w+hp8VElE@J(hEo#M7IZKUJT^nWQ+KZ|k*}#zI@s6&$ z*&tTCi7CQfSj;q9=njz5wVpU<(|bJz-U;mvKzGcnI>K#`oPp)>!*OHNF!Bnj`*)q|YP|4|9PA-fB)v09KwLg0o z+>bx$ls92o?*{Y-yCIgspq&voaWOmD2?r1675#oja*Mo>ge|Gb(y;l?>8-y*Dz+&M zF4^t)n=Tuh)@5dhzkVFLI+6YJPwql~NDbA0}OyhS>3VB+rXn7E&d$V(O6ktynzedj{ zElcDfQ4f9FTEGFC)dmf=vH8K>iB8=LO*oY22eJM7L?sL+Yc+4wEH zTLvH@rPeW~=WDk`l2}^*q!=LQ7h`*r`Q7zO=jmZ;F=-s-`1Xv_XM5+Bb)aR(FWQ)C zh_Vw3`W+_%z|T3bYcAQF*(-6q)kc32@qkGDlXnTDy7eO8GbN9v71W#Msro!oQ5Wte zzeL7a9GzR4kX7zZ*zP8)76V*fiopmXjbD=7Ptn?5R50pjTvz)Kuz5f?o@GZ zR!r9WE-7IcoT!!0S0l!XPE={xe2aCUZVN`1w(*XW(i5FeV~OG9ffFZkaZooKVh6bT z4SD3$)FCd8nMLarf9&SKfQ8J?bbW(%OMIdRo~z}^OFrU6SsmJHdv;acfl>}UYgv;Z zH#F|`8pATfL>H?Jgw~Gj+~N>-H8tSOaJ1mB`EQ<s1g4Ti@T_^84 zhUF@|w~XMvrt?(uxO0){TK>LhVQoS9QB4VH9|7W+-_??2ipsg!@MzvGDb6S6=7jWd zymyQidp_nu){9dS@LD0|K&IOMmmrkNiZ>;388aQMvc8;mlTOa?;)GOjPgx_GDXt0` zP09~iHL*NjKyNYf+;YXVjp6E5j?f zK~8?7m|aflNnbwKfX%sVp-yDo)}4Kj63lHAgoqIVjuwpRIkVQ`1c^g%!^+2*f1egB zEW2q&7ip6}Ziib_WWe*o6O;swS0ejN+HTG4G?8Jd*A$6XGa_2PA>{2odZ{D~S;UAr z!^(R1(I;;qTsSNtwpk`7Wy>J~XU8dpZB({LH&syNyudLiYZ8+D6wC5MYQ2vO2{VRP zvgu5RgxOm!AF1fFUSbhA+_Q;npM<(2`-PXC$S!2Ms&lw1$InC*tIxic)3=pzO!vrh zxH+n14W%SY7o+CRxwPzV<)Skc>{rPKqW=m^k!_OF z+BmV&O8Inky>^+a!23v7$NPY!35#RFd?Thmw?KqA$ni0xl36j0C1;$@+c0+GM!iG} zY_<3#v+yzy-?R=Xh`fTzs2Gg_8vL`z7ZKTb!YuYg|R5F^w9i)Mv-dGEJKE zV0J9y6WVq5piPibMhWd2wX(Hw+X`KChrYct#-7p0ndP)=p7k1jQ<+_x0xG%kP+EH# z5yjl+I?4}lr57w}`pOFSxx)&}Zg-wr*KpvPm~)wqf)6xsJ4jYPx|mYz5aVF&99O5h zp9geX*ct6+mdRN&BnO`V=ci0AuUDsjBh_szQzv)xP5$4_1a)VdR8!$(r27nbi^VmU z`Q`&w$u~e!_~nrtK|8VWTSu!Qw+iLUH1qI2fs7{qRbc)$ScCtqv{kQK25CB_jD^leTjI=jy zFxbM6<%>VG&VIR&{S2C4n&^iB?ng-a{{#4+hWvk#f{xH5c05SvvwF~+*RL8u=mZcB PnH%Z&`2p|Ct^a=q!Sc-; literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/sv.po b/cpp/third_party/xz-5.8.3/po/sv.po new file mode 100644 index 000000000..9dc9da13b --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/sv.po @@ -0,0 +1,1271 @@ +# SPDX-License-Identifier: 0BSD +# +# Swedish translation for xz. +# Copyright (C) The XZ Utils authors and contributors +# This file is published under the BSD Zero Clause License. +# +# Sebastian Rasmussen , 2019. +# Anders Jonsson , 2024. +# Luna Jernberg , 2022, 2023, 2024, 2025. +# # +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-01-24 11:03+0100\n" +"Last-Translator: Luna Jernberg \n" +"Language-Team: Swedish \n" +"Language: sv\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" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.5\n" +"X-Poedit-Bookmarks: -1,10,-1,-1,-1,-1,-1,-1,-1,-1\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Ogiltigt argument till --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: För mÃ¥nga argument till --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "I --block-list saknas blockstorlek efter filterkedjenummer â€%c:â€" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 kan endast användas som det sista elementet i --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Okänd filformatstyp" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Integritetskontrolltyp stöds inte" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Endast en fil kan anges med â€--files†eller â€--files0â€." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Miljövariabeln %s innehÃ¥ller för mÃ¥nga argument" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Komprimeringsstöd inaktiverades vid byggtid" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Dekomprimeringsstöd inaktiverades vid byggtid" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Komprimering av lzip-filer (.lz) stöds inte" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list ignoreras sÃ¥vida du inte komprimerar till .xz-formatet" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Med --format=raw krävs --suffix=.SUF om data inte skrivs till standard ut" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Maximalt antal filter är fyra" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Fel i flagga för --filters%s=FILTER:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Begränsning av minnesanvändning är allt för lÃ¥g för den angivna filteruppsättningen." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "filterkedja %u används av --block-list men inte specificerad med --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Det avrÃ¥ds frÃ¥n att använda en förinställning i rÃ¥tt läge." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "De exakta flaggorna för förinställningar kan variera mellan programversioner." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Formatet .lzma har endast stöd för LZMA1-filtret" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 kan inte användas tillsammans med .xz-formatet" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Filterkedja %u är inkompatibel med --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Växlar till entrÃ¥dsläge pÃ¥ grund av --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Flaggor som inte stöds i filterkedjan %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Använder upp till % trÃ¥dar." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Filterkedja eller filterflaggor stöds inte" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Dekomprimering kommer att kräva %s MiB minne." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Reducerade antalet trÃ¥dar frÃ¥n %s till %s för att inte överstiga begränsningen av minnesanvändning pÃ¥ %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Reducerade antalet trÃ¥dar frÃ¥n %s till en. Den automatiska minnesanvändningsgränsen pÃ¥ %s MiB överskrids fortfarande. %s MiB minne krävs. Fortsätter i alla fall." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Ändrar till enkeltrÃ¥dat läge för att inte överskrida minnesanvändningsgränsen pÃ¥ %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Justerade storlek för LZMA%c-lexikon frÃ¥n %s MiB till %s MiB för att inte överstiga begränsningen av minnesanvändning pÃ¥ %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Justerade storlek för LZMA%c-lexikon för --filters%u frÃ¥n %s MiB till %s MiB för att inte överskrida minnesanvändningsgränsen pÃ¥ %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Fel vid ändring till filterkedja %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Fel vid skapande av rörledning: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() misslyckades: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Filen verkar ha flyttats, tar inte bort" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Kan inte ta bort: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Kan inte sätta filägaren: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Kan inte sätta filgruppen: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Kan inte sätta filrättigheterna: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Synkroniseringen av filen misslyckades: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s:Synkroniseringen av filens katalog misslyckades:: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Fel vid hämtning av filstatusflaggor frÃ¥n standard in: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Är en symbolisk länk, hoppar över" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Är en katalog, hoppar över" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Är inte en vanlig fil, hoppar över" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Filen har setuid- eller setgid-biten satt, hoppar över" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Filen har stickybiten satt, hoppar över" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Indatafilen har mer än en hÃ¥rdlänk, hoppar över" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Tomt filnamn, hoppar över" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Fel vid Ã¥terställning av statusflaggorna för standard in: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Fel vid hämtning av filstatusflaggorna frÃ¥n standard ut: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Att öppna katalogen misslyckades: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: Destinationen är inte en vanlig fil" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Fel vid Ã¥terställning av O_APPEND-flaggan till standard ut: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Stängning av filen misslyckades: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Sökning misslyckades vid skapande av gles fil: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Läsfel: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Fel vid sökning i fil: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Oväntat filslut" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Skrivfel: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Inaktiverad" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Totalt mängd fysiskt minne (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Antal processortrÃ¥dar:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Komprimering:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Dekomprimering:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "FlertrÃ¥dad dekomprimering:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Standard för -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "HÃ¥rdvaruinformation:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Minnesanvändningsgränser:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Strömmar:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Block:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Komprimerad storlek:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Okomprimerad storlek:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "FörhÃ¥llande:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Kontroll:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Strömfyllnad:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Minne som behövs:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Storlek i huvuden:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Antal filer:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Ström" + +#: src/xz/list.c +msgid "Block" +msgstr "Block" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Block" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "Komprimerad position" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "Okomprimerad position" + +#: src/xz/list.c +msgid "CompSize" +msgstr "Komprimerad storlek" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "Okomprimerad storlek" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "Total storlek" + +#: src/xz/list.c +msgid "Ratio" +msgstr "FörhÃ¥llande" + +#: src/xz/list.c +msgid "Check" +msgstr "Kontroll" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "Kontrollvärde" + +#: src/xz/list.c +msgid "Padding" +msgstr "Fyllnad" + +#: src/xz/list.c +msgid "Header" +msgstr "Huvud" + +#: src/xz/list.c +msgid "Flags" +msgstr "Flaggor" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "Minnesanvändning" + +#: src/xz/list.c +msgid "Filters" +msgstr "Filters" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Ingen" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Okänd-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Okänd-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Okänd-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Okänd-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Okänd-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Okänd-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Okänd-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Okänd-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Okänd-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Okänd-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Okänd-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Okänd-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Fil är tom" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: För liten för att vara en giltig .xz-fil" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Strmr Block Komprimerd Okomprimerd Förh. Kntrll Filnamn" + +#: src/xz/list.c +msgid "Yes" +msgstr "Ja" + +#: src/xz/list.c +msgid "No" +msgstr "Nej" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Minsta XZ Utils version:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s fil\n" +msgstr[1] "%s filer\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Total:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list fungerar endast med .xz-filer (--format=xz eller --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Pröva â€lzmainfo†med .lzma-filer." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list saknar stöd för att läsa frÃ¥n standard in" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Fel vid läsning av filnamn: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Oväntat slut av indata vid läsning av filnamn" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Nulltecken hittades vid läsning av filnamn; kanske du menade att använda â€--files0†istället för â€--filesâ€?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Komprimering och dekomprimering med --robot stöds inte än." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Kan inte läsa data frÃ¥n standard in när filnamn läses frÃ¥n standard in" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Internt fel" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Kan inte etablera signalhanterare" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Ingen integritetskontroll; kan inte verifiera filintegritet" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Typ av integritetskontroll stöds inte; verifierar inte filintegritet" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Begränsning av minnesanvändning uppnÃ¥dd" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Filformat okänt" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Flaggor stöds inte" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Komprimerad data är korrupt" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Oväntat avslut av indata" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB minne krävs. Begränsaren inaktiverad." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB minne krävs. Begränsningen är %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Filterkedja: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Testa â€%s --help†för mer information." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Fel vid utskrift av hjälptexten (felkod %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Användning: %s [ALTERNATIV]... [FIL]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "Komprimera eller dekomprimera FILER i formatet .xz." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Obligatoriska argument för lÃ¥nga alternativ är ocksÃ¥ obligatoriska för korta alternativ." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Operationsläge:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "tvinga komprimering" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "tvinga dekomprimering" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "testa den komprimerade filens integritet" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "lista information om .xz-filer" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Operationsmodifierare:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "behÃ¥ll (ta inte bort) indatafiler" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "tvinga överskrift av utdatafilen och (av)komprimera länkar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "skriv till standardutdata och ta inte bort indatafiler" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "synkronisera inte utdatafilen till lagringsenheten innan du tar bort indatafilen" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "dekomprimera endast den första strömmen och ignorera eventuellt kvarvarande indata i tysthet" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "skapa inte glesa filer vid dekomprimering" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "använd suffixet '.SUF' pÃ¥ komprimerade filer" + +#: src/xz/message.c +msgid "FILE" +msgstr "FIL" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "läs filnamn att bearbeta frÃ¥n FIL; om FIL utelämnas läses filnamnen frÃ¥n standardinmatningen; filnamn mÃ¥ste avslutas med nyradstecknet" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "som --filer men använd null-tecknet som terminator" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Grundläggande filformat och komprimeringsalternativ:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMAT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "filformat för kodning eller avkodning; möjliga värden är 'auto' (standard), 'xz', 'lzma', 'lzip' och 'raw'" + +#: src/xz/message.c +msgid "NAME" +msgstr "NAMN" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "integritetskontrolltyp: 'ingen' (använd med försiktighet), 'crc32', 'crc64' (standard) eller 'sha256'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "verifiera inte integritetskontrollen vid dekomprimering" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "förinställd komprimering; standard är 6; ta hänsyn till användningen av kompressor *och* dekomprimeringsminne innan du använder 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "försök att förbättra kompressionsförhÃ¥llandet genom att använda mer CPU-tid; pÃ¥verkar inte dekomprimeringsminneskraven" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "NUM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "använd som mest NUM trÃ¥dar; standard är 0 som använder lika mÃ¥nga trÃ¥dar som det finns processorkärnor" + +#: src/xz/message.c +msgid "SIZE" +msgstr "STORLEK" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "starta ett nytt .xz-block efter varje STORLEK-byte med inmatning; använd detta för att ställa in blockstorleken för flertrÃ¥dad kompression" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOCK" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "starta ett nytt .xz-block efter de givna kommaseparerade intervallen av okomprimerad data; ange eventuellt ett filterkedjenummer (0-9) följt av ett ':' före den okomprimerade datastorleken" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "vid komprimering, om mer än NUM millisekunder har gÃ¥tt sedan föregÃ¥ende tömning och läsning av mer indata skulle blockeras, rensas all väntande data ut" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "GRÄNSVÄRDE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "ställ in minnesanvändningsgräns för komprimering, dekompression, flertrÃ¥dad dekompression eller alla dessa; GRÄNSVÄRDE är i byte, % av RAM-minnet eller 0 för standardinställningar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "om komprimeringsinställningarna överskrider minnesanvändningsgränsen, ge ett felmeddelande istället för att justera inställningarna nedÃ¥t" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Anpassad filterkedja för komprimering (ett alternativ till förinställningar):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTER" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "ställ in filterkedjan med hjälp av liblzma-filtersträngsyntaxen; använd --filters-help för mer information" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "ställ in ytterligare filterkedjor med hjälp av liblzma-filtersträngsyntaxen att använda med --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "visa mer information om liblzma filtersträngsyntax och avsluta" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "ALTERNATIV" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 eller LZMA2; OPTS är en kommaseparerad lista med noll eller fler av följande alternativ (giltiga värden; standard):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "FÖRINSTÄLLNING" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "Ã¥terställ alternativ till en förinställning" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "ordboksstorlek" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "antal bokstavliga kontextbitar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "antal bokstavliga positionsbitar" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "antal positionsbitar" + +#: src/xz/message.c +msgid "MODE" +msgstr "LÄGE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "komprimeringsläge" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "fin längd pÃ¥ en match" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "träffsökare" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "maximalt sökdjup; 0=automatisk (standard)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ-filter (32-bitars och 64-bitars)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ-filter (endast big endian)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (Itanium) BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ-filter" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "Giltiga ALTERNATIV för alla BCJ-filter:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "startoffset för omvandlingar (standard=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Delta filter; giltiga ALTERNATIV (giltiga värden; standard):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "avstÃ¥ndet mellan byte som subtraheras frÃ¥n varandra" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Andra alternativ:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "dämpa varningar; ange tvÃ¥ gÃ¥nger för att dämpa fel ocksÃ¥" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "var utförlig; specificera tvÃ¥ gÃ¥nger för ännu mer utförlighet" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "Ã¥t inte varningar pÃ¥verka avslutningsstatus" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "använd maskintolkningsbara meddelanden (användbara för skript)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "visa den totala mängden RAM och de för närvarande aktiva minnesanvändningsgränserna och avsluta" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "visa den korta hjälpen (visar endast de grundläggande alternativen)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "visa den lÃ¥nga hjälpen och avsluta" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "visa den korta hjälpen och avsluta" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "visa den lÃ¥nga hjälpen (visar även de avancerade alternativen)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "visa versionsnumret och avsluta" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Med FIL, eller när FIL är -, läs standard in." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"Rapportera fel till <%s> (pÃ¥ engelska eller finska).\n" +"Rapportera översättningsfel till " + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "%s hemsida: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "DETTA ÄR EN UTVECKLINGSVERSION SOM INTE ÄR AVSEDD FÖR PRODUKTIONSANVÄNDNING." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Filterkedjor ställs in med alternativen --filters=FILTERS eller --filters1=FILTER ... --filters9=FILTER. Varje filter i kedjan kan separeras med mellanslag eller '--'. Alternativt kan en förinställd %s specificeras istället för en filterkedja." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Filtren som stöds och flaggorna för dem är:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Alternativ mÃ¥ste vara â€namn=värdeâ€-par separerade med kommatecken" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Ogiltigt flaggnamn" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Ogiltigt alternativvärde" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "LZMA1/LZMA2-förinställning stöds inte: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Summan av lc och lp fÃ¥r inte överstiga 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Filnamn har okänd filändelse, hoppar över" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Filen har redan ändelsen â€%sâ€, hoppar över" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Ogiltig filnamnsändelse" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Värdet är inte ett icke-negativt, decimalt heltal" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Ogiltig multipeländelse" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Giltiga suffix är â€KiB†(2^10), â€MiB†(2^20) och â€GiB†(2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Värdet för flaggan â€%s†mÃ¥ste vara inom intervallet [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Komprimerad data kan inte läsas frÃ¥n en terminal" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Komprimerad data kan inte skrivas till en terminal" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Användning: %s [--help] [--version] [FIL]…\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Visa information som lagrats i .lzma-filhuvudet" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Filen är för liten för att vara en giltig .lzma-fil" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Inte en .lzma-fil" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Skrivning till standard ut misslyckades" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Okänt fel" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Förinställning stöds inte" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Flagga som inte stöds i förinställningen" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Okänt alternativnamn" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Alternativvärdet fÃ¥r inte vara tomt" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Värde utanför intervallet" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Det här alternativet stöder inte nÃ¥gra multiplikatorsuffix" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Ogiltigt multiplikatorsuffix (KiB, MiB eller GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Okänt filternamn" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Detta filter kan inte användas med .xz-formatet" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Minnesallokering misslyckades" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Tom sträng är inte tillÃ¥ten, försök '6' om ett standardvärde behövs" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Det maximala antalet filter är fyra" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Filternamn saknas" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Ogiltig filterkedja ('lzma2' saknas pÃ¥ slutet?)" diff --git a/cpp/third_party/xz-5.8.3/po/tr.gmo b/cpp/third_party/xz-5.8.3/po/tr.gmo new file mode 100644 index 0000000000000000000000000000000000000000..80e3501997ad1cd50a5f9478960b7648fbef6419 GIT binary patch literal 28887 zcmb`P3w$I;edpW84_Jc%^D^(Yv5?kY3GKscTk_i8ht?KeNy|!WV-o|dnU>UO9?JC0 z?v5ZP5E93^fPt7-&c_l0*#ro9li<7LHV`6h5(tFjagdP2;S%0l0)+6m3kmuD{#8BQ zGm;kj^T~X+^qcOks;>Ii|6Miv;6>-W>8v0K&g0K8_|iuPLB#jhKQ0K)=K6_Gc6b@M zg`&^B;1KvGa3{D5UIhND#|xhl1m|#l33wj(T<}TYAb1J5*JBL!bA1>1Z14kMANWas z{XOtmTtDgJAh;ad0X`3W38;GafR6`1=W%2Q}UrcrExEa69-Ba2NPJ@EmYEgVy`51}_Bb;1j_+L6$4{ z6|f1u3oL_Ag?J%&C#ZEe4vLPy0iFwf%HRJycs|z;f+6@7a0)!1MNz$5LAAdFggt^X zxCyNK>tmqSZ-W}o-+?T7@HKEZc-EzEJ@$euX^?=U;Lm}g?}tIr|3{$s<&x(> zQ*aU#eeVKA?+<~Z%L=IZ|2e4nd>T~ye+0!}7jf|o@J0|32)4ltYBvswelGyEzPEzv zrwXc{CaC$|18N;V2Z~R=32I!=dak>FGk7l7F9ip{IdBQQ2h=zvL^lEFf{-AX1Vxu6 zP;_a7qTd_AYrtOv_5QyG_1^D;qSFO*4(kMcp!(elJ_5W6JR3X!YF(!M^PdH^9zXB# z%^<8AobbO#R5qu{&dby+9gP_KL!4+fLDPZ2KRwK09mr&+CeA(vmm#EyFEStickIld=z-`kelD7pxRvy zhTuW)(cn*mo4`9k>6^Pj>8bm`$AG^FN^ktJ$IpSP{|%4d^Qgh<{skVN4C?)tc)Y^n zl^(D6IPP)U;~gNP63l~;HuxnF6%l+8)Hps1!ivGyK#ljYFp1>wQjnzy%3uh-4pjRO zfSS)2KvYEV&)^N%m*V7KmsE9|twQZ-XKDI4Y_BR*WNu0@79RPv9JQDN02B-wi$<{51Fk@Jk?7f**n!*ASh(5Ihd*JwF8X{9+~@f|DSk z6VyTR#altq=iT6w!B2r&hp&NZe?G$f6tEw>54;|fT>lODQ{eZ(*MZXzw+#M0SOafF zIsQKQ0I2sZA+!u7cpIqxKLsY>x4{U!eV5Zyr$DXmx4^f6Pen*H{*$2i<*VR3&VmQ8 zcYOZd8ysCe1&SU|+wJt?5GZ-w2TCr-L5=$$sD54sYCT>HN?uNS{JekuZ{TIz5BE6z zH3qU|K?&qh@KzAk3BCYc2tInRdIrxUhC+&CRxd9ZtUk++qzY0DF z`~-+d2j2nJUwEVAkDcHFu5Sg!_wND^f}aJ?0sCM=rVv~XN*-#U_~w=1Mc|vkUj}~* zOu?PwZocmU&*%DM;CArSp!z%S`R@J&;3K(y0@w#W1Dpi+_~&o%&))_;b#lP# zGvoN`AgFbEB`CVw4L%lpHz<045PUB9BT(~s&S6KVJ>V9uXTh_YF&aJNBi$Trz z8Q^yCQc%xt0X3eN`R8@;r@3x{?*qRIUIpI!Lf8J|;6+@28oUzxGWbOB>9@K041*f? zRp2J@Mo@G-1d3nY4)QN}kUwMK)wjFx-0AUmK!zTC1sno*y~yc}3b=#oH~H(2f$HzO zp!jL~Pr3J94_?9b^TEyF5m4iKhsXOt@x>p3PX-_K_rC{T%=NihVP$U*fUkaUL9?-6A*w-U~{uJ_$Yz{1&(k-1K6{54%8EGPo5K zUET}!gI@p#!LwiD_-q)|{OE+-~@DD-t`!As8 z|BT4By95-!+y?$4SOujQz7LANduQGFra|eW6QKC;J0MFG>?}Eb{zg#!{~@UPe;L$x zE-btC-3PMtK^wdl{4Cf2A0Ior@fz?cTz?IGCMahD)e}4mJOWn11@KGYv%!gZ$7faW zQm%g&6dgVXijOa(@-^Tkpz6N}RKG6=pANna6rX$${7vxV;B&xM!n^bw{A=+1moaAW zAHX+*cPv6f@Lxc^@9PyepG#<@b$v1T%itTp{{lX%=JeKkK&``%K=re|?&$I{P~-bC zcoz5!%0E&b!Nvaq2Pvr;(DEfSq@+Xx4Ns*kthoTQ;w~uJ@Qp$(z%JB%S5FGN?89c}rrW8P) z08-iKhx}Ep<+zvgfL0DL^<9h5IqHdFNZH0Ak}7UfpT zk0|e?Y@z5gPq~5ereRD=FtvK0q0v=<_AY?^6DpGD^9ca+31v6n*}$1JgrKK@NXz>e=Ue9=P;)~0>40cCPkmGP&9{UFFAZJxC3UqiBhH%Ry37pq+uie z=~mK+%R}MJLL63-YSPs0zI5oJR*xHMP)^clwn9H@HkVZ5P1%>!zAeP90~1DUuv*7s@3XEhEuH{p-%VRG;W4XhNphR`9{69bjBL>qqVqk#u`g;qne~? zQm-+L>|K?5n$+g=7tKYyuH1RPFHW0DEo#z86V_-W#yj7tL=796&10<5s5iJBmDQI9 zT#Kr4{ucKO??9M?iERC$Zh!B(v} zF3s77AJxKEZL!9RY&eM~3{+Z(lA4GhUKt6;YfG)BTWw7cUX586`l{E|ZKDjM))sr_ zH(omuRhWI$m~U0%8XQv(2M1>>_0r;CB}tpUXICj(7(c46XVq4vnJiTj#^ng#^|ZcZ z9H1Gx`zdTtMubXDM5=d8dYHDWv-L_+T5r&kYq+SVhsjo@BJwn%k_a_dZ`I1-(FN$g zhQ~(3YSf;M!*;!efJcr3tuzk%2M0CZbhtlEYH1VRk`Bo3_Fr%Fm|BW!8B2Di6ZXi! zA+?Rg;vJ5i_N?q`x}h~2ZR@HYmKbFdjty&)D=v zBiq_Xi81f`OXQn4fpDX)H>wf5+Fr`~OIu4z^@iS+)SB^pBWbo_fVi}nSGtv(anCv| z)hm^O%|$8{=PHer%-0a4G6D%Nq+zLEU25>fuau~5lePf`gC;X!xgI-J=SP)uU87zN z(`HmFOB`*^S(~Hv#$t-7R@(e=eTw_S0oc$w-vw>aR-MbJ)vRw0hNchi4~D~%i8*aq z444;rX5nO-qO=*tmDof(sdbC??n4vdp1sf4vLGb^mxD74t?F#g&7C{CZj@ivLK@29 zf!il`_mvRhl0-YgFs8{e4CTgXU8a4la86Uky2*yZEcrK?g7{b|rYnuq8`oBfweuDg zj&aq4-9PE2|0yr2q9&T+)1`%Wnv|kSHmHF^yC*h}1bYrl?Y((A*c0*4cv+JbAF`e~ zW3YNo+oiOS9(8|H4w=x%qtU2=&$w2 zhcDOTXwqDO`5X0FnGOu2hMDV(cHGP-qxvvGWjR^0RYnGfD$AQQ_odUS>y??LA4Tvo zuP%f&W?M-G22Zeig%L7bgb2ZKqUS8RiB3jy4PpSHjwG7$pKu@`PRkUJG*H}3Vaa`+ zMN)%@Fo^C3M-xoR@lL*HhIOMN)-*vM_4`ce5z*vGJcC)Ril9`U{Ey{*`) zGK;tzI8PDNUz_(Tx{JhpEwiJ(mdvbbMd4Di0xdiBlHCUnj!o{fnTVk}T4l{px*K*8pxDlgn9V?1BJd*)_D>y}*gX^M zHy^`kNr@Z|Uwt0eg_W{LtZ{RVFM+gGjk97^k^^U+ZiqFJL9R(gSU3WwOs?lDt#n~f zQpPm88sSPJ?MRCk9j&N2c63{yuh~^+v$l4qJ~T9x*S)55+iUlsa4aew^2437n(IP&QSI z9H5PbXGA)VY-zAx{2JVZvvE{pNNUbtp({p$n=mhNgZ<4x4E(@2PD#?LZZ4Yo@os-% zOK4$%GxPb&!e~xQG*?`y8eRnV`uj>F{lPd687i#eT(59owl%+*n@&q~H5=&H%5Uq> z<{<^D1;c&3K5w!n(g+7`PWEh(hp|P5>&9eHUfBm8rY3>|;}hdEfgG2uqOvzt<}aCn z(7ST;<}1>pT5KB)O}jDiNXEVz4d&~sNJ%zhId0T71dF}6HvNH%SwAWP^o+Byf}EJz zHx^9DJ5*HE?Soh9g&wq+xaq#0T&{Eh@3->?WNL_xjwRJrHS~+Ya2&A_A#_;1)d(iy z>S6g?`eH9+q$L-tyXYZ%AQM4QpIsK6H2RVRGet8En(;iws+KVXqSsntFzyY-mS|r* z^zu57@SG-+nhpMiw}*$DNhJ-BAg{)^6ACm3n+x(V5RNW8KN3vto)`-z4^IS>b^gKe zUBSSp*?qc7<}B8NAd(7ShX%EnKT1&)bkL+@W=B7g5=F>}A?g4pLyD+h z`eB#V?I)d-G?f0xbdwFn7&;B6SiVNaMI*t%Lu0|gsH~(+a1bNhIJmc--nvY5OHBx;k4EhwX0Hepj}RAv z*(sqH4q!LNYV#Hbzy|x1T8)Tc^H4B7e*0K3eQ@`oBE^I01;nhN#Tl9fr{4PHOdBqk zcBda~t-0>*2Anh9L~^PgLchG(ZTFm{RcN6L81D6sHS2cROfQB?9(-s^%X5peL&om1 zcEL0pRa(%@ggr zrpJtKK{%j^YH0y=x8FI7xr{(G$Iw0sb{F=VE=G6pFEtY&Y$5LLLGOBq-4nB9!T|yl_F2AoIXSY8b*!JSB!<)B+ z{n#M8+NLW>Xg~h1-Pt~j9iamsADdfKtJel=@jPaad;+dhLK4>zFmCv|UiWxzwVjmA zkMJwoAh?dh7xh&ttu3Mc-tq98TFbm48yCFSIu34ixf-W1c0tlDh`A%dE~Ps~+-w6b zOUo*Mlv$i+SwW!nQmb3;%EAK6Eo*hvesGJ+P<6sz3uA`@<%m1|$iXH}>mp;HBMxpu zAK_BLFthbE9wn|*nAQ%PN0XAve#Y{CO&R%0fdW=p&CI9ky5TsxlPA&Wc8-S4Xfalp zVeR0I%Nfk&1!tFAU2Y3PKA!J5idgV$UVz%58f0@t zmBu)v_>%~OMqEZ5J1lF_j@OuS^-+mgCK9cAY`LGm;zfta5-76vqi_0y9!rEI!Dl3K zx;BSqVQP6zP6H@WW1&=LG`l0kLZB_x#U}KbHdVG*bk0R`3VC9?JG8)1WFH%haUU{LzHD zIW{b|2C~ zPESD|`&L-)1}aD4fpWMULP*zn3|C{9Smd7P-S_2Fm^{kGv>4OpC!GAt_Khlgo*BV9 z$5zNrZYi{pgWA6nE=?r#78-70Ox0W@PSKjX5OBRmG_$h zC1;gn&;%hxQT9@A!_?&&Z3q2z_^&9W*7;gRZSg`uc($1S=oo4C8rDrOnI9n^&G|?& z|CUme&Biw}<%>t8$5;-lJ#4S?nkTj4Xfnk~KEyeW+6+6|#R4Deyw~0aa4mU;h>e}2 zmdMB8-8U7>K}@ZQ##zYtqRMiz6lizG*QpPe4x~j_%2djv zfs!Vep2LgFI)sVjT#S0F4zYDQ#QRv?+3(Dp4h#=o!xp}!S)H1W!v2x|%=~BwYx=h& zwjX)jHbFg0)V!@`)6Xy3uHnsr;w3q79c|I;_laa#9g74l&<`-i&5n|0Y-YYXYBbP} z7A+GP59QyfC_%RjpiGW);%trg9z1M2iTH}y0fWdXtlXUBexY}fm5E3L2?xpaYMt?r z9rX*D;%7pgY%h(aAI9h=Xf^6%JINp_B+n9b?o0t1LRunEeX=EsPpmgo@i373L7iH$ z#0P3fNi~Sc*nBKqy921(cpM_@D`u=4oRY1Ids*~)t(#mnad0B#?AqWSa*Bg9^%3ga&}=P6 z?BxvA8}pkEP7NMn(h58V_puW-5^fvbcIDvk*1>I8hFh;186Li3c>D11rUM)k8Jr>f zN-NrW7zxL!WO=4{9~uv@jrsbLlvLIYNvTqAm4{e|>u6D%Z?Uw4Gb9s7!kJcMQAZiB z<+MzdbRU;D*jEiBuRX#h?xuDOn1e4$ctKQw2l#JR*stHfr_*U9{`) z%>Kcv^LiTTT-+EOlmEv8j)Yf3woNZILX3ny(~9?N6Ouf2gwj}{YxFWc67Hc*2P?$u zmBIa_syI(qTe8b^7h6B>>#l)XcwM-4^QaxpRQ7i^u2ka1a6WEuG_hT8429FHCu^%G z8<>IoFzAN0Dy%t`S5KB!Pa=j#kSnfFALnY8`_ba+$qF}yfPi}BT^yWxC@QO-QT|LPVEx)7lg8S4V2SZ!4tuSgw4F8sGh4o6bdR$wm@Sx2V(ySg&Do`OCbyVj3 zD81DeTQzu%fO`S)?DS(()7zp(w87IdM#4^s;=L{=G_NEJ(K3|c0l8LWzX?H%V)=Wy zHb%PM$|+WN3k1#<+^u(^X#^+W%t2V3vufP7Ofu77_vOOM^Z)>}ETkyK4Bws<4~F*VWW&W>xEjG(f5a*^T%tzK!JK92Tg$01@l^;FzuGDPK# z-eB`I;V_bFJn`w{%ha!-b~X_9j*$N3s_QU~@!DLpT#44>no45YL$RJQ4-=PKf$@!k z#&%24a&hI<%88Xzi^dZ9EN0_HqP8kzhM()TR{j_U>eW2O%JU`~ohEy7L9<~nC|+Gn z!sf~;MAmhSkLX_~ft+1A#lu>KL9yO7R6}?5+ae{aKm`t7I!gDjWWTF(~62r2bZV6^V@uBKoKd2H{y|L@uxqrYQp!^4tU|c* z0O=?e9!U!qNft<>8yh5c-qqZ&)D&GQ={W#fyzP&`c5d}ud70b&^_D&BT0$z7Xr$$D zh_0?800^zITqk<#+jbd;nd}~;tJywc-`2}YVY>3bvaS7Wz1?cI!oKb9O-A6p9sUBI zcLv+EnZKJkBM)^j+Volfo!hc^GP2G9aQpLj?nmh?rm=R#%>k+=iv*oaI6o?T^MT!m zf*CYc#p{-g_lb0hJP0>u+F1^S9h$W>v#9h&z&5my{pqB}iigSR?K%uh?3b8J;r$@aIGO-v$PvcX;|*>$**{-Igc?&i zKb!cAJzBD$C~d}v`=+LE+ikqwHE-`d6r`~#{cK#ba$+cuer~Otn8ox~C0#|D!Nkt~ z7e*W{cQxrIa(9Ea933g<Ok?)fUrzsOc4=?)MGw|QMfRh=u;6JBhn zVa$BuFSfBYPTJ)?LB{U>JMC9aunZXC{xVwD(c>X@kz0{;*YwJLx8FFna@T>eLzx{-2k<*wEHCxU$zwPv=&^Jyn?4P4Ohu-(6PctyL; zUFVZRDY;g=RZUyy&2Hv0Yt&hnu2so=nCx_MVOC+!3FG3UqD}0m6!;2X!rNh%a45Xp zf-|!-I=Y9o$k>3`1xc&4#Ej0?=-{zU0v?tAR~Seaos-BGdGi7e`l_4m8M4wWH~yoZ zp=G?blPbo)kLih1a^IJk@gOlZ5HT-*4IH~eh*r&xhs-;B98f2Hnx!f?mA%-6An1zD4Fq2_GZsi z3Q*U)V}M>EKz?vJv>rLGoQJRLgs1tDWw$hTW;t(>ExuQAI2hxTaVERCo!UE1a`# zj4kBhLsR)FJjT4Br4z;NID)XIILrAas;xaZ+_T0*vJ*G2-hVJSyxdZX#f9q(!`r0g zdV^o!nF8lWF+NQo&L);gBYknk8O68qK$~A6!`Z=<@pxP!&|{P?JCQL7X)~KgSSEYY zR6G{!i7Ph~Bh;$;rnH`_5DItYs#sSnD&3ihUF3)kq(TAatReAq#L=FR>nU3q^F(A5 zsG#_>ymIRFaWp9I-i8&)@$rh&B*4nahSi{ejP)3%#CI8Xj!wh01e?{BQ^?m{us(fp z3b;YkMcUDVf7Y`T6Ea`#5$xUy+{9hx zm)=TN$veNTj$;oqxHEXxMAGTAdrq@w>mr$yuU{>}B(yuPX}3|q`#x-Y~w(` z-GwXjP*FVThuWjE{M$l)ERG(^u4?Sh=J5s|T$V?2-VRv?c{6ww=1b>XyJZ8J=#R>~ zT+@E|F_~*h&}h#wEF@4=-j~RYDoOyW_U1`+Wo5qAbqYIEhf-NtY^|7=MUYWOebty_ z*P-mJNiaof-2RLNS%9~ORaqG)=Wv#!y(gC4cu_*4N{(1v7ZT;Ny$5UNMoR&!h+AYp zu`Vw_gff}LzR-MYr|mL+Gjq0%ryhNA%k2{ru9bk}R{yWIB=~+@+X< zcYCI8J3Lc3!QCN!f%(IgQ)$!NKDlh1C4gGkL}w7&mfA&uG7K3;t7)d*M_;>5XafiE zH5`(*M*KB{9tlGKjC0(Iq{DE!AnB0D_A3gapAJz|%n^n@_VwEYQ5mb-?GDvQ*4Gkr zEn)b2N(D($`~jO+EH*EOCV4idpb^($vWM35p2J%>&CL(a4um%!K5$_7cGVA+jdWeIFN_J8^;d7d~cuO`@|UL@V-MU_f4$aw~sGFfm;~wSr+q4&X8sch%wA! z*9Q93#WvcXAfXRE@Qt>ZYVXcXI$LRUSb4L>iN;j5a8c}36nFE|jdLN5)7+*coGT+| z!;EZIX@BuX=5swvW5@AtB6QA9bNYo%X!hF_ukPqaZEMXqGlBAe!-?LqK;3N^cmpca zOb48*Gx6=30XdvjZV$T?B0WxuDrPzr2iAVKX)fkkr%6;O5Z@(yW^Cjx^Wwf6-|veS zI4oe*LDkezGCa(Je;Yq5@dX!ozzDRTa7)1U47vqOKba!v258jJg5;2qE2w$nCP{%lvsDZS1>v$fP(VYZCXE#=b1LoP_}9YdjQ zCs^pbM!)?;(`1sD?Ox>;x3@Px3s$uEN$#X{`!Oyj{}5dnIf@p$h)5e8CATQnoh9$7 zK25|vHaT{)J5gS!cT-fA2ZApzPsPunBQlau?m=6&F_wqq?U_?6;uKA)xk#DIiDO}g zYz7ywkndhOVOqs`&60R>H$JH|l1I__6XIGnjW<4aE;Z17=zO20f?OEsPMa&V)SeQX z1ZXgZ#Q)0?Rn6W9ZX4FEBx;m3mIuTRk|jQi&QbT7^M}_iJ82yiGGfq3Nm^4s=%4JH;!NGDg#0r=X&Su!| zH7voxF~im}Sy$?;VQXKN{8RHR!OQ=!>bNQkNJTw=ilWHtnSi<;^k(Wg zmt8S)dw%sK0;p)cu=U+D9s+3zhdY##8=`!xR}PMkni&^4S%sDy(9lT}lZbr(+Q+fd z;8hayUO=4obSm4Qdq-3|`Fx$qUgz+;xWyfPpUx5_q~CSyLs|2#d>i|G(VUST=QZ0> zH5)Suv$4S-o#~RDoPc);D$_zTS`vn#b!b9*r-BmhR#TRS5XIcnZu)183vZlaffbT@ z)h#`trLk6;n9icWH&UAx$Qd2iybLLHk2e+;*RKVZm{cU!r+Ts!nqN8=Dqhq&6*8ul zVn=NS>n*xJ4v?RvcM4KUKBMsZ$LYIP)-g%vPfnZ#w)GWPZA$g4v}2J=2yjt#MH@&0FwM3bb=X@~&UeS#hp>NBO!R z2xO943$#6CNhuq@bEL#YutftOM5zm{zD4V#ids~IaibRrU#J@O7W45eQs(6!%ll6R@!B*-Pi?_TQlLxs>ae)t9{1}A7>dDnOmI&# z`MECaHfF^yo~y7y0SARfHGU+4X&`B<)U6A5Y;|pAE$`P%+E^Z(rhMtq1uQK;Vw1va zYd4J=QlT(AQ_-PClSg|MgoXfw)3^~jhm|>PE~r(<>-i<-k_6fBBAj@!Q2a7NEjWGW zeiU(NytREB|0~USYbXCL0$eg5`k&NizfsA4@a}$~<$pxv4ti%lS5vx^UxUD@_9J$V W%-oSDQa0oSmc-{#9#-1HdjAh3uY>vk literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/tr.po b/cpp/third_party/xz-5.8.3/po/tr.po new file mode 100644 index 000000000..f6d0a7639 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/tr.po @@ -0,0 +1,1264 @@ +# SPDX-License-Identifier: 0BSD +# +# Turkish translation for xz. +# This file is published under the BSD Zero Clause License. +# +# Emir SARI , 2022-2025. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-01-25 17:00+0300\n" +"Last-Translator: Emir SARI \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: --block-list için geçersiz argüman" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: --block-list için çok fazla argüman" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "--block-list içinde, süzgeç zinciri numarası '%c' sonrası blok boyutu eksik:" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0, yalnızca --block-list içindeki son öge olarak kullanılabilir" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Bilinmeyen dosya biçimi türü" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Desteklenmeyen bütünlük denetimi türü" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "'--files' veya '--files0' ile yalnızca bir dosya belirtilebilir." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Çevre deÄŸiÅŸkeni %s, pek fazla argüman içeriyor" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Sıkıştırma desteÄŸi, yapım sırasında devre dışı bırakıldı" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Sıkıştırma açma desteÄŸi, yapım sırasında devre dışı bırakıldı" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "lzip dosyalarının (.lz) sıkıştırılması desteklenmiyor" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr ".xz biçimine sıkıştırılmadığı durumlarda --block-list yok sayılır" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "stdout'a yazılmıyorsa --format-raw ile --suffix=.SUF gereklidir" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Olabilecek en çok süzgeç sayısı dörttür" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "--filters%s=SÜZGEÇLER seçeneÄŸinde hata:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Verilen süzgeç ayarı için bellek kullanım sınırı pek düşük." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "Süzgeç zinciri %u --block-list tarafından kullanılıyor; ancak --filters%u= ile belirtilmemiÅŸ." + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Ham kipte bir önayar kullanımı önerilmez." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Önayarların kesin seçenekleri yazılım sürümleri arasında ayrım gösterebilir." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr ".lzma biçimi, yalnızca LZMA1 süzgecini destekler" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1, .xz biçimi ile birlikte kullanılamaz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Süzgeç zinciri %u, --flush-timeout ile uyumsuz" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "--flush-timeout nedeniyle tek iÅŸ parçacıklı kipe geçiliyor" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Süzgeç zinciri %u ile desteklenmeyen seçenekler" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "En çok % iÅŸ parçacığı kullanılıyor." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Desteklenmeyen süzgeç zinciri veya süzgeç seçenekleri" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Sıkıştırma açma, %s MiB belleÄŸe gereksinim duyacak." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "%3$s MiB bellek kullanımı sınırını aÅŸmamak için iÅŸ parçacığı sayısı %1$s -> %2$s olarak ayarlandı" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "İş parçacıklarının sayısı %s -> 1 olarak azaltıldı. %s MiB otomatik bellek sınırı hâlâ aşılıyor. %s MiB belleÄŸe gereksinim var. Yine de sürdürülüyor." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "%s MiB bellek kullanım sınırını aÅŸmamak için tek iÅŸ parçacıklı kipe geçiliyor" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "%4$s MiB bellek kullanımı sınırını aÅŸmamak için LZMA%1$c sözlük boyutu %2$s MiB'dan %3$s MiB'e ayarlandı" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "%5$s MiB bellek kullanımı sınırını aÅŸmamak için --filters%2$u için olan LZMA%1$c sözlük boyutu %3$s MiB'den %4$s MiB'a ayarlandı" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Süzgeç zinciri %u olarak deÄŸiÅŸtirilirken hata: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Veriyolu oluÅŸtururken hata: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: poll() baÅŸarısız oldu: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Dosya taşınmış gibi görünüyor, kaldırılmıyor" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Kaldırılamıyor: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Dosya sahibi ayarlanamıyor: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Dosya grubu ayarlanamıyor: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Dosya izinleri ayarlanamıyor: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Dosyayı eÅŸzamanlama baÅŸarısız: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Dosyanın dizinini eÅŸzamanlama baÅŸarısız: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Standart girdi'den dosya durum bayrakları alınırken hata: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Bir sembolik baÄŸ, atlanıyor" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Bir dizin, atlanıyor" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: OlaÄŸan bir dosya deÄŸil, atlanıyor" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Dosyanın setuid'si veya setgid biti ayarlanmış, atlanıyor" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Dosyanın yapışkan bit seti var, atlanıyor" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Girdi dosyasında birden çok sabit baÄŸ var, atlanıyor" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "BoÅŸ dosya adı, atlanıyor" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Standart girdi'ye durum bayrakları geri yüklenirken hata: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Standart çıktı'dan dosya durum bayrakları alınırken hata: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Dizini açma baÅŸarısız: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: Hedef olaÄŸan bir dosya deÄŸil" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Standart çıktı'dan O_APPEND bayrağı geri yüklenirken hata: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Dosyayı kapatma baÅŸarısız: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Bir aralıklı dosya oluÅŸturmaya çalışırken arama baÅŸarısız: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Okuma hatası: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Dosyayı ararken hata: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Dosyanın beklenmedik sonu" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Yazma hatası: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Devre dışı" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Fiziksel bellek miktarı (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "İşlemci iÅŸ parçacığı sayısı:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Sıkıştırma:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Sıkıştırma açma:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Çok iÅŸ parçacıklı sıkıştırma açma:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "-T0 için öntanımlı:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Donanım bilgisi:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Bellek kullanım sınırları:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Akışlar:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Bloklar:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Sıkıştırılmış boyut:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Sıkıştırılmamış boyut:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Oran:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Denetim:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Akış dolgusu:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Gereken bellek:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Üstbilgideki boyut:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Dosya sayısı:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Akış" + +#: src/xz/list.c +msgid "Block" +msgstr "Blok" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Bloklar" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "SkÅŸtrOfseti" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "SkÅŸtrmmÅŸOfset" + +#: src/xz/list.c +msgid "CompSize" +msgstr "SkÅŸtrBoyut" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "SkÅŸtrmmÅŸBoyut" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "ToplamBoyut" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Oran" + +#: src/xz/list.c +msgid "Check" +msgstr "Denetim" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "DÄŸrDentm" + +#: src/xz/list.c +msgid "Padding" +msgstr "Dolgu" + +#: src/xz/list.c +msgid "Header" +msgstr "Üstveri" + +#: src/xz/list.c +msgid "Flags" +msgstr "Bayrak" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "BelKullnm" + +#: src/xz/list.c +msgid "Filters" +msgstr "Süzgeçler" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Yok" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "?-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "?-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "?-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "?-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "?-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "?-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "?-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "?-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "?-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "?-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "?-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "?-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Dosya boÅŸ" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Geçerli bir .xz dosyası olabilmek için pek küçük" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr " Akış Blok Sıkıştırıl. Sıkıştırmas. Oran Denetim Dosya ad" + +#: src/xz/list.c +msgid "Yes" +msgstr "Evet" + +#: src/xz/list.c +msgid "No" +msgstr "Hayır" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "En düşük XZ Utils sürümü:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s dosya\n" +msgstr[1] "%s dosya\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Toplamlar:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list, yalnızca .xz dosyalarında çalışır (--format=xz veya --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr ".lzma dosyalarıyla 'lzmainfo'yu deneyin." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list, standart girdi'den okumayı desteklemez" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Dosya adları okunurken hata: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Dosya adları okunurken beklenmedik girdi sonu" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Dosya adları okunurken boÅŸ karakter bulundu; '--files' yerine '--files0' mı demek istediniz?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "--robot ile sıkıştırma ve sıkıştırma açma henüz desteklenmiyor." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Standart girdi'den dosya adları okunurken standart girdi'den veri okunamıyor" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "İç hata (yazılım hatası)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Sinyal iÅŸleyicileri tesis edilemiyor" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Bütünlülük denetimi yok; dosya bütünlüğü doÄŸrulanmıyor" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Desteklenmeyen bütünlülük denetimi türü; dosya bütünlüğü doÄŸrulanmıyor" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Bellek kullanım sınırına eriÅŸildi" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Dosya biçimi tanımlanamıyor" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Desteklenmeyen seçenekler" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Sıkıştırılmış veri hasarlı" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Beklenmedik girdi sonu" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "%s MiB bellek gerekiyor. Sınırlandırıcı devre dışı bırakıldı." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "%s MiB bellek gerekiyor. Sınır, %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Süzgeç zinciri: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Daha fazla bilgi için '%s --help' deneyin." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Yardım metni yazdırılırken hata (hata kodu %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "Kullanım: %s [SEÇENEK]... [DOSYA]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr ".xz biçimindeki DOSYAları sıkıştır veya sıkıştırmasını aç." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Uzun seçenekler için zorunlu olan argümanlar kısalar için de öyledir." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "İşlem kipi:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "sıkıştırmayı zorla" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "sıkıştırma açmayı zorla" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "sıkıştırılmış dosya bütünlüğünü sına" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr ".xz dosyaları hakkında bilgi ver" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "İşlem niteleyicileri:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "girdi dosyalarını tut (silme)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "çıktı dosyalarının üzerine yazılmasını zorla ve baÄŸlantıları çöz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "standart çıktıya yaz ve girdi dosyalarını silme" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "girdi dosyasını kaldırmadan önce çıktı dosyasını depolama aygıtına eÅŸzamanlama" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "yalnızca ilk akışı çöz ve kalan olası girdi verisini sessizce yok say" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "sıkıştırma çözerken seyrek dosyalar oluÅŸturma" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "sıkıştırılmış dosyalarda '.SUF' sonekini kullan" + +#: src/xz/message.c +msgid "FILE" +msgstr "DOSYA" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "DOSYA'dan iÅŸlemek için dosya adlarını oku; DOSYA verilmemiÅŸse dosya adları standart girdiden okunur; dosya adları, yenisatır karakteriyle sonlandırılmalıdır" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "--files gibi; ancak sonlandırıcı olarak boÅŸ karakterini kullanır" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Temel dosya biçimi ve sıkıştırma seçenekleri:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "BİÇİM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "kodlamak veya çözmek için dosya biçimi; olası deÄŸerler: 'auto' (öntanımlı), 'xz', 'lzma', 'lzip' ve 'raw'" + +#: src/xz/message.c +msgid "NAME" +msgstr "AD" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "bütünlük denetimi türü: 'none' (dikkatlı kullanın), 'crc32', 'crc64' (öntanımlı) veya 'sha256'" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "sıkıştırmayı açarken bütünlük denetimini doÄŸrulama" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "sıkıştırma önayarı; öntanımlı 6'dır; 7-9 kullanmadan önce sıkıştırıcı *ve* açıcı bellek kullanımını dikkate alın" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "daha çok CPU zamanı kullanarak sıkıştırma oranını iyileÅŸtirmeye çalış; sıkıştırma açıcı bellek gereksinimlerini etkilemez" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "SAYI" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "en çok SAYI iÅŸ parçacığı kullan; öntanımlı 1; var olan iÅŸlemci çekirdeÄŸi kadar iÅŸ parçacığı kullanmak için 0'a ayarlayın" + +#: src/xz/message.c +msgid "SIZE" +msgstr "BOYUT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "her BOYUT bayt girdiden sonra yeni bir .xz bloku baÅŸlat; iÅŸ parçacığı kullanan sıkıştırma için blok boyutunu ayarlamak için bunu kullanın" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOKLAR" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "verilen virgülle ayrılmış sıkıştırılmamış veri aralığından sonra yeni bir .xz bloku baÅŸlat; isteÄŸe baÄŸlı olarak, sıkıştırılmamış veri boyutundan önce bir süzgeç zinciri numarası belirtin (0-9, sonrasında ':' gelir)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "sıkıştırırken, bir önceki floÅŸtan SAYI milisaniyeden daha çok zaman geçtiyse ve daha çok okuma engelleyecekse tüm bekleyen veri floÅŸlanır" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "SINIR" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "sıkıştırma, sıkıştırma açma, çok iÅŸ parçacıklı sıkıştırma açma veya bunların tümü için için bellek kullanımı sınırı ayarla; SINIR; bayt, bellek yüzdesi veya öntanımlılar için 0 olabilir" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "sıkıştırma ayarları bellek kullanımı sınırını aşıyorsa ayarı aÅŸağı doÄŸru çekmek yerine bir hata ver" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Sıkıştırma için özel süzgeç zinciri (önayar kullanımı alternatifi):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "SÜZGEÇLER" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "süzgeç zincirini liblzma süzgeç zinciri sözdizimi kullanarak ayarla; daha fazla bilgi için --filters-help kullanın" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "--block-list ile kullanmak üzere liblzma süzgeç dizisi sözdizimi kullanarak ek süzgeç zincirleri ayarla" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "liblzma süzgeç dizisi sözdizimi hakkında daha fazla bilgi görüntüle ve çık" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "SÇNK" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 veya LZMA2; SÇNK (seçenekler), aÅŸağıdaki seçeneklerin hiçbirini veya bir sayısını içeren virgülle ayrılmış bir listedir (geçerli deÄŸerler; öntanımlı):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "ÖN" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "seçenekleri bir önayara sıfırla" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "sözlük boyutu" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "düz baÄŸlam bitleri sayısı" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "düz konum bitleri sayısı" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "konum bitleri sayısı" + +#: src/xz/message.c +msgid "MODE" +msgstr "KİP" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "sıkıştırma kipi" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "eÅŸleÅŸmenin öncelik uzunluÄŸu" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "eÅŸleÅŸme bulucusu" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "en çok arama derinliÄŸi; 0=kendiliÄŸinden (öntanımlı)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ süzgeci (32 ve 64 bit)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ süzgeci" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BCJ süzgeci" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ süzgeci" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ süzgeci (yalnızca son büyük haneli)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (Itanium) BCJ süzgeci" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ süzgeci" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ süzgeci" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "Tüm BCJ süzgeçleri için geçerli SÇNK:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "dönüşümler için baÅŸlangıç ofseti (öntanımlı)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "Fark süzgeci; geçerli SÇNK (geçerli deÄŸerler; öntanımlı):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "birbirinden çıkarılan baytlar arasındaki uzaklık" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "DiÄŸer seçenekler:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "uyarıları sustur; hataları susturmak için iki kez belirt" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "ayrıntılı ol; daha da ayrıntı için iki kez belirt" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "uyarıların çıkış durumunu etkilemesine izin verme" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "makine tarafından ayrıştırılabilir iletiler kullan (betikler için yararlı)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "toplam RAM miktarını ve ÅŸu anki bellek kullanımı sınırlarını görüntüle ve çık" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "kısa yardımı görüntüle (yalnızca temel seçenekleri listeler)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "bu uzun yardımı görüntüle ve çık" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "bu kısa yardımı görüntüle ve çık" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "bu uzun yardımı görüntüle (ayrıca geliÅŸmiÅŸ seçenekleri listeler)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "sürüm numarasını görüntüle ve çık" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "DOSYA olmadan veya DOSYA - iken standart girdi'yi oku." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Hataları <%s> adresine bildir (İngilizce veya Fince)." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "%s ana sayfası: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "BU, NORMAL KULLANIM İÇİN OLMAYAN BİR GELİŞTİRME SÜRÜMÜDÜR." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Süzgeç zincirleri --filters=SÜZGEÇLER veya --filters1=SÜZGEÇLER ... --filters9=SÜZGEÇLER seçenekleri kullanılarak ayarlanır. Zincirdeki her bir seçenek boÅŸluklar veya '--' ile ayrılabilir. Alternatif olarak, bir süzgeç zinciri yerine bir %s önayarı da belirtilebilir." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Desteklenmeyen süzgeçler ve onların seçenekleri:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "Seçenekler, virgülle ayrılmış 'ad=deÄŸer' çiftleri olmalıdır" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Geçersiz seçenek adı" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Geçersiz seçenek deÄŸeri" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Desteklenmeyen LZMA1/LZMA2 önayarı: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "lc ve lp'nin toplamı 4'ü geçmemelidir" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Dosya adında bilinmeyen sonek var, atlanıyor" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Dosyada '%s' soneki halihazırda var, atlanıyor" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Geçersiz dosya adı soneki" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "DeÄŸer, bir negatif olmayan ondalık tamsayı" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Geçersiz çoklayıcı soneki" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Geçerli sonekler: 'KiB' (2^10), 'MiB' (2^20) ve 'GiB' (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "'%s' seçeneÄŸi deÄŸeri erimde olmalıdır [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Bir uçbirimden sıkıştırılmış veri okunamaz" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Bir uçbirime sıkıştırılmış veri yazılamaz" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "Kullanım: %s [--help] [--version] [DOSYA]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr ".lzma dosya üstbilgisinde depolanan bilgiyi göster." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Geçerli bir .xz dosyası olabilmek için pek küçük" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Bir .lzma dosyası deÄŸil" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Standart çıktı'ya yazma baÅŸarısız" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Bilinmeyen hata" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Desteklenmeyen önayarlar" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Önayarda desteklenmeyen bayrak" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Geçersiz seçenek adı" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Seçenek deÄŸeri boÅŸ olamaz" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "DeÄŸer erim dışında" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "Bu seçenek herhangi bir çoklayıcı soneklerini desteklemiyor" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "Geçersiz çoklayıcı soneki (KiB, MiB veya GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Bilinmeyen süzgeç adı" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Bu süzgeç .xz biçiminde kullanılamaz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Bellek ayırma baÅŸarısız" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "BoÅŸ diziye izin verilmiyor; bir öntanımlı deÄŸer gerekiyorsa '6' deneyin" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "Olabilecek en çok süzgeç sayısı dörttür" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Süzgeç adı eksik" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Geçersiz süzgeç zinciri (sonda 'lzma2' mi eksik?)" diff --git a/cpp/third_party/xz-5.8.3/po/uk.gmo b/cpp/third_party/xz-5.8.3/po/uk.gmo new file mode 100644 index 0000000000000000000000000000000000000000..5975b6d850ee4f431b8c580879f956523dc7df4d GIT binary patch literal 39005 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%0AhKG7EwoiBtJ&%xf?8hJ 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, 2019, 2022, 2023, 2024, 2025. +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-01-24 13:54+0200\n" +"Last-Translator: Yuri Chornoivan \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\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" +"X-Generator: Lokalize 23.04.3\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: некоректний аргумент --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: забагато аргументів --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "У --block-list пропущено розмір блоку піÑÐ»Ñ Ð½Ð¾Ð¼ÐµÑ€Ð° ланцюжка фільтрів «%c:»" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 можна викориÑтовувати лише Ñк оÑтанній елемент у --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: невідомий тип формату файлів" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: непідтримуваний тип перевірки ціліÑноÑті" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Разом із параметрами --files або --files0 можна вказувати лише один файл." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "У змінній Ñередовища %s міÑтитьÑÑ Ð½Ð°Ð´Ñ‚Ð¾ багато аргументів" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Підтримку ÑтиÑÐºÐ°Ð½Ð½Ñ Ð±ÑƒÐ»Ð¾ вимкнено під Ñ‡Ð°Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Підтримку Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð¾ вимкнено під Ñ‡Ð°Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Підтримки ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² lzip (.lz) не передбачено" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list буде проігноровано, Ñкщо дані не ÑтиÑкаютьÑÑ Ð´Ð¾ формату .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "" +"Якщо вказано --format=raw, Ñлід вказати Ñ– --suffix=.SUF, Ñкщо дані\n" +"виводÑтьÑÑ Ð½Ðµ до Ñтандартного виведеннÑ" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "МакÑимальна кількіÑть фільтрів — чотири" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Помилка у параметрі --filters%s=ФІЛЬТРИ:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ñ” надто жорÑтким Ð´Ð»Ñ Ð²ÐºÐ°Ð·Ð°Ð½Ð¾Ð³Ð¾ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ñ–Ð²." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "у --block-list викориÑтано ланцюжок фільтрів %u, але його не вказано за допомогою --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Ðе варто кориÑтуватиÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñм Ñ€Ñ–Ð²Ð½Ñ Ñƒ режимі без обробки." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Точний перелік параметрів рівнів може залежати від верÑій програмного забезпеченнÑ." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "У форматі .lzma передбачено підтримку лише фільтра LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 не можна викориÑтовувати разом із визначеннÑм формату .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Ланцюжок Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ %u Ñ” неÑуміÑним із параметром --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "ПеремикаємоÑÑ Ð½Ð° однопотоковий режим через викориÑÑ‚Ð°Ð½Ð½Ñ --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Ðепідтримувані параметри у ланцюжку фільтрів %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "ВикориÑтовуємо до % потоків обробки." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Ðепідтримуваний ланцюжок Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ непідтримувані параметри фільтруваннÑ" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Ð”Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ð´Ð¾Ð±Ð»ÑтьÑÑ %s МіБ пам'Ñті." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Зменшено кількіÑть потоків обробки з %s до %s, щоб не перевищувати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті у %s МіБ" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "КількіÑть потоків обробки зменшено з %s до одного. Ðвтоматичне Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті у %s МіБ уÑе ще перевищено. Потрібно %s МіБ пам'Ñті. Продовжуємо роботу попри це." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "ПеремикаємоÑÑ Ð½Ð° однопотоковий режим, щоб не перевищувати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті у %s МіБ" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Скориговано розмір Ñловника LZMA%c з %s МіБ до %s МіБ, щоб не перевищувати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті у %s МіБ" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Скориговано розмір Ñловника LZMA%c Ð´Ð»Ñ --filters%u з %s МіБ до %s МіБ, щоб не перевищувати Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті у %s МіБ" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби перейти до ланцюжка фільтрів %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Помилка під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: помилка poll(): %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: здаєтьÑÑ, файл переÑунуто; не вилучаємо" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: не вдалоÑÑ Ð²Ð¸Ð»ÑƒÑ‡Ð¸Ñ‚Ð¸: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: не вдалоÑÑ Ð²Ñтановити влаÑника файла: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: не вдалоÑÑ Ð²Ñтановити групу влаÑника файла: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: не вдалоÑÑ Ð²Ñтановити права доÑтупу до файла: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: не вдалоÑÑ Ñинхронізувати файл: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: не вдалоÑÑ Ñинхронізувати каталог файла: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñ–Ð² Ñтану файла зі Ñтандартного джерела вхідних даних: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Ñ” Ñимволічним поÑиланнÑм; пропуÑкаємо" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Ñ” каталогом; пропуÑкаємо" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: не Ñ” звичайним файлом; пропуÑкаємо" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° вÑтановлено біт setuid або setgid; пропуÑкаємо" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° вÑтановлено липкий біт; пропуÑкаємо" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: виÑвлено декілька жорÑтких поÑилань на файл із вхідними даними; пропуÑкаємо" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° файла; пропуÑкаємо" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñ–Ð² Ñтану Ð´Ð»Ñ Ñтандартного джерела вхідних даних: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñ–Ð² Ñтану файла зі Ñтандартного виведеннÑ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s: не вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ каталог: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%s: Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ Ñ” звичайним файлом" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñ O_APPEND Ð´Ð»Ñ Ñтандартного виведеннÑ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: не вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ файл: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: помилка Ð¿Ð¾Ð·Ð¸Ñ†Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ñпроби Ñтворити розріджений файл: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: помилка читаннÑ: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: помилка Ð¿Ð¾Ð·Ð¸Ñ†Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñƒ файлі: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: неочікуваний кінець файла" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: помилка під Ñ‡Ð°Ñ Ñпроби запиÑу: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Вимкнено" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "ОбÑÑг фізичної пам'Ñті (RAM): " + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "КількіÑть потоків обробки процеÑором:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "СтиÑканнÑ:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "РозпакуваннÑ:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Багатопотокове розпаковуваннÑ:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Типове Ð´Ð»Ñ -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Дані щодо обладнаннÑ:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Потоки:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Блоки:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "СтиÑнутий розмір:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "ÐеÑтиÑнутий розмір:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "ПропорціÑ:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Перевірка:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Потрібний об'єм пам'Ñті:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Розмір у заголовках:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "КількіÑть файлів:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Потік" + +#: src/xz/list.c +msgid "Block" +msgstr "Блок" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Блоки" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "СтиÑЗÑув" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "ÐеÑтиÑЗÑув" + +#: src/xz/list.c +msgid "CompSize" +msgstr "СтиÑРозмір" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "ÐеÑтиÑРозмір" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "Загальний розмір" + +#: src/xz/list.c +msgid "Ratio" +msgstr "ПропорціÑ" + +#: src/xz/list.c +msgid "Check" +msgstr "Перевірка" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "ЗначПерев" + +#: src/xz/list.c +msgid "Padding" +msgstr "Заповн" + +#: src/xz/list.c +msgid "Header" +msgstr "Заголов" + +#: src/xz/list.c +msgid "Flags" +msgstr "Прапор" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "ВикПам" + +#: src/xz/list.c +msgid "Filters" +msgstr "Фільтри" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Ðемає" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "Ðевідомо-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "Ðевідомо-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "Ðевідомо-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "Ðевідомо-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "Ðевідомо-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "Ðевідомо-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "Ðевідомо-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "Ðевідом-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "Ðевідом-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "Ðевідом-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "Ðевідом-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "Ðевідом-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: файл порожній" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Ñ” надто малим Ð´Ð»Ñ ÐºÐ¾Ñ€ÐµÐºÑ‚Ð½Ð¾Ð³Ð¾ файла .xz" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Потоки Блоки СтиÑнуті ÐеÑтиÑнуті Коеф. Перев. Ðазва файла" + +#: src/xz/list.c +msgid "Yes" +msgstr "Так" + +#: src/xz/list.c +msgid "No" +msgstr "ÐÑ–" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "Мінімальна верÑÑ–Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼ XZ:" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s файл\n" +msgstr[1] "%s файли\n" +msgstr[2] "%s файлів\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Загалом:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list працює лише Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² .xz (--format=xz або --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Спробуйте «lzmainfo» із файлами .lzma." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ --list ÑкаÑовує підтримку Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ñ– Ñтандартного джерела вхідних даних" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: помилка під Ñ‡Ð°Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð·Ð² файлів: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: неочікуваний кінець вхідних даних під Ñ‡Ð°Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð·Ð² файлів" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: під Ñ‡Ð°Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð·Ð² файлів виÑвлено нуль-Ñимвол; можливо, ви хотіли ÑкориÑтатиÑÑ --files0, а не --files?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "У поточній верÑÑ–Ñ— ще не передбачено підтримки ÑтиÑÐºÐ°Ð½Ð½Ñ Ð°Ð±Ð¾ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð· параметром --robot." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Ð§Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… зі Ñтандартного джерела вхідних даних неможливе, Ñкщо зі Ñтандартного джерела даних виконуєтьÑÑ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ð·Ð² файлів standard input" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° (вада)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Ðе вдалоÑÑ Ð²Ñтановити обробники Ñигналів" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Ðемає перевірки ціліÑноÑті; ціліÑніÑть файлів перевірено не буде" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Ðепідтримуваний тип перевірки ціліÑноÑті; перевірки ціліÑноÑті виконано не буде" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Перевищено Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Формат файла не розпізнано" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Ðепідтримувані параметри" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "СтиÑнені дані пошкоджено" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "ÐеÑподіваний кінець вхідних даних" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "Потрібно %s МіБ пам'Ñті. ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð¾." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "Потрібно %s МіБ пам'Ñті. Маємо Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ñƒ %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: ланцюжок фільтруваннÑ: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Спробуйте «%s --help» Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾ÐºÐ»Ð°Ð´Ð½Ñ–ÑˆÐ¾Ð³Ð¾ опиÑу." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "Помилка при друці текÑту довідки (код помилки %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "ВикориÑтаннÑ: %s [ПÐРÐМЕТР]... [ФÐЙЛ]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "СтиÑнути або розпакувати файли у форматі .xz." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Обов’Ñзкові аргументи Ð´Ð»Ñ Ð´Ð¾Ð²Ð³Ð¸Ñ… форм запиÑу параметрів Ñ” обов’Ñзковими Ñ– Ð´Ð»Ñ Ñкорочених форм." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "Режим роботи:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "примуÑове ÑтиÑканнÑ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "примуÑове розпаковуваннÑ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "перевірити ціліÑніÑть ÑтиÑнутого файла" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "вивеÑти відомоÑті щодо файлів .xz" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "Модифікатори режиму роботи:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "зберегти (не вилучати) вхідні файли" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "примуÑово перезапиÑувати файл-результат Ñ– ÑтиÑкати поÑиланнÑ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "запиÑати до Ñтандартного Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… Ñ– не вилучати файли вхідних даних" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "не Ñинхронізувати файл-результат з приÑтроєм Ñховища даних до Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð²Ñ…Ñ–Ð´Ð½Ð¾Ð³Ð¾ файла" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "розпакувати лише перший потік Ñ– без запитань ігнорувати решту вхідних даних" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "не Ñтворювати розріджених файлів при розпаковуванні" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".СУФ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "викориÑтати ÑÑƒÑ„Ñ–ÐºÑ Â«.СУФ» Ð´Ð»Ñ ÑтиÑнутих файлів" + +#: src/xz/message.c +msgid "FILE" +msgstr "ФÐЙЛ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "прочитати назви файлів Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ з файла ФÐЙЛ; Ñкщо ФÐЙЛ не вказано, назви буде прочитано зі Ñтандартного джерела вхідних даних; ÑпиÑок назв файлів має бути завершено Ñимволом нового Ñ€Ñдка" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "подібно до --files, але з викориÑтаннÑм нуль-Ñимволу Ñк роздільника" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "Параметри базового формату файлів та ÑтиÑканнÑ:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "ФОРМÐТ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "формат файлів Ð´Ð»Ñ ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ декодуваннÑ; можливі значеннÑ: auto (типовий), xz, lzma, lzip Ñ– raw" + +#: src/xz/message.c +msgid "NAME" +msgstr "ÐÐЗВÐ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "тип перевірки ціліÑноÑті: none («немає», будьте обережні), crc32, crc64 (типовий) або sha256" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "не виконувати перевірку ціліÑноÑті при розпаковуванні" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "рівень ÑтиÑканнÑ; типовим Ñ” 6; візьміть до уваги параметри викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñ– розпакуваннÑ, перш ніж викориÑтовувати рівні 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "Ñпробувати поліпшити рівень ÑтиÑÐºÐ°Ð½Ð½Ñ ÑˆÐ¸Ñ€ÑˆÐ¸Ð¼ викориÑтаннÑм процеÑора; не впливає на вимоги щодо пам'Ñті Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "ЧИСЛО" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "викориÑтовувати не більше N потоків; типовим Ñ” Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ 0, за Ñкого програма викориÑтовує Ñтільки потоків, Ñкільки Ñ” Ñдер у процеÑора" + +#: src/xz/message.c +msgid "SIZE" +msgstr "РОЗМІР" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "розпочинати новий файл .xz кожні РОЗМІР байтів вхідних даних; цим параметром Ñлід кориÑтуватиÑÑ Ð´Ð»Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€Ñƒ блоку Ð´Ð»Ñ Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ декілька потоків" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "БЛОКИ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "розпочинати нові блоки .xz піÑÐ»Ñ Ð²ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… інтервалів неÑтиÑнених даних; запиÑи відокремлюютьÑÑ ÐºÐ¾Ð¼Ð°Ð¼Ð¸; можна вказати номер ланцюжка фільтрів (0-9) із завершальною «:» до розміру неÑтиÑнених даних" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "під Ñ‡Ð°Ñ ÑтиÑканнÑ, Ñкщо з чаÑу попереднього ÑÐ¿Ð¾Ñ€Ð¾Ð¶Ð½ÐµÐ½Ð½Ñ Ð±ÑƒÑ„ÐµÑ€Ð° Ñ– Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ð³Ð¾ блоку вхідних даних минуло більше за ЧÐС_ОЧІКУВÐÐÐЯ міліÑекунд, витерти уÑÑ– дані у черзі" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "ОБМЕЖЕÐÐЯ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "вÑтановити Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð° викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ð´Ð»Ñ ÑтиÑканнÑ, розпаковуваннÑ, потокового Ñ€Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ уÑÑ–Ñ… режимів; ОБМЕЖЕÐÐЯ Ñлід вказувати у байтах, % RAM або вказати 0 (типове значеннÑ)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "Ñкщо параметри ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¿Ñ€Ð¸Ð·Ð²Ð¾Ð´Ñть до Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½ÑŒ на пам'Ñть, вивеÑти помилку Ñ– не коригувати параметри" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "Ðетиповий ланцюжок Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ ÑтиÑÐºÐ°Ð½Ð½Ñ (альтернатива викориÑÑ‚Ð°Ð½Ð½Ñ Ñ€Ñ–Ð²Ð½Ñ–Ð²):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "ФІЛЬТРИ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "вÑтановити ланцюжок фільтрів за допомогою ÑинтакÑиÑу Ñ€Ñдків фільтрів liblzma; ÑкориÑтайтеÑÑ --filters-help, щоб дізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "вÑтановити додаткові ланцюжки фільтрів за допомогою ÑинтакÑиÑу Ñ€Ñдків ланцюжка фільтрів liblzma Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð· --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "вивеÑти докладніші відомоÑті щодо ÑинтакÑиÑу Ñ€Ñдків liblzma Ñ– завершити роботу" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "ПÐРÐМ" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 або LZMA2; ПÐРÐМ Ñ” ÑпиÑок відокремлених комами Ð½ÑƒÐ»Ñ Ð°Ð±Ð¾ декількох параметрів (коректні значеннÑ; типове):" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "ÐÐБ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "Ñкинути параметри до початкового набору" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "розмір Ñловника" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "кількіÑть бітів буквального контекÑту" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "кількіÑть буквальних позиційних бітів" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "кількіÑть позиційних бітів" + +#: src/xz/message.c +msgid "MODE" +msgstr "РЕЖИМ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "режим ÑтиÑканнÑ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "форматована довжина відповідноÑті" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "пошук відповідників" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "макÑимальна глибина пошуку; 0=автоматична (типове значеннÑ)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "фільтр BCJ x86 (32-бітовий Ñ– 64-бітовий)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "фільтр BCJ ARM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "фільтр BCJ ARM-Thumb" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "фільтр BCJ ARM64" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "фільтр BCJ PowerPC (лише зі зворотним порÑдком байтів)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "фільтр BCJ IA-64 (Itanium)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "фільтр BCJ SPARC" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "фільтр BCJ RISC-V" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "Коректні Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐŸÐРÐМ Ð´Ð»Ñ ÑƒÑÑ–Ñ… фільтрів BCJ:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "початковий відÑтуп Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½ÑŒ (типовий=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "дельта-фільтр; коректні ПÐРÐМЕТРИ (значеннÑ; типове):" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "відÑтань між байтами, Ñкі віднімаютьÑÑ Ð¾Ð´Ð¸Ð½ від одного" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "Інші параметри:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "придушити попередженнÑ; вкажіть двічі, щоб придушити Ñ– помилки" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "режим докладних повідомлень; вкажіть двічі Ð´Ð»Ñ Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ð´Ð¾ÐºÐ»Ð°Ð´Ð½Ð¾Ñті" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ впливають на Ñтан виходу" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "викориÑтовувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ комп'ютером (кориÑно Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñценаріїв)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "вивеÑти загальні дані щодо оперативної пам'Ñті Ñ– поточних обмежень щодо Ñ—Ñ— викориÑтаннÑ, потім завершити роботу" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "показати Ñкорочену довідку (лише ÑпиÑок оÑновних параметрів)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "показати цю розширену довідку Ñ– завершити роботу" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "показати цю коротку довідку Ñ– завершити роботу" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "показати розгорнуту довідку (із уÑіма додатковими параметрами)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "показати дані щодо верÑÑ–Ñ— Ñ– завершити роботу" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "Якщо вхідний файл не вказано, або Ñкщо вказано Ñимвол -, Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ виконано зі Ñтандартного джерела вхідних даних." + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "Сповіщайте розробників про вади за адреÑою <%s> (англійÑькою Ñ– фінÑькою)." + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка %s: <%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ЦЕ ТЕСТОВРВЕРСІЯ, ЯКУ ÐЕ ПРИЗÐÐЧЕÐО ДЛЯ ПРОМИСЛОВОГО ВИКОРИСТÐÐÐЯ." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "Ланцюжки Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÑтановлюютьÑÑ Ð·Ð° допомогою параметрів --filters=ФІЛЬТРИ або --filters1=ФІЛЬТРИ ... --filters9=ФІЛЬТРИ. Кожен фільтр у ланцюжку можна відокремлювати від інших пробілами або «--». Крім того, можна вказати шаблон %s заміÑть ланцюжка фільтрів." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Підтримувані фільтри та їхні параметри:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "параметри -- пари «назва=значеннÑ», відокремлені комами" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: некоректна назва параметра" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "Ðекоректне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Ðепідтримуваний рівень ÑтиÑÐºÐ°Ð½Ð½Ñ LZMA1/LZMA2: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Сума lc Ñ– lp не повинна перевищувати 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: назва файла має невідомий ÑуфікÑ; пропуÑкаємо" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: файл вже має ÑÑƒÑ„Ñ–ÐºÑ Ð½Ð°Ð·Ð²Ð¸ %s; пропуÑкаємо" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: некоректний ÑÑƒÑ„Ñ–ÐºÑ Ð½Ð°Ð·Ð²Ð¸ файла" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ Ñ” невід'ємним деÑÑтковим цілим" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: некоректний ÑÑƒÑ„Ñ–ÐºÑ Ð¼Ð½Ð¾Ð¶Ð½Ð¸ÐºÐ°" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Коректними Ñ” ÑуфікÑи «KiB» (2^10), «MiB» (2^20) та «GiB» (2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° «%s» має належати до діапазону [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "СтиÑнені дані неможливо прочитати з термінала" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "СтиÑнені дані неможливо запиÑати до термінала" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "КориÑтуваннÑ: %s [--help] [--version] [ФÐЙЛ]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "Показати відомоÑті, що зберігаютьÑÑ Ñƒ заголовку файла .lzma." + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Файл Ñ” надто малим, щоб бути файлом .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Ðе Ñ” файлом .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати дані до Ñтандартного виведеннÑ" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Ðевідома помилка" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "Ðепідтримуваний набір параметрів" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "Ðепідтримуваний прапорець у наборі параметрів" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "Ðевідома назва параметра" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° не може бути порожнім" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð·Ð° діапазоном" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "У цьому параметрі не передбачено викориÑÑ‚Ð°Ð½Ð½Ñ ÑуфікÑів-множників" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "некоректний ÑÑƒÑ„Ñ–ÐºÑ Ð¼Ð½Ð¾Ð¶Ð½Ð¸ÐºÐ° (KiB, MiB або GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "Ðевідома назва фільтра" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "Цей фільтр не можна викориÑтовувати у форматі .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ міÑце у пам'Ñті" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "Ðе можна викориÑтовувати порожній Ñ€Ñдок; Ñпробуйте «6», Ñкщо потрібне типове значеннÑ" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "МакÑимальна кількіÑть фільтрів — чотири" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "Пропущено назву фільтра" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "Ðекоректний ланцюжок Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ (пропущено lzma2 у кінці?)" diff --git a/cpp/third_party/xz-5.8.3/po/vi.gmo b/cpp/third_party/xz-5.8.3/po/vi.gmo new file mode 100644 index 0000000000000000000000000000000000000000..6b124fe4c6392b87cf9fa57555365f81b907035e GIT binary patch literal 16808 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 literal 0 HcmV?d00001 diff --git a/cpp/third_party/xz-5.8.3/po/vi.po b/cpp/third_party/xz-5.8.3/po/vi.po new file mode 100644 index 000000000..c46e1303e --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/vi.po @@ -0,0 +1,1671 @@ +# SPDX-License-Identifier: 0BSD +# +# Vietnamese translations for xz package +# Bản dịch tiếng Việt cho gói xz. +# This file is published under the BSD Zero Clause License. +# Trần Ngá»c Quân , 2014-2024. +# +msgid "" +msgstr "" +"Project-Id-Version: xz 5.6.0-pre2\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2024-02-24 10:23+0700\n" +"Last-Translator: Trần Ngá»c Quân \n" +"Language-Team: Vietnamese \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Gtranslator 42.0\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s: Äối số cho --block-list không hợp lệ" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s: Quá nhiá»u đối số cho --block-list" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "Trong --block-list, cỡ khối thiếu sau số mắt xích bá»™ lá»c '%c:'" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 chỉ có thể dùng như là phần tá»­ cuối trong --block-list" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s: Không hiểu kiểu định dạng tập tin" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%s: Không há»— trợ kiểu kiểm tra toàn vẹn" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "Chỉ được đưa ra má»™t tập tin cho “--files†hay “--files0â€." + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "Biến môi trưá»ng %s chứa quá nhiá»u đối số" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "Há»— trợ nén đã bị vô hiệu hóa tại thá»i Ä‘iểm biên dịch" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "Há»— trợ giải nén đã bị vô hiệu hóa tại thá»i Ä‘iểm biên dịch" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "Nén tệp lzip (.lz) không được há»— trợ" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list bị bá» qua trừ khi nén theo định dạng .xz" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "Vá»›i --format=raw, --suffix=.SUF được yêu cầu trừ trưá»ng hợp ghi ra đầu ra tiêu chuẩn" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "Số lượng bá»™ lá»c tối Ä‘a là bốn" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "Có lá»—i trong tùy chá»n --filters%s=FILTERS:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "Mức giá»›i hạn dùng bá»™ nhá»› là quá thấp cho việc cài đặt bá»™ lá»c đã cho." + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "móc xích lá»c %u được sá»­ dụng bởi --block-list nhưng lại chưa đưa ra gì vá»›i --filters%u=" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "Dùng hiện tại trong chế độ thô là ngá»› ngẩn." + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "Các tùy chá»n trích xuất cá»§a chỉnh trước có thể biến đổi phụ thuá»™c vào phiên bản." + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "Äịnh dạng .lzma chỉ há»— trợ bá»™ lá»c LZMA1" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 không thể được dùng vá»›i định dạng .xz" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "Móc xích lá»c %u là không tương thích vá»›i --flush-timeout" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "Chuyển sang chế độ đơn tuyến trình bởi vì --flush-timeout" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "Các tùy chá»n không được há»— trợ trong chuá»—i móc xích %u" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "Dùng đến % tuyến trình." + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "Không há»— trợ lá»c móc xích hay tùy chá»n lá»c" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "Giải nén sẽ cần %s MiB bá»™ nhá»›." + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "Äã giảm số lượng tuyến trình từ %s xuống %s để không vượt quá giá»›i hạn sá»­ dụng bá»™ nhá»› là %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "Äã giảm số lượng tuyến trình từ %s xuống còn má»™t. Giá»›i hạn sá»­ dụng bá»™ nhá»› tá»± động %s MiB vẫn Ä‘ang bị vượt quá. Cần có %s MiB bá»™ nhá»›. Vẫn tiếp tục." + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "Chuyển sang chế độ đơn tuyến trình để không vượt quá giá»›i hạn sá»­ dụng bá»™ nhá»› là %sMiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Chỉnh cỡ từ Ä‘iển LZMA%c từ %s MiB thành %s MiB để không vượt quá giá»›i hạn tiêu dùng bá»™ nhá»› là %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "Chỉnh cỡ từ Ä‘iển LZMA%c cho --filters%u từ %s MiB thành %s MiB để không vượt quá giá»›i hạn tiêu dùng bá»™ nhá»› là %s MiB" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "Gặp lá»—i thay đổi chuá»—i móc xích lá»c %u: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "Gặp lá»—i khi tạo má»™t ống dẫn: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s: hàm poll() bị lá»—i: %s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s: Tập tin có lẽ đã bị di chuyển, không phải gỡ bá»" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s: Không thể gỡ bá»: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s: Không thể đặt chá»§ sở hữu tập tin: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s: Không thể đặt nhóm tập tin: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s: Không thể đặt chế độ Ä‘á»c ghi cho tập tin: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s: Gặp lá»—i khi đóng tập tin: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s: Gặp lá»—i khi đóng tập tin: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "Gặp lá»—i khi lấy các cá» trạng thái tập tin từ đầu vào tiêu chuẩn: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s: Là má»™t liên kết má»m nên bá» qua" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s: Không phải là má»™t thư mục nên bá» qua" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%s: Không phải là tập tin thưá»ng nên bá» qua" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s: Tập tin có đặt bít setuid hoặc setgid nên bá» qua" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%s: Tập tin có bít sticky nên bá» qua" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s: Tập tin đầu vào có nhiá»u hÆ¡n má»™t liên kết cứng nên bá» qua" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "Tên tập tin trống rá»—ng nên bá» qua" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "Gặp lá»—i khi phục hồi các cá» trạng thái tá»›i đầu vào tiêu chuẩn: %s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "Gặp lá»—i khi lấy các cá» trạng thái tập tin từ đầu vào tiêu chuẩn: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s: Gặp lá»—i khi đóng tập tin: %s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%s: Không phải là tập tin thưá»ng nên bá» qua" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "Gặp lá»—i khi phục hồi cá» O_APPEND trên đầu ra tiêu chuẩn: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s: Gặp lá»—i khi đóng tập tin: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s: Gặp lá»—i khi di chuyển vị trí Ä‘á»c khi cố tạo má»™t tập tin rải rác: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s: Lá»—i Ä‘á»c: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s: Gặp lá»—i khi di chuyển vị trí Ä‘á»c tập tin: %s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s: Kết thúc tập tin bất ngá»" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s: Lá»—i ghi: %s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "Bị tắt" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "Tổng dung lượng bá»™ nhá»› vật lý (RAM):" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "Số luồng bá»™ xá»­ lý:" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "Nén:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "Giải nén:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "Giải nén Ä‘a luồng:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "Mặc định cho -T0:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "Thông tin phần cứng:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "Äã chạm mốc giá»›i hạn sá»­ dụng bá»™ nhá»›:" + +#: src/xz/list.c +msgid "Streams:" +msgstr "Các luồng dữ liệu:" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "Khối:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "Kích cỡ đã nén:" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "Kích cỡ đã giải nén:" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "Tỉ lệ:" + +#: src/xz/list.c +msgid "Check:" +msgstr "Kiểm tra:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "Äệm luồng dữ liệu:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "Bá»™ nhá»› cần:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "Kích cỡ phần đầu:" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "Số lượng tập tin:" + +#: src/xz/list.c +msgid "Stream" +msgstr "Luồng dữ liệu" + +#: src/xz/list.c +msgid "Block" +msgstr "Khối" + +#: src/xz/list.c +msgid "Blocks" +msgstr "Khối" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "BùNén" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "BùGiảiNén" + +#: src/xz/list.c +msgid "CompSize" +msgstr "CỡNén" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "CỡGiảiNén" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "CỡTổng" + +#: src/xz/list.c +msgid "Ratio" +msgstr "Tá»· lệ" + +#: src/xz/list.c +msgid "Check" +msgstr "Kiểm tra" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "Gtr.Kiểm" + +#: src/xz/list.c +msgid "Padding" +msgstr "Äệm" + +#: src/xz/list.c +msgid "Header" +msgstr "Phần đầu" + +#: src/xz/list.c +msgid "Flags" +msgstr "Cá»" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "DùngBá»™Nhá»›" + +#: src/xz/list.c +msgid "Filters" +msgstr "Bá»™ lá»c" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "Không" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "ChưaBiết2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "ChưaBiết3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "ChưaBiết5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "ChưaBiết6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "ChưaBiết7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "ChưaBiết8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "ChưaBiết9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "ChưaBiết11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "ChưaBiết12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "ChưaBiết13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "ChưaBiết14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "ChưaBiết15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s: Tập tin trống rá»—ng" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s: Là quá nhỠđối vá»›i tập tin .xz hợp lệ" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "Luồng Khối Nén Giải nén Tá»· lệ Ktra Tập tin" + +#: src/xz/list.c +msgid "Yes" +msgstr "Có" + +#: src/xz/list.c +msgid "No" +msgstr "Không" + +#: src/xz/list.c +#, fuzzy +#| msgid " Minimum XZ Utils version: %s\n" +msgid "Minimum XZ Utils version:" +msgstr " Phiên bản “XZ Utils†tối thiểu: %s\n" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s tập tin\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "Tổng cá»™ng:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list chỉ hoạt động trên các tập tin .xz (--format=xz hay --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "Thá»­ 'lzmainfo' vá»›i các tập tin .lzma." + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list không há»— trợ Ä‘á»c từ đầu vào tiêu chuẩn" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%s: Gặp lá»—i khi Ä‘á»c tên tập tin: %s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%s: Gặp kết thúc đầu vào bất ngá» khi Ä‘á»c các tên tập tin" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%s: Gặp ký hiệu null khi Ä‘á»c tên tập tin; có lẽ ý bạn muốn là dùng “--files0†chứ không phải “--files'?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "Nén và giải nén vá»›i --robot vẫn chưa được há»— trợ." + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "Không thể Ä‘á»c dữ liệu từ đầu vào tiêu chuẩn khi Ä‘á»c tập tin từ đầu vào tiêu chuẩn" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s: " + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "Lá»—i ná»™i bá»™ (lá»—i)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "Không thể thiết lập bá»™ xá»­ lý tín hiệu" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "Không có kiểm tra toàn vẹn nên không thể thẩm tra tính toàn vẹn cá»§a tập tin" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "Kiểu kiểm tra toàn vẹn chưa được há»— trợ; nên không thể thẩm tra tính toàn vẹn cá»§a tập tin" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "Äã chạm mốc giá»›i hạn sá»­ dụng bá»™ nhá»›" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "Không nhận ra định dạng tập tin" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "Tùy chá»n không được há»— trợ" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "Dữ liệu đã nén bị há»ng" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "Gặp kết thúc đầu vào bất ngá»" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "Yêu cầu cần có %s MiB bá»™ nhá»›. Nhưng giá»›i hạn bị tắt." + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "Yêu cầu cần có %s MiB bá»™ nhá»›. Nhưng giá»›i hạn là %s." + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s: Móc xích lá»c: %s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "Hãy chạy lệnh “%s --help†để xem thông tin thêm." + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "Usage: %s [OPTION]... [FILE]...\n" +#| "Compress or decompress FILEs in the .xz format.\n" +#| "\n" +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" +"Cách dùng: %s [TÙY CHỌN]... [TẬP TIN]...\n" +"Nén hoặc giải nén các TẬP TIN có định dạng .xz.\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "Các tùy chá»n dài bắt buá»™c phải có đối số thì vá»›i tùy chá»n ngắn cÅ©ng vậy.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr " Chế độ thao tác:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force compression" +msgstr "Giải nén:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force decompression" +msgstr "Giải nén:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +" Bá»™ chỉnh sá»­a thao tác:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "Gặp lá»—i khi ghi dữ liệu vào đầu ra tiêu chuẩn" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --single-stream decompress only the first stream, and silently\n" +#| " ignore possible remaining input data" +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" +" --single-stream chỉ giải nén luồng dữ liệu đầu, và bá» qua\n" +" dữ liệu đầu vào còn lại có thể" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Basic file format and compression options:\n" +msgid "Basic file format and compression options:" +msgstr "" +"\n" +" Các tùy chá»n vỠđịnh dạng và nén cÆ¡ bản:\n" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --ignore-check don't verify the integrity check when decompressing" +msgid "don't verify the integrity check when decompressing" +msgstr " --ignore-check không thẩm tra tính toàn vẹn khi giải nén" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -0 ... -9 compression preset; default is 6; take compressor *and*\n" +#| " decompressor memory usage into account before using 7-9!" +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" +" -0 ... -9 đặt mức nén; mặc định là 6; tiêu dùng nhiá»u bá»™ nhá»› khi nén\n" +" và giải nén, nên tính toán trước khi dùng 7-9!" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -e, --extreme try to improve compression ratio by using more CPU time;\n" +#| " does not affect decompressor memory requirements" +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" +" -e, --extreme cố gắng nâng cao mức nén bằng cách dùng nhiá»u CPU hÆ¡n;\n" +" nhưng không yêu cần nhiá»u bá»™ nhá»› khi giải nén" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -T, --threads=NUM use at most NUM threads; the default is 0 which uses\n" +#| " as many threads as there are processor cores" +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" +" -T, --threads=Sá» dùng tối Ä‘a là Sá» tuyến trình; mặc định là 0 ý là\n" +" dùng số lượng bằng số lõi vi xá»­ lý" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-size=SIZE\n" +#| " start a new .xz block after every SIZE bytes of input;\n" +#| " use this to set the block size for threaded compression" +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" +" --block-size=Cá» \n" +" bắt đầu má»™t khối .xz má»›i sau má»—i Cá»  byte cá»§a đầu vào;\n" +" dùng tùy chá»n này để đặt cỡ khối cho nén tuyến trình" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-list=BLOCKS\n" +#| " start a new .xz block after the given comma-separated\n" +#| " intervals of uncompressed data; optionally, specify a\n" +#| " filter chain number (0-9) followed by a ':' before the\n" +#| " uncompressed data size" +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" +" --block-list=Cá» \n" +" bắt đầu má»™t khối .xz má»›i sau má»™t danh sách ngăn\n" +" cách bằng dấu phẩy nhịp dữ cá»§a dữ liệu chưa nén; tùy chá»n\n" +" chỉ định số móc xích bá»™ lá»c (0-9) theo sau là ':' trước\n" +" kích cỡ dữ liệu chưa nén" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --flush-timeout=TIMEOUT\n" +#| " when compressing, if more than TIMEOUT milliseconds has\n" +#| " passed since the previous flush and reading more input\n" +#| " would block, all pending data is flushed out" +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" +" --flush-timeout=THỜI_GIAN_CHỜ\n" +" khi Ä‘ang nén, nếu đã trải qua hÆ¡n THỜI_GIAN_CHỜ milli-giây\n" +" kể từ lần đẩy dữ liệu lên đĩa trước đó và Ä‘ang Ä‘á»c thêm\n" +" khối nữa, má»i dữ liệu Ä‘ang chá» sẽ được ghi lên đĩa" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --no-adjust if compression settings exceed the memory usage limit,\n" +#| " give an error instead of adjusting the settings downwards" +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" +" --no-adjust nếu các cài đặt nén vượt quá giá»›i hạn dùng bá»™ nhá»›,\n" +" đưa ra má»™t lá»—i thay vì sá»­a đổi các cài đặt xuống" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Custom filter chain for compression (alternative for using presets):" +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" +"\n" +" Móc xích lá»c tùy chỉnh cho nén (thay cho việc dùng chỉnh trước):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " --filters=FILTERS set the filter chain using the liblzma filter string\n" +#| " syntax; use --filters-help for more information" +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" +"\n" +" --filters=CÃC_BỘ_LỌC đặt móc xích bá»™ lá»c sá»­ dụng cú pháp chuá»—i bá»™ lá»c\n" +" liblzma dùng để biết thêm chi tiết" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters1=FILTERS ... --filters9=FILTERS\n" +#| " set additional filter chains using the liblzma filter\n" +#| " string syntax to use with --block-list" +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" +" --filters1=CÃC_BỘ_LỌC ... --filters9=CÃC_BỘ_LỌC\n" +" đặt móc xích lá»c thêm sá»­ dụng cú pháp chuá»—i bá»™ lá»c\n" +" liblzma để dùng vá»›i --block-list" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters-help display more information about the liblzma filter string\n" +#| " syntax and exit." +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" +" --filters-help hiển thị thêm thông tin vá» cú pháp bá»™ lá»c liblzma\n" +" rồi thoát." + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Number of processor threads:" +msgid "number of position bits" +msgstr "Số luồng bá»™ xá»­ lý:" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "compression mode" +msgstr "Giải nén:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +" Tùy chá»n khác:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -Q, --no-warn make warnings not affect the exit status" +msgid "make warnings not affect the exit status" +msgstr "" +" -Q, --no-warn làm cho các cảnh báo không ảnh hưởng đến\n" +" trạng thái thoát" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr "" +" --robot dùng các thông báo mà máy có thể phân tích\n" +" (hữu dụng vá»›i scripts)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --info-memory display the total amount of RAM and the currently active\n" +#| " memory usage limits, and exit" +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" +" --info-memory hiển thị tổng lượng RAM và mức giá»›i hạn tiêu dùng\n" +" bá»™ nhá»› hiện tại, rồi thoát" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version hiển thị số phiên bản và thoát" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"Không có TẬP_TIN, hoặc TẬP_TIN là “-â€, thì Ä‘á»c đầu vào tiêu chuẩn.\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"Hãy báo cáo lá»—i cho <%s> (bằng tiếng Anh hoặc Phần Lan).\n" +"Thông báo lá»—i dịch cho: .\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "Trang chá»§ %s: <%s>.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "ÄÂY LÀ PHIÊN BẢN PHÃT TRIỂN VÀ NÓ KHÔNG PHÙ HỢP VỚI MỤC ÄÃCH SẢN XUẤT." + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "" +#| "Filter chains are set using the --filters=FILTERS or\n" +#| "--filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain\n" +#| "can be separated by spaces or '--'. Alternatively a preset <0-9>[e] can be\n" +#| "specified instead of a filter chain.\n" +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" +"Các móc xích lá»c được đặt bằng --filters=CÃC_BỘ_LỌC hoặc các tùy chá»n\n" +"--filters1=CÃC_BỘ_LỌC ... --filters9=CÃC_BỘ_LỌC. Má»—i bá»™ lá»c trong chuá»—i\n" +"có thể được ngăn cách bằng khoảng trắng hoặc '--'. Cách khác là dùng <0-9>[e]\n" +"để chỉ định thay thay cho móc xích lá»c.\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "Các bá»™ lá»c và các tùy chá»n cá»§a chúng được há»— trợ là:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be 'name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s: Các tùy chá»n phải là các cặp “tên=giá_trị†ngăn cách nhau bằng dấu phẩy" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s: Tên tùy chá»n không hợp lệ" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s: Giá trị cá»§a tùy chá»n không hợp lệ" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "Hiện nay chưa há»— trợ LZMA1/LZMA2: %s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "Tổng số lượng lc và lp không được vượt quá 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%s: Tên tập tin có phần hậu tố chưa biết nên bá» qua" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s: Tập tin đã sẵn có hậu tố “%s†nên bá» qua" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s: Hậu tố tên tập tin không hợp lệ" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%s: Giá trị không phải là số thập phân nguyên không âm" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s: Hậu tố (đơn vị) nhân tố không hợp lệ" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "Các hậu tố (đơn vị) hợp lệ là “KiB†(2^10), “MiB†(2^20), và “GiB†(2^30)." + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "Giá trị cá»§a tùy chá»n “%s†phải nằm trong vùng [%, %]" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "Dữ liệu đã nén không thể Ä‘á»c từ thiết bị cuối" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "Dữ liệu đã nén không thể ghi ra thiết bị cuối" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" +"Cách dùng: %s [--help] [--version] [TẬP TIN]...\n" +"Hiển thị thông tin được lưu trong phần đầu cá»§a tập tin .lzma" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Show information stored in the .lzma file header." +msgstr "" +"Cách dùng: %s [--help] [--version] [TẬP TIN]...\n" +"Hiển thị thông tin được lưu trong phần đầu cá»§a tập tin .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "Tập tin quá nhỠđể có thể là má»™t tin .lzma" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "Không phải là má»™t tập tin .lzma" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "Gặp lá»—i khi ghi dữ liệu vào đầu ra tiêu chuẩn" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "Lá»—i chưa biết" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "Tùy chá»n không được há»— trợ" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "Không há»— trợ lá»c móc xích hay tùy chá»n lá»c" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s: Tên tùy chá»n không hợp lệ" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s: Hậu tố (đơn vị) nhân tố không hợp lệ" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s: Không hiểu kiểu định dạng tập tin" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "LZMA1 không thể được dùng vá»›i định dạng .xz" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "Số lượng bá»™ lá»c tối Ä‘a là bốn" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -z, --compress force compression\n" +#~ " -d, --decompress force decompression\n" +#~ " -t, --test test compressed file integrity\n" +#~ " -l, --list list information about .xz files" +#~ msgstr "" +#~ " -z, --compress ép buá»™c nén\n" +#~ " -d, --decompress ép buá»™c giải nén\n" +#~ " -t, --test kiểm tra tính toàn vẹn cá»§a tập tin nén\n" +#~ " -l, --list liệt kê các thông tin vá» tập tin .xz" + +#~ msgid "" +#~ " -k, --keep keep (don't delete) input files\n" +#~ " -f, --force force overwrite of output file and (de)compress links\n" +#~ " -c, --stdout write to standard output and don't delete input files" +#~ msgstr "" +#~ " -k, --keep giữ lại (đừng xóa) tập tin đầu vào\n" +#~ " -f, --force buá»™c ghi đè tập tin đầu ra và (giải) nén các liên kết\n" +#~ " -c, --stdout ghi ra đầu ra tiêu chuẩn và không xóa tập tin đầu vào" + +#~ msgid "" +#~ " --no-sparse do not create sparse files when decompressing\n" +#~ " -S, --suffix=.SUF use the suffix '.SUF' on compressed files\n" +#~ " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~ " omitted, filenames are read from the standard input;\n" +#~ " filenames must be terminated with the newline character\n" +#~ " --files0[=FILE] like --files but use the null character as terminator" +#~ msgstr "" +#~ " --no-sparse đừng tạo các tập tin rải rác khi giải nén\n" +#~ " -S, --suffix=.ÄUÔI dùng hậu tố “.ÄUÔI†trên các tập tin nén\n" +#~ " --files[=TẬP-TIN] Ä‘á»c các tập tin cần xá»­ lý từ TẬP-TIN; nếu không có\n" +#~ " TẬP-TIN thì tên tập tin sẽ được Ä‘á»c vào từ đầu vào tiêu\n" +#~ " chuẩn; chúng phải được kết thúc bằng ký tá»± dòng má»›i\n" +#~ " --files0[=TẬP-TIN] giống --files nhưng ký tá»± kết thúc là null" + +#~ msgid "" +#~ " -F, --format=FMT file format to encode or decode; possible values are\n" +#~ " 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'\n" +#~ " -C, --check=CHECK integrity check type: 'none' (use with caution),\n" +#~ " 'crc32', 'crc64' (default), or 'sha256'" +#~ msgstr "" +#~ " -F, --format=ÄDạng định dạng tập tin cần mã hóa hoặc giải mã; giá trị có thể\n" +#~ " là “auto†(mặc định), “xzâ€, “lzmaâ€, “lzipâ€, và “rawâ€\n" +#~ " -C, --check=KIỂM kiểu kiểm tra toàn vẹn: “none†(thận trá»ng khi dùng),\n" +#~ " “crc32â€, “crc64†(mặc định), hay “sha256â€" + +#, no-c-format +#~ msgid "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " --memlimit-mt-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " set memory usage limit for compression, decompression,\n" +#~ " threaded decompression, or all of these; LIMIT is in\n" +#~ " bytes, % of RAM, or 0 for defaults" +#~ msgstr "" +#~ " --memlimit-compress=GIỚI_HẠN\n" +#~ " --memlimit-decompress=GIỚI_HẠN\n" +#~ " --memlimit-mt-decompress=GIỚI_HẠN\n" +#~ " -M, --memlimit=GIỚI_HẠN\n" +#~ " đặt mức giá»›i hạn dùng bá»™ nhá»› cho việc nén, giải nén,\n" +#~ " giải nén tuyến trình, hoặc tất cả; GIỚI_HẠN có đơn vị là\n" +#~ " byte, % cá»§a RAM, hay 0 cho mặc định" + +#~ msgid "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n" +#~ " --lzma2[=OPTS] more of the following options (valid values; default):\n" +#~ " preset=PRE reset options to a preset (0-9[e])\n" +#~ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM number of literal context bits (0-4; 3)\n" +#~ " lp=NUM number of literal position bits (0-4; 0)\n" +#~ " pb=NUM number of position bits (0-4; 2)\n" +#~ " mode=MODE compression mode (fast, normal; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM maximum search depth; 0=automatic (default)" +#~ msgstr "" +#~ "\n" +#~ " --lzma1[=CTC] LZMA1 hay LZMA2; CÃC-TÙY-CHỌN là danh sách cá»§a không hoặc\n" +#~ " --lzma2[=CTC] hÆ¡n các tùy chá»n sau đây (giá trị hợp lệ; mặc định):\n" +#~ " preset=PRE các tùy chá»n tối ưu nén (0-9[e])\n" +#~ " dict=Sá» cỡ từ Ä‘iển (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=Sá» số bít ngữ cảnh văn bản (0-4; 3)\n" +#~ " lp=Sá» số bít vị trí văn bản (0-4; 0)\n" +#~ " pb=Sá» số bít vị trí (0-4; 2)\n" +#~ " mode=CHẾ_ÄỘ chế độ nén (fast, normal; normal)\n" +#~ " nice=Sá» chiá»u dài “tốt†cá»§a khá»›p (2-273; 64)\n" +#~ " mf=TÊN bá»™ tìm khá»›p (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=Sá» mức sâu tìm kiếm tối Ä‘a; 0=tá»± động (mặc định)" + +#~ msgid "" +#~ "\n" +#~ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~ " --arm[=OPTS] ARM BCJ filter\n" +#~ " --armthumb[=OPTS] ARM-Thumb BCJ filter\n" +#~ " --arm64[=OPTS] ARM64 BCJ filter\n" +#~ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~ " --sparc[=OPTS] SPARC BCJ filter\n" +#~ " --riscv[=OPTS] RISC-V BCJ filter\n" +#~ " Valid OPTS for all BCJ filters:\n" +#~ " start=NUM start offset for conversions (default=0)" +#~ msgstr "" +#~ "\n" +#~ " --x86[=OPTS] bá»™ lá»c x86 BCJ (32-bit và 64-bit)\n" +#~ " --arm[=OPTS] bá»™ lá»c ARM BCJ\n" +#~ " --armthumb[=OPTS] bá»™ lá»c ARM-Thumb BCJ\n" +#~ " --arm64[=OPTS] bá»™ lá»c ARM64 BCJ\n" +#~ " --powerpc[=OPTS] bá»™ lá»c PowerPC BCJ (chỉ big endian)\n" +#~ " --ia64[=OPTS] bá»™ lá»c IA-64 (Itanium) BCJ\n" +#~ " --sparc[=OPTS] bá»™ lá»c SPARC BCJ\n" +#~ " --riscv[=OPTS] bá»™ lá»c RISC-V BCJ\n" +#~ " các tùy chá»n hợp lệ cho má»i bá»™ lá»c BCJ:\n" +#~ " start=Sá» khoảng bù khởi đầu cho chuyển đổi (mặc định=0)" + +#~ msgid "" +#~ "\n" +#~ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" +#~ " dist=NUM distance between bytes being subtracted\n" +#~ " from each other (1-256; 1)" +#~ msgstr "" +#~ "\n" +#~ " --delta[=OPTS] bá»™ lá»c Delta;\n" +#~ " CÃC-TÙY-CHỌN hợp lệ (giá trị hợp lệ; mặc định):\n" +#~ " dist=Sá» khoảng cách giữa các byte được trừ từ\n" +#~ " những cái khác (1-256; 1)" + +#~ msgid "" +#~ " -q, --quiet suppress warnings; specify twice to suppress errors too\n" +#~ " -v, --verbose be verbose; specify twice for even more verbose" +#~ msgstr "" +#~ " -q, --quiet không xuất các cảnh báo;\n" +#~ " chỉ định hai lần nến bạn muốn chặn cả báo lá»—i\n" +#~ " -v, --verbose thông báo chi tiết; dùng hai lần nếu muốn chi tiết hÆ¡n" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help hiển thị trợ giúp dạng ngắn gá»n\n" +#~ " (chỉ liệt kê các tùy chá»n cÆ¡ bản)\n" +#~ " -H, --long-help hiển thị trợ giúp đầy đủ rồi thoát" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help hiển thị trợ giúp dạng ngắn gá»n rồi thoát\n" +#~ " -H, --long-help hiển thị trợ giúp đầy đủ\n" +#~ " (liệt kê cả những tùy chá»n cấp cao)" + +#~ msgid "Failed to enable the sandbox" +#~ msgstr "Không bật được sandbox" + +#~ msgid "Memory usage limit for compression: " +#~ msgstr "Mức giá»›i hạn dùng bá»™ nhá»› cho nén: " + +#~ msgid " Streams: %s\n" +#~ msgstr " Luồng dữ liệu: %s\n" + +#~ msgid " Blocks: %s\n" +#~ msgstr " Khối: %s\n" + +#~ msgid " Ratio: %s\n" +#~ msgstr " Tá»· lệ nén: %s\n" + +#~ msgid " Check: %s\n" +#~ msgstr " Kiểm tra: %s\n" + +#~ msgid "" +#~ " Streams:\n" +#~ " Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding" +#~ msgstr "" +#~ " Luồng dữ liệu:\n" +#~ " Luồng Khối BùNén BùGiảiNén CỡNén CỡGiảiNén Tá»·Lệ Ktra Äệm" + +#~ msgid "" +#~ " Blocks:\n" +#~ " Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check" +#~ msgstr "" +#~ " Khối:\n" +#~ " Luồng Khối BùNén BùGiảiNén CỡTổng CỡGiảiNén Tá»·Lệ Ktra" + +#~ msgid " CheckVal %*s Header Flags CompSize MemUsage Filters" +#~ msgstr " GTrịKiểm %*s Äầu Cá» CỡNén DùngRAM Bá»™Lá»c" + +#~ msgid "The selected match finder requires at least nice=%" +#~ msgstr "Bá»™ tìm khá»›p đã chá»n yêu cầu mức “tốt†ít nhất là nice=%" + +#~ msgid "Error setting O_NONBLOCK on standard input: %s" +#~ msgstr "Lá»—i cài đặt O_NONBLOCK trên đầu vào tiêu chuẩn: %s" + +#~ msgid "Error setting O_NONBLOCK on standard output: %s" +#~ msgstr "Lá»—i cài đặt O_NONBLOCK trên đầu ra tiêu chuẩn: %s" + +#~ msgid "" +#~ " --block-size=SIZE\n" +#~ " when compressing to the .xz format, start a new block\n" +#~ " after every SIZE bytes of input; 0=disabled (default)" +#~ msgstr "" +#~ " --block-size=Cá» \n" +#~ " khi nén thành định dạng .xz, bắt đầu khối má»›i\n" +#~ " sau má»—i Sá» byte đầu vào; 0=tắt (mặc định)" diff --git a/cpp/third_party/xz-5.8.3/po/xz.pot b/cpp/third_party/xz-5.8.3/po/xz.pot new file mode 100644 index 000000000..01e848406 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/xz.pot @@ -0,0 +1,1264 @@ +# SPDX-License-Identifier: 0BSD +# +# SOME DESCRIPTIVE TITLE. +# Copyright (C) The XZ Utils authors and contributors +# This file is published under the BSD Zero Clause License. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: xz 5.8.3\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-27 18:13+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "" + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "" + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "" + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr "" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "" + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "" + +#: src/xz/list.c +msgid "Streams:" +msgstr "" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "" + +#: src/xz/list.c +msgid "Check:" +msgstr "" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "" + +#: src/xz/list.c +msgid "Stream" +msgstr "" + +#: src/xz/list.c +msgid "Block" +msgstr "" + +#: src/xz/list.c +msgid "Blocks" +msgstr "" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "" + +#: src/xz/list.c +msgid "CompSize" +msgstr "" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "" + +#: src/xz/list.c +msgid "Ratio" +msgstr "" + +#: src/xz/list.c +msgid "Check" +msgstr "" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "" + +#: src/xz/list.c +msgid "Padding" +msgstr "" + +#: src/xz/list.c +msgid "Header" +msgstr "" + +#: src/xz/list.c +msgid "Flags" +msgstr "" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "" + +#: src/xz/list.c +msgid "Filters" +msgstr "" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr "" + +#: src/xz/list.c +msgid "Yes" +msgstr "" + +#: src/xz/list.c +msgid "No" +msgstr "" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "" +msgstr[1] "" + +#: src/xz/list.c +msgid "Totals:" +msgstr "" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "" + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "" + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "" + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "" + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of position bits" +msgstr "" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "" + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" diff --git a/cpp/third_party/xz-5.8.3/po/xz.pot-header b/cpp/third_party/xz-5.8.3/po/xz.pot-header new file mode 100644 index 000000000..6d277c90f --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po/xz.pot-header @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: 0BSD +# +# SOME DESCRIPTIVE TITLE. +# Copyright (C) The XZ Utils authors and contributors +# This file is published under the BSD Zero Clause License. +# FIRST AUTHOR , YEAR. +# diff --git a/cpp/third_party/xz-5.8.3/po/zh_CN.gmo b/cpp/third_party/xz-5.8.3/po/zh_CN.gmo new file mode 100644 index 0000000000000000000000000000000000000000..b9206e45833f169c59ad5fda7f8b2aa05f41aa4a GIT binary patch literal 14488 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 z, 2019, 2022, 2023, 2024. +# Mingye Wang , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: xz-5.6.0-pre2\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2024-08-27 13:08+0800\n" +"Last-Translator: Mingye Wang (Artoria2e5) \n" +"Language-Team: Chinese (simplified) \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.4.4\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s:--block-list çš„æ— æ•ˆå‚æ•°" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s:--block-list å¾—åˆ°è¿‡å¤šå‚æ•°" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "在 --block-list 中,å—大å°åœ¨è¿‡æ»¤å™¨é“¾ç¼–å· '%c:' 之åŽç¼ºå¤±" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 ä»…å¯ç”¨äºŽ --block-list 的最åŽä¸€ä¸ªå…ƒç´ " + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s:未知文件格å¼ç±»åž‹" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%sï¼šä¸æ”¯æŒçš„完整性检查类型" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "ä»…å¯ä½¿ç”¨ '--files' 或 '--files0' 指定å•个文件。" + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s:%s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "环境å˜é‡ %s 包å«è¿‡å¤šå‚æ•°" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "压缩支æŒå·²åœ¨æž„建时ç¦ç”¨" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "解压支æŒå·²åœ¨æž„建时ç¦ç”¨" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "䏿”¯æŒå¯¹ lzip 文件 (.lz) 的压缩" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "除éžåŽ‹ç¼©ä¸º .xz æ ¼å¼ï¼Œ--block-list 将被忽略" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "å¯ç”¨ --format-raw 选项时,必须指定 --suffix=.SUF 获知写入至标准输出" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "过滤器最多数é‡ä¸ºå››" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "在 --filters%s=过滤器 选项中出现错误:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "内存用é‡é™åˆ¶å¯¹æŒ‡å®šè¿‡æ»¤å™¨è®¾ç½®è¿‡ä½Žã€‚" + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "--block-list 使用了过滤器链 %u,但未ç»ç”± --filters%u= 指定" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "䏿ލè在 raw 模å¼ä½¿ç”¨é¢„设等级。" + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "å„个预设等级所使用的准确选项列表在ä¸åŒè½¯ä»¶ç‰ˆæœ¬ä¹‹é—´å¯èƒ½ä¸åŒã€‚" + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr ".lzma æ ¼å¼åªæ”¯æŒ LZMA1 过滤器" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 无法用于 .xz æ ¼å¼" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "过滤器链 %u å’Œ --flush-timeout ä¸å…¼å®¹" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "å›  --flush-timeout 而切æ¢è‡³å•线程模å¼" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "过滤器链 %u ä¸­å­˜åœ¨ä¸æ”¯æŒçš„选项" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "使用最多 % 个线程。" + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "䏿”¯æŒçš„过滤器链或过滤器选项" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "è§£åŽ‹ç¼©éœ€è¦ %s MiB 的内存。" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "已将所使用的线程数从 %s å‡å°ä¸º %s,以ä¸è¶…出 %s MiB 的内存用é‡é™åˆ¶" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "已将所使用的线程数从 %s å‡å°ä¸º 1。这ä»ç„¶è¶…出了自动的内存使用é™åˆ¶ %s MiBã€‚éœ€è¦ %s MiB 的内存。继续æ“作。" + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "正在切æ¢åˆ°å•线程模å¼ä»¥ä¸è¶…出 %s MiB 的内存用é‡é™åˆ¶" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "已调整 LZMA%c 字典大å°ï¼ˆä»Ž %s MiB 调整为 %s MiB),以ä¸è¶…出 %s MiB 的内存用é‡é™åˆ¶" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "已调整 --filters%2$u LZMA%1$c 字典大å°ï¼ˆä»Ž %3$s MiB 调整为 %4$s MiB),以ä¸è¶…出 %5$s MiB 的内存用é‡é™åˆ¶" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "更改为过滤器链 %u 时出错:%s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "åˆ›å»ºç®¡é“æ—¶å‡ºé”™ï¼š%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s:poll() 失败:%s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s:文件似乎已移动,ä¸å†è¿›è¡Œåˆ é™¤æ“作" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s:无法删除:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s:无法设置文件所有者:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s:无法设置文件所有组:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s:无法设置文件æƒé™ï¼š%s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the file failed: %s" +msgstr "%s:关闭文件失败:%s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%s:关闭文件失败:%s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "ä»Žæ ‡å‡†è¾“å…¥èŽ·å–æ–‡ä»¶çŠ¶æ€æ ‡å¿—出错:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s:是符å·é“¾æŽ¥ï¼Œè·³è¿‡" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s:是目录,跳过" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%sï¼šä¸æ˜¯æ ‡å‡†æ–‡ä»¶ï¼Œè·³è¿‡" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s:文件有设置用户ID或设置组ID标识,跳过" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%sï¼šæ–‡ä»¶æœ‰ç²˜æ»žä½æ ‡è¯†ï¼Œè·³è¿‡" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s:输入文件有多于一个硬链接,跳过" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "空文件å,跳过" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "å›žå¤æ ‡å‡†è¾“å…¥çš„çŠ¶æ€æ ‡å¿—时出错:%s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "èŽ·å–æ ‡å‡†è¾“å‡ºçš„æ–‡ä»¶çŠ¶æ€æ ‡å¿—时出错:%s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Closing the file failed: %s" +msgid "%s: Opening the directory failed: %s" +msgstr "%s:关闭文件失败:%s" + +#: src/xz/file_io.c +#, fuzzy, c-format +#| msgid "%s: Not a regular file, skipping" +msgid "%s: Destination is not a regular file" +msgstr "%sï¼šä¸æ˜¯æ ‡å‡†æ–‡ä»¶ï¼Œè·³è¿‡" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "æ¢å¤æ ‡å‡†è¾“出的 O_APPEND 标志时出错:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s:关闭文件失败:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s:å°è¯•åˆ›å»ºç¨€ç–æ–‡ä»¶æ—¶ seek 失败:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%s:读å–错误:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s:seek 文件时出错:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%s:未预期的文件结æŸ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s:写入错误:%s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "å·²ç¦ç”¨" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "物ç†å†…存(RAM)用é‡ï¼š" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "处ç†å™¨çº¿ç¨‹æ•°ï¼š" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "压缩:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "解压缩:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "多线程解压缩:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "-T0 的默认值:" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "硬件信æ¯ï¼š" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "内存使用é™åˆ¶ï¼š" + +#: src/xz/list.c +msgid "Streams:" +msgstr "æµï¼š" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "å—:" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "压缩åŽå¤§å°ï¼š" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "解压缩大å°ï¼š" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "比例:" + +#: src/xz/list.c +msgid "Check:" +msgstr "校验:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "æµå¡«å……大å°ï¼š" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "所需内存:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "头部存放大å°ï¼š" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "文件数é‡ï¼š" + +#: src/xz/list.c +msgid "Stream" +msgstr "æµ" + +#: src/xz/list.c +msgid "Block" +msgstr "å—" + +#: src/xz/list.c +msgid "Blocks" +msgstr "å—" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "压缩åç§»é‡" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "解压åç§»é‡" + +#: src/xz/list.c +msgid "CompSize" +msgstr "压缩åŽå¤§å°" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "解压缩大å°" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "总大å°" + +#: src/xz/list.c +msgid "Ratio" +msgstr "比例" + +#: src/xz/list.c +msgid "Check" +msgstr "校验" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "校验值" + +#: src/xz/list.c +msgid "Padding" +msgstr "å¡«å……" + +#: src/xz/list.c +msgid "Header" +msgstr "头部" + +#: src/xz/list.c +msgid "Flags" +msgstr "标志" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "内存用é‡" + +#: src/xz/list.c +msgid "Filters" +msgstr "过滤器" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "æ— " + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "未知-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "未知-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "未知-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "未知-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "未知-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "未知-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "未知-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "未知-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "未知-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "未知-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "未知-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "未知-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s:文件为空" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s:过å°ï¼Œä¸å¯èƒ½æ˜¯æœ‰æ•ˆçš„ .xz 文件" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr " æµ å— åŽ‹ç¼©å¤§å° è§£åŽ‹å¤§å° æ¯”ä¾‹ 校验 文件å" + +#: src/xz/list.c +msgid "Yes" +msgstr "是" + +#: src/xz/list.c +msgid "No" +msgstr "å¦" + +#: src/xz/list.c +#, fuzzy +#| msgid " Minimum XZ Utils version: %s\n" +msgid "Minimum XZ Utils version:" +msgstr " 最低 XZ Utils 版本:%s\n" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s 文件\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "总计:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list 仅适用于 .xz 文件(--format=xz 或 --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "试试用“lzmainfoâ€å¤„ç† .lzma 文件。" + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list 䏿”¯æŒä»Žæ ‡å‡†è¾“入读å–" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%sï¼šè¯»å–æ–‡ä»¶å列表时出错:%s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%sï¼šè¯»å–æ–‡ä»¶å列表时é‡åˆ°æœªé¢„期的输入结æŸ" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%sï¼šè¯»å–æ–‡ä»¶å列表时获得了空字符;您å¯èƒ½æƒ³è¦ä½¿ç”¨ '--files0' è€Œéž '--files'?" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "å°šä¸æ”¯æŒå¸¦ --robot 的压缩和解压缩。" + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "æ— æ³•åŒæ—¶ä»Žæ ‡å‡†è¾“å…¥è¯»å–æ•°æ®å’Œæ–‡ä»¶å列表" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s:" + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "内部错误(bug)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "无法建立信å·å¤„ç†å™¨" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "无完整性检查;将ä¸éªŒè¯æ–‡ä»¶å®Œæ•´æ€§" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "䏿”¯æŒçš„完整性检查类型;将ä¸éªŒè¯æ–‡ä»¶å®Œæ•´æ€§" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "达到内存使用é™åˆ¶" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "无法识别文件格å¼" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "䏿”¯æŒçš„选项" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "压缩数æ®å·²æŸå" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "输入æ„外结æŸ" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "éœ€è¦ %s MiB 的内存空间。é™åˆ¶å·²ç¦ç”¨ã€‚" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "éœ€è¦ %s MiB 的内存空间。é™åˆ¶ä¸º %s。" + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%s:过滤器链:%s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "请å°è¯•执行 '%s --help' æ¥èŽ·å–æ›´å¤šä¿¡æ¯ã€‚" + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "Usage: %s [OPTION]... [FILE]...\n" +#| "Compress or decompress FILEs in the .xz format.\n" +#| "\n" +msgid "Compress or decompress FILEs in the .xz format." +msgstr "" +"用法:%s [选项]... [文件]...\n" +"使用 .xz æ ¼å¼åŽ‹ç¼©æˆ–è§£åŽ‹ç¼©æ–‡ä»¶ã€‚\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Mandatory arguments to long options are mandatory for short options too.\n" +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "å¿…é€‰å‚æ•°å¯¹é•¿çŸ­é€‰é¡¹åŒæ—¶é€‚用。\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " Operation mode:\n" +msgid "Operation mode:" +msgstr " æ“作模å¼ï¼š\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force compression" +msgstr "解压缩:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "force decompression" +msgstr "解压缩:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Operation modifiers:\n" +msgid "Operation modifiers:" +msgstr "" +"\n" +" æ“作修饰符:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Writing to standard output failed" +msgid "write to standard output and don't delete input files" +msgstr "写入标准输出失败" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --single-stream decompress only the first stream, and silently\n" +#| " ignore possible remaining input data" +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr " --single-stream 仅解压缩第一个æµï¼Œå¿½ç•¥å…¶åŽå¯èƒ½ç»§ç»­å‡ºçŽ°çš„è¾“å…¥æ•°æ®" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "" + +#: src/xz/message.c +msgid ".SUF" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "" + +#: src/xz/message.c +msgid "FILE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Basic file format and compression options:\n" +msgid "Basic file format and compression options:" +msgstr "" +"\n" +" 基本文件格å¼å’ŒåŽ‹ç¼©é€‰é¡¹ï¼š\n" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "" + +#: src/xz/message.c +msgid "NAME" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --ignore-check don't verify the integrity check when decompressing" +msgid "don't verify the integrity check when decompressing" +msgstr " --ignore-check 解压缩时ä¸è¦è¿›è¡Œå®Œæ•´æ€§æ£€æŸ¥éªŒè¯" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -0 ... -9 compression preset; default is 6; take compressor *and*\n" +#| " decompressor memory usage into account before using 7-9!" +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "" +" -0 ... -9 压缩预设等级;默认为 6;使用 7-9 的等级之å‰ï¼Œè¯·å…ˆè€ƒè™‘\n" +" 压缩和解压缩所需的内存用é‡ï¼ï¼ˆä¼šå ç”¨å¤§é‡å†…存空间)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -e, --extreme try to improve compression ratio by using more CPU time;\n" +#| " does not affect decompressor memory requirements" +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "" +" -e, --extreme å°è¯•使用更多 CPU æ—¶é—´æ¥æ”¹è¿›åŽ‹ç¼©æ¯”çŽ‡ï¼›\n" +" ä¸ä¼šå½±å“解压缩的内存需求é‡" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " -T, --threads=NUM use at most NUM threads; the default is 0 which uses\n" +#| " as many threads as there are processor cores" +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "" +" -T, --threads=æ•°é‡ ä½¿ç”¨æœ€å¤šæŒ‡å®šæ•°é‡çš„线程;默认值为 0,å³\n" +" å¯ä»¥ä½¿ç”¨ä¸Žå¤„ç†å™¨å†…核数é‡ç›¸åŒçš„线程数" + +#: src/xz/message.c +msgid "SIZE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-size=SIZE\n" +#| " start a new .xz block after every SIZE bytes of input;\n" +#| " use this to set the block size for threaded compression" +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "" +" --block-size=å—大å°\n" +" 输入æ¯è¯»å–指定å—大å°çš„æ•°æ®åŽå³å¼€å§‹ä¸€ä¸ªæ–°çš„ .xz å—ï¼›\n" +" 使用该选项å¯ä»¥è®¾ç½®å¤šçº¿ç¨‹åŽ‹ç¼©ä¸­çš„å—大å°" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --block-list=BLOCKS\n" +#| " start a new .xz block after the given comma-separated\n" +#| " intervals of uncompressed data; optionally, specify a\n" +#| " filter chain number (0-9) followed by a ':' before the\n" +#| " uncompressed data size" +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "" +" --block-list=å—大å°åˆ—表\n" +" 在所给出的未压缩数æ®é—´éš”大å°çš„æ•°æ®ä¹‹åŽå¼€å§‹ä¸€ä¸ªæ–°çš„\n" +" .xz å—(使用逗å·åˆ†éš”)\n" +" å¯é€‰ï¼šåœ¨æœªåŽ‹ç¼©å¤§å°ä¹‹å‰æä¾›ä¸€ä¸ªè¿‡æ»¤å™¨é“¾å·ï¼ˆ0-9),用\n" +" “:â€å’Œå¤§å°åˆ†å¼€" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --flush-timeout=TIMEOUT\n" +#| " when compressing, if more than TIMEOUT milliseconds has\n" +#| " passed since the previous flush and reading more input\n" +#| " would block, all pending data is flushed out" +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "" +" --flush-timeout=è¶…æ—¶æ—¶é—´\n" +" 进行压缩时,如果从上次刷洗输出之åŽç»è¿‡äº†æŒ‡å®šçš„è¶…æ—¶æ—¶é—´\n" +" ä¸”è¯»å–æ›´å¤šæ•°æ®ä¼šè¢«é˜»å¡žï¼Œåˆ™åˆ·æ´—输出所有缓冲数æ®" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --no-adjust if compression settings exceed the memory usage limit,\n" +#| " give an error instead of adjusting the settings downwards" +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr " --no-adjust 如果压缩设置超出内存用é‡é™åˆ¶ï¼Œä¸è°ƒæ•´è®¾ç½®è€Œç›´æŽ¥æŠ¥é”™" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Custom filter chain for compression (alternative for using presets):" +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "" +"\n" +" 用于压缩的自定义过滤器链(ä¸ä½¿ç”¨é¢„设等级时的备选用法):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " --filters=FILTERS set the filter chain using the liblzma filter string\n" +#| " syntax; use --filters-help for more information" +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "" +"\n" +"--filters=FILTERS 使用 liblzma 过滤器字符串语法设置过滤器链\n" +" 使用 --filters-help 了解更多信æ¯" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters1=FILTERS ... --filters9=FILTERS\n" +#| " set additional filter chains using the liblzma filter\n" +#| " string syntax to use with --block-list" +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "" +"--filters1=过滤器 ... --filters9=过滤器\n" +" 使用 liblzma 过滤器语法设置其他过滤器链,\n" +" 与 --block-list 一起使用的" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --filters-help display more information about the liblzma filter string\n" +#| " syntax and exit." +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "" +"--filters-help 显示有关 liblzma 过滤器字符串语法的更多信æ¯\n" +" ç„¶åŽé€€å‡ºã€‚" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal context bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "number of literal position bits" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Number of processor threads:" +msgid "number of position bits" +msgstr "处ç†å™¨çº¿ç¨‹æ•°ï¼š" + +#: src/xz/message.c +msgid "MODE" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "Decompression:" +msgid "compression mode" +msgstr "解压缩:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| "\n" +#| " Other options:\n" +msgid "Other options:" +msgstr "" +"\n" +" 其它选项:\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -Q, --no-warn make warnings not affect the exit status" +msgid "make warnings not affect the exit status" +msgstr " -Q, --no-warn 使得警告信æ¯ä¸å½±å“程åºé€€å‡ºè¿”回值" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " --robot use machine-parsable messages (useful for scripts)" +msgid "use machine-parsable messages (useful for scripts)" +msgstr " --robot 使用机器å¯è§£æžçš„ä¿¡æ¯ï¼ˆå¯¹äºŽè„šæœ¬æœ‰ç”¨ï¼‰" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid "" +#| " --info-memory display the total amount of RAM and the currently active\n" +#| " memory usage limits, and exit" +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr " --info-memory 显示 RAM 总é‡å’Œå½“å‰é…置的内存用é‡é™åˆ¶ï¼Œç„¶åŽé€€å‡º" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +#| msgid " -V, --version display the version number and exit" +msgid "display the version number and exit" +msgstr " -V, --version 显示软件版本å·å¹¶é€€å‡º" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "\n" +#| "With no FILE, or when FILE is -, read standard input.\n" +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "" +"\n" +"如果没有指定文件,或者文件为\"-\",则从标准输入读å–。\n" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "Report bugs to <%s> (in English or Finnish).\n" +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "" +"è¯·ä½¿ç”¨è‹±æ–‡æˆ–èŠ¬å…°è¯­å‘ <%s> 报告软件错误。\n" +"è¯·ä½¿ç”¨ä¸­æ–‡å‘ TP 简体中文翻译团队 \n" +"报告软件的简体中文翻译错误。\n" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "%s home page: <%s>\n" +msgid "%s home page: <%s>" +msgstr "%s 主页:<%s>\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "这是开å‘版本,ä¸é€‚用于生产环境使用。" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy, c-format +#| msgid "" +#| "Filter chains are set using the --filters=FILTERS or\n" +#| "--filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain\n" +#| "can be separated by spaces or '--'. Alternatively a preset <0-9>[e] can be\n" +#| "specified instead of a filter chain.\n" +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "" +"设置过滤器链使用 --filters=FILTERS 或\n" +"--filters1=FILTER … --filters9=FILTER选项。链中的æ¯ä¸ªè¿‡æ»¤å™¨\n" +"å¯ä»¥ç”¨ç©ºæ ¼æˆ–“--â€åˆ†éš”。或者å¯ä»¥æŒ‡å®šé¢„设 <0-9>[e]\n" +"è€Œä¸æ˜¯è¿‡æ»¤å™¨é“¾ã€‚\n" +"\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "支æŒçš„筛选器åŠå…¶é€‰é¡¹åŒ…括:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Options must be 'name=value' pairs separated with commas" +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "%s:选项必须按照 'åç§°=值' çš„æ ¼å¼æˆå¯¹å‡ºçŽ°ï¼Œä½¿ç”¨åŠè§’逗å·åˆ†éš”" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s:无效的选项åç§°" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option value" +msgid "Invalid option value" +msgstr "%s:无效的选项值" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "䏿”¯æŒçš„ LZMA1/LZMA2 预设等级:%s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "lc å’Œ lp 的和必须ä¸å¤§äºŽ 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%sï¼šæ–‡ä»¶åæœ‰æœªçŸ¥åŽç¼€ï¼Œè·³è¿‡" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s:文件已有 '%s' åŽç¼€å,跳过" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s:无效的文件ååŽç¼€" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Value is not a non-negative decimal integer" +msgid "Value is not a non-negative decimal integer" +msgstr "%sï¼šå€¼ä¸æ˜¯éžè´Ÿå进制整数" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s:无效的乘数åŽç¼€" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "有效的åŽç¼€åŒ…括“KiBâ€ï¼ˆ2^10)ã€â€œMiBâ€ï¼ˆ2^20)和“GiBâ€ï¼ˆ2^30)。" + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "选项“%sâ€çš„值必须ä½äºŽ [%, %] 范围内" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "压缩数æ®ä¸èƒ½ä»Žç»ˆç«¯è¯»å–" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "压缩数æ®ä¸èƒ½å‘终端写入" + +#: src/lzmainfo/lzmainfo.c +#, fuzzy, c-format +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "" +"用法:%s [--help] [--version] [文件]...\n" +"显示存储在 .lzma 文件头中的信æ¯" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +#, fuzzy +#| msgid "" +#| "Usage: %s [--help] [--version] [FILE]...\n" +#| "Show information stored in the .lzma file header" +msgid "Show information stored in the .lzma file header." +msgstr "" +"用法:%s [--help] [--version] [文件]...\n" +"显示存储在 .lzma 文件头中的信æ¯" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "%s:过å°ï¼Œä¸å¯èƒ½æ˜¯æœ‰æ•ˆçš„ .lzma 文件" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "䏿˜¯ .lzma 文件" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "写入标准输出失败" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "未知错误" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported options" +msgid "Unsupported preset" +msgstr "䏿”¯æŒçš„选项" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Unsupported filter chain or filter options" +msgid "Unsupported flag in the preset" +msgstr "䏿”¯æŒçš„过滤器链或过滤器选项" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid option name" +msgid "Unknown option name" +msgstr "%s:无效的选项åç§°" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Invalid multiplier suffix" +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "%s:无效的乘数åŽç¼€" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "%s: Unknown file format type" +msgid "Unknown filter name" +msgstr "%s:未知文件格å¼ç±»åž‹" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "LZMA1 cannot be used with the .xz format" +msgid "This filter cannot be used in the .xz format" +msgstr "LZMA1 无法用于 .xz æ ¼å¼" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "" + +#: src/liblzma/common/string_conversion.c +#, fuzzy +#| msgid "Maximum number of filters is four" +msgid "The maximum number of filters is four" +msgstr "过滤器最多数é‡ä¸ºå››" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "" + +#~ msgid "" +#~ " -z, --compress force compression\n" +#~ " -d, --decompress force decompression\n" +#~ " -t, --test test compressed file integrity\n" +#~ " -l, --list list information about .xz files" +#~ msgstr "" +#~ " -z, --compress 强制压缩\n" +#~ " -d, --decompress 强制解压缩\n" +#~ " -t, --test 测试压缩文件完整性\n" +#~ " -l, --list 列出 .xz 文件的信æ¯" + +#~ msgid "" +#~ " -k, --keep keep (don't delete) input files\n" +#~ " -f, --force force overwrite of output file and (de)compress links\n" +#~ " -c, --stdout write to standard output and don't delete input files" +#~ msgstr "" +#~ " -k, --keep ä¿ç•™ï¼ˆä¸è¦åˆ é™¤ï¼‰è¾“入文件\n" +#~ " -f, --force 强制覆写输出文件和(解)压缩链接\n" +#~ " -c, --stdout 呿 ‡å‡†è¾“å‡ºå†™å…¥ï¼ŒåŒæ—¶ä¸è¦åˆ é™¤è¾“入文件" + +#~ msgid "" +#~ " --no-sparse do not create sparse files when decompressing\n" +#~ " -S, --suffix=.SUF use the suffix '.SUF' on compressed files\n" +#~ " --files[=FILE] read filenames to process from FILE; if FILE is\n" +#~ " omitted, filenames are read from the standard input;\n" +#~ " filenames must be terminated with the newline character\n" +#~ " --files0[=FILE] like --files but use the null character as terminator" +#~ msgstr "" +#~ " --no-sparse 解压缩时ä¸è¦åˆ›å»ºç¨€ç–文件\n" +#~ " -S, --suffix=.SUF 压缩文件使用指定的“.SUFâ€åŽç¼€å\n" +#~ " --files[=文件] 从指定文件读å–è¦å¤„ç†çš„æ–‡ä»¶å列表;如果çœç•¥äº†æŒ‡å®šæ–‡ä»¶å,\n" +#~ " å°†ä»Žæ ‡å‡†è¾“å…¥è¯»å–æ–‡ä»¶å列表;文件å必须使用æ¢è¡Œç¬¦åˆ†éš”ã€ç»ˆæ­¢\n" +#~ " --files0[=文件] 类似 --files,但使用空(\\0)字符进行分隔" + +#~ msgid "" +#~ " -F, --format=FMT file format to encode or decode; possible values are\n" +#~ " 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'\n" +#~ " -C, --check=CHECK integrity check type: 'none' (use with caution),\n" +#~ " 'crc32', 'crc64' (default), or 'sha256'" +#~ msgstr "" +#~ " -F, --format=æ ¼å¼ è¦ç¼–ç æˆ–è§£ç çš„æ–‡ä»¶æ ¼å¼ï¼›å¯èƒ½çš„值包括\n" +#~ " “autoâ€ï¼ˆé»˜è®¤ï¼‰ã€â€œxzâ€ã€â€œlzmaâ€ã€\n" +#~ " “lzipâ€å’Œâ€œrawâ€\n" +#~ " -C, --check=类型 完整性检查类型:“noneâ€ï¼ˆè¯·è°¨æ…Žä½¿ç”¨ï¼‰ã€\n" +#~ " “crc32â€ã€â€œcrc64â€ï¼ˆé»˜è®¤ï¼‰æˆ–“sha256â€" + +#, no-c-format +#~ msgid "" +#~ " --memlimit-compress=LIMIT\n" +#~ " --memlimit-decompress=LIMIT\n" +#~ " --memlimit-mt-decompress=LIMIT\n" +#~ " -M, --memlimit=LIMIT\n" +#~ " set memory usage limit for compression, decompression,\n" +#~ " threaded decompression, or all of these; LIMIT is in\n" +#~ " bytes, % of RAM, or 0 for defaults" +#~ msgstr "" +#~ " --memlimit-compress=é™åˆ¶ç”¨é‡\n" +#~ " --memlimit-decompress=é™åˆ¶ç”¨é‡\n" +#~ " --memlimit-mt-decompress=é™åˆ¶ç”¨é‡\n" +#~ " -M, --memlimit=é™åˆ¶ç”¨é‡\n" +#~ " 设置压缩ã€è§£åŽ‹ç¼©ã€å¤šçº¿ç¨‹è§£åŽ‹ç¼©æˆ–è€…å…±åŒçš„内存用é‡é™åˆ¶ï¼›\n" +#~ " 所指定é™åˆ¶é‡å•ä½ä¸ºå­—èŠ‚ï¼Œæˆ–ä»¥ç™¾åˆ†å· % 结尾表示内存比例,\n" +#~ " 或者指定 0 å–软件默认值" + +#~ msgid "" +#~ "\n" +#~ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n" +#~ " --lzma2[=OPTS] more of the following options (valid values; default):\n" +#~ " preset=PRE reset options to a preset (0-9[e])\n" +#~ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=NUM number of literal context bits (0-4; 3)\n" +#~ " lp=NUM number of literal position bits (0-4; 0)\n" +#~ " pb=NUM number of position bits (0-4; 2)\n" +#~ " mode=MODE compression mode (fast, normal; normal)\n" +#~ " nice=NUM nice length of a match (2-273; 64)\n" +#~ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=NUM maximum search depth; 0=automatic (default)" +#~ msgstr "" +#~ "\n" +#~ " --lzma1[=选项] LZMA1 或 LZMA2;指定选项是用逗å·åˆ†éš”的下列选项的组åˆï¼Œ\n" +#~ " --lzma2[=选项] 值应当为零或大于零(有效值;默认值):\n" +#~ " preset=PRE 将选项é‡ç½®ä¸ºé¢„设é…ç½® (0-9[e])\n" +#~ " dict=æ•°å­— å­—å…¸å¤§å° (4KiB - 1536MiB; 8MiB)\n" +#~ " lc=æ•°å­— literal context ä½çš„æ•°é‡ (0-4; 3)\n" +#~ " lp=æ•°å­— literal position ä½çš„æ•°é‡ (0-4; 0)\n" +#~ " pb=æ•°å­— position ä½çš„æ•°é‡ (0-4; 2)\n" +#~ " mode=æ¨¡å¼ åŽ‹ç¼©æ¨¡å¼ (fast, normal; normal)\n" +#~ " nice=æ•°å­— 匹é…çš„ nice 值 (2-273; 64)\n" +#~ " mf=åç§° åŒ¹é…æœç´¢å™¨ match finder\n" +#~ " (hc3, hc4, bt2, bt3, bt4; bt4)\n" +#~ " depth=æ•°å­— 最大æœç´¢æ·±åº¦ï¼› 0=自动(默认)" + +#~ msgid "" +#~ "\n" +#~ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" +#~ " --arm[=OPTS] ARM BCJ filter\n" +#~ " --armthumb[=OPTS] ARM-Thumb BCJ filter\n" +#~ " --arm64[=OPTS] ARM64 BCJ filter\n" +#~ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" +#~ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" +#~ " --sparc[=OPTS] SPARC BCJ filter\n" +#~ " --riscv[=OPTS] RISC-V BCJ filter\n" +#~ " Valid OPTS for all BCJ filters:\n" +#~ " start=NUM start offset for conversions (default=0)" +#~ msgstr "" +#~ "\n" +#~ " --x86[=选项] x86 BCJ 过滤器(32 ä½å’Œ 64 ä½ï¼‰\n" +#~ " --arm[=选项] ARM BCJ 过滤器\n" +#~ " --armthumb[=选项] ARM-Thumb BCJ 过滤器\n" +#~ " --arm64[=选项] ARM64 BCJ 过滤器\n" +#~ " --powerpc[=选项] PowerPC BCJ 过滤器(仅大端åºï¼‰\n" +#~ " --ia64[=选项] IA-64 (Itanium,安腾) BCJ 过滤器\n" +#~ " --sparc[=选项] SPARC BCJ 过滤器\n" +#~ " --riscv[=选项] RISC-V BCJ 过滤器\n" +#~ " 所有过滤器å¯ç”¨é€‰é¡¹ï¼š\n" +#~ " start=æ•°å­— 转æ¢çš„èµ·å§‹åç§»é‡ï¼ˆé»˜è®¤=0)" + +#~ msgid "" +#~ "\n" +#~ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" +#~ " dist=NUM distance between bytes being subtracted\n" +#~ " from each other (1-256; 1)" +#~ msgstr "" +#~ "\n" +#~ " --delta[=选项] 增é‡è¿‡æ»¤å™¨ï¼›æœ‰æ•ˆé€‰é¡¹ï¼ˆæœ‰æ•ˆå€¼ï¼›é»˜è®¤å€¼ï¼‰ï¼š\n" +#~ " dist=NUM 相å‡çš„字节之间的è·ç¦» (1-256; 1)" + +#~ msgid "" +#~ " -q, --quiet suppress warnings; specify twice to suppress errors too\n" +#~ " -v, --verbose be verbose; specify twice for even more verbose" +#~ msgstr "" +#~ " -q, --quiet 䏿˜¾ç¤ºè­¦å‘Šä¿¡æ¯ï¼›æŒ‡å®šä¸¤æ¬¡å¯ä¸æ˜¾ç¤ºé”™è¯¯ä¿¡æ¯\n" +#~ " -v, --verbose 输出详细信æ¯ï¼›æŒ‡å®šä¸¤æ¬¡å¯ä»¥è¾“出更详细的信æ¯" + +#~ msgid "" +#~ " -h, --help display the short help (lists only the basic options)\n" +#~ " -H, --long-help display this long help and exit" +#~ msgstr "" +#~ " -h, --help 显示短帮助信æ¯ï¼ˆä»…列出基本选项)\n" +#~ " -H, --long-help 显示本长帮助信æ¯" + +#~ msgid "" +#~ " -h, --help display this short help and exit\n" +#~ " -H, --long-help display the long help (lists also the advanced options)" +#~ msgstr "" +#~ " -h, --help 显示本短帮助信æ¯å¹¶é€€å‡º\n" +#~ " -H, --long-help 显示长帮助信æ¯ï¼ˆåŒæ—¶åˆ—出高级选项)" + +#~ msgid "Failed to enable the sandbox" +#~ msgstr "沙盒å¯ç”¨å¤±è´¥" + +#~ msgid "The selected match finder requires at least nice=%" +#~ msgstr "æ‰€é€‰ä¸­çš„åŒ¹é…æœç´¢å™¨ï¼ˆmatch finderï¼‰è‡³å°‘éœ€è¦ nice=%" + +#~ msgid "Sandbox is disabled due to incompatible command line arguments" +#~ msgstr "沙盒已因ä¸å…¼å®¹çš„å‘½ä»¤è¡Œå‚æ•°è€Œç¦ç”¨" + +#~ msgid "Sandbox was successfully enabled" +#~ msgstr "å·²æˆåŠŸå¯ç”¨æ²™ç›’" + +#~ msgid "Memory usage limit for compression: " +#~ msgstr "用于压缩的内存用é‡é™åˆ¶ï¼š " + +#~ msgid " Streams: %s\n" +#~ msgstr " æµï¼š %s\n" + +#~ msgid " Blocks: %s\n" +#~ msgstr " å—: %s\n" + +#~ msgid " Ratio: %s\n" +#~ msgstr " 压缩比: %s\n" + +#~ msgid " Check: %s\n" +#~ msgstr " 校验方å¼ï¼š %s\n" + +#~ msgid "" +#~ " Streams:\n" +#~ " Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding" +#~ msgstr "" +#~ " æµï¼š\n" +#~ " æµ å— åŽ‹ç¼©åç§»é‡ è§£åŽ‹åç§»é‡ åŽ‹ç¼©å¤§å° è§£åŽ‹å¤§å° æ¯”ä¾‹ 校验 å¡«å……" + +#~ msgid "" +#~ " Blocks:\n" +#~ " Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check" +#~ msgstr "" +#~ " å—:\n" +#~ " æµ å— åŽ‹ç¼©åç§»é‡ è§£åŽ‹åç§»é‡ æ€»è®¡å¤§å° è§£åŽ‹å¤§å° æ¯”ä¾‹ 校验" + +#~ msgid " CheckVal %*s Header Flags CompSize MemUsage Filters" +#~ msgstr " CheckVal %*s 头部 标记 åŽ‹ç¼©å¤§å° å†…å­˜ä½¿ç”¨ 过滤器" diff --git a/cpp/third_party/xz-5.8.3/po/zh_TW.gmo b/cpp/third_party/xz-5.8.3/po/zh_TW.gmo new file mode 100644 index 0000000000000000000000000000000000000000..38ebcdbb81e66d155ca1fec2e3e628c92abfb716 GIT binary patch literal 26773 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, 2019, 2023, 2024 +msgid "" +msgstr "" +"Project-Id-Version: xz 5.7.1-dev1\n" +"Report-Msgid-Bugs-To: xz@tukaani.org\n" +"POT-Creation-Date: 2026-03-30 17:13+0300\n" +"PO-Revision-Date: 2025-02-02 00:12+0800\n" +"Last-Translator: Yi-Jyun Pan \n" +"Language-Team: Chinese (traditional) \n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"X-Generator: Poedit 3.5\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: src/xz/args.c +#, c-format +msgid "%s: Invalid argument to --block-list" +msgstr "%s:傳入 --block-list çš„åƒæ•¸ç„¡æ•ˆ" + +#: src/xz/args.c +#, c-format +msgid "%s: Too many arguments to --block-list" +msgstr "%s:傳入 --block-list çš„åƒæ•¸éŽå¤š" + +#: src/xz/args.c +#, c-format +msgid "In --block-list, block size is missing after filter chain number '%c:'" +msgstr "在 --block-list 中,編號「%c:ã€å¾Œæ–¹éºæ¼å€å¡Šå¤§å°" + +#: src/xz/args.c +msgid "0 can only be used as the last element in --block-list" +msgstr "0 åªèƒ½ä½œç‚º --block-list 的最後一個元素" + +#: src/xz/args.c +#, c-format +msgid "%s: Unknown file format type" +msgstr "%s:未知檔案格å¼é¡žåž‹" + +#: src/xz/args.c +#, c-format +msgid "%s: Unsupported integrity check type" +msgstr "%sï¼šä¸æ”¯æ´çš„完整性檢查類型" + +#: src/xz/args.c +msgid "Only one file can be specified with '--files' or '--files0'." +msgstr "「--filesã€æˆ–「--files0ã€åªèƒ½æŒ‡å®šä¸€å€‹æª”案。" + +#. TRANSLATORS: This is a translatable +#. string because French needs a space +#. before the colon ("%s : %s"). +#: src/xz/args.c src/xz/coder.c src/xz/file_io.c src/xz/list.c src/xz/options.c +#: src/xz/util.c +#, c-format +msgid "%s: %s" +msgstr "%s:%s" + +#: src/xz/args.c +#, c-format +msgid "The environment variable %s contains too many arguments" +msgstr "%s 環境變數包å«éŽå¤šåƒæ•¸" + +#: src/xz/args.c +msgid "Compression support was disabled at build time" +msgstr "已在編譯時åœç”¨å£“縮支æ´" + +#: src/xz/args.c +msgid "Decompression support was disabled at build time" +msgstr "已在編譯時åœç”¨è§£å£“縮支æ´" + +#: src/xz/args.c +msgid "Compression of lzip files (.lz) is not supported" +msgstr "䏿”¯æ´å£“縮為 lzip 檔案 (.lz)" + +#: src/xz/args.c +msgid "--block-list is ignored unless compressing to the .xz format" +msgstr "--block-list åªæœ‰åœ¨å£“ç¸®æˆ .xz æ ¼å¼æ™‚æ‰æœƒç”Ÿæ•ˆ" + +#: src/xz/args.c +msgid "With --format=raw, --suffix=.SUF is required unless writing to stdout" +msgstr "æ­é… --format=raw 時,除éžå¯«å…¥æ¨™æº–輸出,å¦å‰‡éœ€è¦å‚³å…¥ --suffix=.SUF" + +#: src/xz/coder.c +msgid "Maximum number of filters is four" +msgstr "最多åªèƒ½æŒ‡å®š 4 å€‹éŽæ¿¾å™¨" + +#: src/xz/coder.c +#, c-format +msgid "Error in --filters%s=FILTERS option:" +msgstr "--filters%s=FILTERS é¸é …發生錯誤:" + +#: src/xz/coder.c +msgid "Memory usage limit is too low for the given filter setup." +msgstr "記憶體用é‡é™åˆ¶éŽä½Žï¼Œä¸è¶³ä»¥è¨­å®šæŒ‡å®šçš„éŽæ¿¾å™¨ã€‚" + +#: src/xz/coder.c +#, c-format +msgid "filter chain %u used by --block-list but not specified with --filters%u=" +msgstr "--block-list 使用了 %u,但未使用 --filters%u= 指定" + +#: src/xz/coder.c +msgid "Using a preset in raw mode is discouraged." +msgstr "ä¸å»ºè­°åœ¨ Raw 模å¼ä½¿ç”¨è¨­å®šæª”。" + +#: src/xz/coder.c +msgid "The exact options of the presets may vary between software versions." +msgstr "設定檔的é¸é …å¯èƒ½å› è»Ÿé«”版本而有異。" + +#: src/xz/coder.c +msgid "The .lzma format supports only the LZMA1 filter" +msgstr ".lzma æ ¼å¼åƒ…æ”¯æ´ LZMA1 éŽæ¿¾å™¨" + +#: src/xz/coder.c +msgid "LZMA1 cannot be used with the .xz format" +msgstr "LZMA1 ä¸èƒ½èˆ‡ .xz æ ¼å¼ä¸€åŒä½¿ç”¨" + +#: src/xz/coder.c +#, c-format +msgid "Filter chain %u is incompatible with --flush-timeout" +msgstr "éŽæ¿¾éˆ %u 與 --flush-timeout ä¸ç›¸å®¹" + +#: src/xz/coder.c +msgid "Switching to single-threaded mode due to --flush-timeout" +msgstr "因指定 --flush-timeout,因此切æ›åˆ°å–®åŸ·è¡Œç·’模å¼" + +#: src/xz/coder.c +#, c-format +msgid "Unsupported options in filter chain %u" +msgstr "éŽæ¿¾éˆ %u 䏿”¯æ´æ­¤é¸é …" + +#: src/xz/coder.c +#, c-format +msgid "Using up to % threads." +msgstr "使用最多 % 個執行緒。" + +#: src/xz/coder.c +msgid "Unsupported filter chain or filter options" +msgstr "䏿”¯æ´çš„æˆ–éŽæ¿¾å™¨é¸é …" + +#: src/xz/coder.c +#, c-format +msgid "Decompression will need %s MiB of memory." +msgstr "è§£å£“ç¸®å°‡éœ€è¦ %s MiB 的記憶體。" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to %s to not exceed the memory usage limit of %s MiB" +msgstr "已將執行緒數é‡å¾ž %s 個減少至 %s 個,以ä¸è¶…éŽè¨˜æ†¶é«”用é‡çš„ %s MiB é™åˆ¶" + +#: src/xz/coder.c +#, c-format +msgid "Reduced the number of threads from %s to one. The automatic memory usage limit of %s MiB is still being exceeded. %s MiB of memory is required. Continuing anyway." +msgstr "已將執行緒數é‡å¾ž %s 減少至一個,但ä¾ç„¶è¶…出 %s MiB 的自動記憶體用é‡é™åˆ¶ã€‚éœ€è¦ %s MiB 的記憶體。ä¾ç„¶ç¹¼çºŒåŸ·è¡Œã€‚" + +#: src/xz/coder.c +#, c-format +msgid "Switching to single-threaded mode to not exceed the memory usage limit of %s MiB" +msgstr "正在切æ›è‡³å–®åŸ·è¡Œç·’模å¼ï¼Œä»¥å…超出 %s MiB 的記憶體用é‡é™åˆ¶" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "已將 LZMA%c 的字典大å°å¾ž %s MiB 調整至 %s MiB,以ä¸è¶…éŽè¨˜æ†¶é«”用é‡çš„ %s MiB é™åˆ¶" + +#: src/xz/coder.c +#, c-format +msgid "Adjusted LZMA%c dictionary size for --filters%u from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB" +msgstr "已將 --filters%2$u çš„ LZMA%1$c 字典大å°ï¼Œå°‡ %3$s MiB 調整為 %4$s MiB,以é¿å…è¶…éŽ %5$s MiB 的記憶體用é‡é™åˆ¶" + +#: src/xz/coder.c +#, c-format +msgid "Error changing to filter chain %u: %s" +msgstr "變更為 %u 時發生錯誤:%s" + +#: src/xz/file_io.c +#, c-format +msgid "Error creating a pipe: %s" +msgstr "建立管線時發生錯誤:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: poll() failed: %s" +msgstr "%s:poll() 失敗:%s" + +#. TRANSLATORS: When compression or decompression finishes, +#. and xz is going to remove the source file, xz first checks +#. if the source file still exists, and if it does, does its +#. device and inode numbers match what xz saw when it opened +#. the source file. If these checks fail, this message is +#. shown, %s being the filename, and the file is not deleted. +#. The check for device and inode numbers is there, because +#. it is possible that the user has put a new file in place +#. of the original file, and in that case it obviously +#. shouldn't be removed. +#: src/xz/file_io.c +#, c-format +msgid "%s: File seems to have been moved, not removing" +msgstr "%s:檔案似乎已經é·ç§»ï¼Œä¸ç§»é™¤" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot remove: %s" +msgstr "%s:無法移除:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file owner: %s" +msgstr "%s:無法設定檔案所有者:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file group: %s" +msgstr "%s:無法設定檔案群組:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Cannot set the file permissions: %s" +msgstr "%s:無法設定檔案權é™ï¼š%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the file failed: %s" +msgstr "%sï¼šåŒæ­¥æª”案失敗:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Synchronizing the directory of the file failed: %s" +msgstr "%sï¼šåŒæ­¥æª”案目錄失敗:%s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard input: %s" +msgstr "從標準輸入å–得檔案狀態旗標時發生錯誤:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a symbolic link, skipping" +msgstr "%s:是個符號連çµï¼Œè·³éŽ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Is a directory, skipping" +msgstr "%s:是個目錄,跳éŽ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Not a regular file, skipping" +msgstr "%sï¼šä¸æ˜¯ä¸€èˆ¬æª”案,跳éŽ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has setuid or setgid bit set, skipping" +msgstr "%s:檔案已設定 setuid 或 setgid ä½å…ƒï¼Œè·³éŽ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: File has sticky bit set, skipping" +msgstr "%sï¼šæª”æ¡ˆå·²è¨­å®šé»æ€§ä½å…ƒï¼ˆsticky bit),跳éŽ" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Input file has more than one hard link, skipping" +msgstr "%s:輸入檔有超éŽä¸€å€‹å¯¦éš›é€£çµ (hard link),跳éŽ" + +#: src/xz/file_io.c +msgid "Empty filename, skipping" +msgstr "空檔å,跳éŽ" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the status flags to standard input: %s" +msgstr "將狀態旗標還原到標準輸入時發生錯誤:%s" + +#: src/xz/file_io.c +#, c-format +msgid "Error getting the file status flags from standard output: %s" +msgstr "從標準輸出å–得檔案狀態旗標時發生錯誤:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Opening the directory failed: %s" +msgstr "%s:開啟目錄失敗:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Destination is not a regular file" +msgstr "%sï¼šç›®çš„åœ°ä¸æ˜¯ä¸€èˆ¬æª”案" + +#: src/xz/file_io.c +#, c-format +msgid "Error restoring the O_APPEND flag to standard output: %s" +msgstr "å°‡ O_APPEND 旗標還原到標準輸出時發生錯誤:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Closing the file failed: %s" +msgstr "%s:關閉檔案失敗:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Seeking failed when trying to create a sparse file: %s" +msgstr "%s:嘗試建立ç–鬆檔案時發生æœå°‹å¤±æ•—:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Read error: %s" +msgstr "%sï¼šè®€å–æ™‚發生錯誤:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Error seeking the file: %s" +msgstr "%s:æœå°‹æª”案時發生錯誤:%s" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Unexpected end of file" +msgstr "%sï¼šéžæœŸæœ›çš„æª”案çµå°¾" + +#: src/xz/file_io.c +#, c-format +msgid "%s: Write error: %s" +msgstr "%s:寫入時發生錯誤:%s" + +#: src/xz/hardware.c +msgid "Disabled" +msgstr "å·²åœç”¨" + +#: src/xz/hardware.c +msgid "Amount of physical memory (RAM):" +msgstr "實體記憶體 (RAM) 數é‡ï¼š" + +#: src/xz/hardware.c +msgid "Number of processor threads:" +msgstr "處ç†å™¨åŸ·è¡Œç·’的數é‡ï¼š" + +#: src/xz/hardware.c +msgid "Compression:" +msgstr "壓縮:" + +#: src/xz/hardware.c +msgid "Decompression:" +msgstr "解壓縮:" + +#: src/xz/hardware.c +msgid "Multi-threaded decompression:" +msgstr "多執行緒解壓縮:" + +#: src/xz/hardware.c +msgid "Default for -T0:" +msgstr "-T0 çš„é è¨­å€¼ï¼š" + +#: src/xz/hardware.c +msgid "Hardware information:" +msgstr "硬體資訊:" + +#: src/xz/hardware.c +msgid "Memory usage limits:" +msgstr "記憶體用é‡ä¸Šé™ï¼š" + +#: src/xz/list.c +msgid "Streams:" +msgstr "串æµï¼š" + +#: src/xz/list.c +msgid "Blocks:" +msgstr "å€å¡Šï¼š" + +#: src/xz/list.c +msgid "Compressed size:" +msgstr "壓縮後大å°ï¼š" + +#: src/xz/list.c +msgid "Uncompressed size:" +msgstr "壓縮å‰å¤§å°ï¼š" + +#: src/xz/list.c +msgid "Ratio:" +msgstr "壓縮比:" + +#: src/xz/list.c +msgid "Check:" +msgstr "檢查:" + +#: src/xz/list.c +msgid "Stream Padding:" +msgstr "串æµå¡«å……:" + +#: src/xz/list.c +msgid "Memory needed:" +msgstr "所需記憶體:" + +#: src/xz/list.c +msgid "Sizes in headers:" +msgstr "檔頭中標示大å°ï¼š" + +#: src/xz/list.c +msgid "Number of files:" +msgstr "檔案數:" + +#: src/xz/list.c +msgid "Stream" +msgstr "串æµ" + +#: src/xz/list.c +msgid "Block" +msgstr "å€å¡Š" + +#: src/xz/list.c +msgid "Blocks" +msgstr "å€å¡Š" + +#: src/xz/list.c +msgid "CompOffset" +msgstr "壓縮åç§»" + +#: src/xz/list.c +msgid "UncompOffset" +msgstr "未壓縮åç§»" + +#: src/xz/list.c +msgid "CompSize" +msgstr "壓縮大å°" + +#: src/xz/list.c +msgid "UncompSize" +msgstr "未壓縮大å°" + +#: src/xz/list.c +msgid "TotalSize" +msgstr "總計大å°" + +#: src/xz/list.c +msgid "Ratio" +msgstr "比率" + +#: src/xz/list.c +msgid "Check" +msgstr "檢查" + +#: src/xz/list.c +msgid "CheckVal" +msgstr "檢查值" + +#: src/xz/list.c +msgid "Padding" +msgstr "補空" + +#: src/xz/list.c +msgid "Header" +msgstr "檔頭" + +#: src/xz/list.c +msgid "Flags" +msgstr "旗標" + +#: src/xz/list.c +msgid "MemUsage" +msgstr "Mem用é‡" + +#: src/xz/list.c +msgid "Filters" +msgstr "éŽæ¿¾å™¨" + +#. TRANSLATORS: Indicates that there is no integrity check. +#. This string is used in tables. In older xz version this +#. string was limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "None" +msgstr "ç„¡" + +#. TRANSLATORS: Indicates that integrity check name is not known, +#. but the Check ID is known (here 2). In older xz version these +#. strings were limited to ten columns in a fixed-width font, but +#. nowadays there is no strict length restriction anymore. +#: src/xz/list.c +msgid "Unknown-2" +msgstr "未知-2" + +#: src/xz/list.c +msgid "Unknown-3" +msgstr "未知-3" + +#: src/xz/list.c +msgid "Unknown-5" +msgstr "未知-5" + +#: src/xz/list.c +msgid "Unknown-6" +msgstr "未知-6" + +#: src/xz/list.c +msgid "Unknown-7" +msgstr "未知-7" + +#: src/xz/list.c +msgid "Unknown-8" +msgstr "未知-8" + +#: src/xz/list.c +msgid "Unknown-9" +msgstr "未知-9" + +#: src/xz/list.c +msgid "Unknown-11" +msgstr "未知-11" + +#: src/xz/list.c +msgid "Unknown-12" +msgstr "未知-12" + +#: src/xz/list.c +msgid "Unknown-13" +msgstr "未知-13" + +#: src/xz/list.c +msgid "Unknown-14" +msgstr "未知-14" + +#: src/xz/list.c +msgid "Unknown-15" +msgstr "未知-15" + +#: src/xz/list.c +#, c-format +msgid "%s: File is empty" +msgstr "%s:檔案是空的" + +#: src/xz/list.c +#, c-format +msgid "%s: Too small to be a valid .xz file" +msgstr "%s:因éŽå°è€Œä¸èªç‚ºæ˜¯å€‹æœ‰æ•ˆ .xz 檔" + +#. TRANSLATORS: These are column headings. From Strms (Streams) +#. to Ratio, the columns are right aligned. Check and Filename +#. are left aligned. If you need longer words, it's OK to +#. use two lines here. Test with "xz -l foo.xz". +#: src/xz/list.c +msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename" +msgstr " ä¸²æµ å€å¡Š 已壓縮 未壓縮 比例 檢驗碼 檔å" + +#: src/xz/list.c +msgid "Yes" +msgstr "是" + +#: src/xz/list.c +msgid "No" +msgstr "å¦" + +#: src/xz/list.c +msgid "Minimum XZ Utils version:" +msgstr "æœ€å° XZ 工具程å¼ç‰ˆæœ¬ï¼š" + +#. TRANSLATORS: %s is an integer. Only the plural form of this +#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". +#: src/xz/list.c +#, c-format +msgid "%s file\n" +msgid_plural "%s files\n" +msgstr[0] "%s 個檔案\n" + +#: src/xz/list.c +msgid "Totals:" +msgstr "總計:" + +#: src/xz/list.c +msgid "--list works only on .xz files (--format=xz or --format=auto)" +msgstr "--list åªèƒ½åœ¨ .xz 檔使用(--format=xz 或 --format=auto)" + +#: src/xz/list.c +msgid "Try 'lzmainfo' with .lzma files." +msgstr "試試看用「lzmainfoã€è™•ç† .lzma 檔案。" + +#: src/xz/list.c +msgid "--list does not support reading from standard input" +msgstr "--list 䏿”¯æ´å¾žæ¨™æº–輸入讀å–" + +#: src/xz/main.c +#, c-format +msgid "%s: Error reading filenames: %s" +msgstr "%sï¼šè®€å–æª”åæ™‚發生錯誤:%s" + +#: src/xz/main.c +#, c-format +msgid "%s: Unexpected end of input when reading filenames" +msgstr "%sï¼šè®€å–æª”åæ™‚é‡åˆ°éžé æœŸçš„輸入çµå°¾" + +#: src/xz/main.c +#, c-format +msgid "%s: Null character found when reading filenames; maybe you meant to use '--files0' instead of '--files'?" +msgstr "%sï¼šè®€å–æª”åæ™‚發ç¾ç©ºå­—元;或許您想使用「--files0ã€è€Œéžã€Œ--filesã€ï¼Ÿ" + +#: src/xz/main.c +msgid "Compression and decompression with --robot are not supported yet." +msgstr "å°šæœªæ”¯æ´æ­é… --robot 壓縮和解壓縮。" + +#: src/xz/main.c +msgid "Cannot read data from standard input when reading filenames from standard input" +msgstr "å¾žæ¨™æº–è¼¸å…¥è®€å–æª”åæ™‚,無法從標準輸入讀å–資料" + +#. TRANSLATORS: This is the program name in the beginning +#. of the line in messages. Usually it becomes "xz: ". +#. This is a translatable string because French needs +#. a space before a colon. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s: " +msgstr "%s:" + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "Internal error (bug)" +msgstr "內部錯誤(臭蟲)" + +#: src/xz/message.c +msgid "Cannot establish signal handlers" +msgstr "無法確立信號處ç†å™¨" + +#: src/xz/message.c +msgid "No integrity check; not verifying file integrity" +msgstr "沒有完整性檢查;ä¸é©—證檔案完整性" + +#: src/xz/message.c +msgid "Unsupported type of integrity check; not verifying file integrity" +msgstr "未知完整性檢查類型;ä¸é©—證檔案完整性" + +#: src/xz/message.c +msgid "Memory usage limit reached" +msgstr "é”到記憶體用é‡ä¸Šé™" + +#: src/xz/message.c +msgid "File format not recognized" +msgstr "無法識別檔案格å¼" + +#: src/xz/message.c +msgid "Unsupported options" +msgstr "䏿”¯æ´çš„é¸é …" + +#: src/xz/message.c +msgid "Compressed data is corrupt" +msgstr "壓縮資料是æå£žçš„" + +#: src/xz/message.c +msgid "Unexpected end of input" +msgstr "é‡åˆ°éžé æœŸè¼¸å…¥çµå°¾" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limiter is disabled." +msgstr "éœ€è¦ %s MiB 的記憶體。已åœç”¨è¨˜æ†¶é«”é™åˆ¶å™¨ã€‚" + +#: src/xz/message.c +#, c-format +msgid "%s MiB of memory is required. The limit is %s." +msgstr "éœ€è¦ %s MiB 的記憶體。記憶體é™åˆ¶ç‚º %s。" + +#: src/xz/message.c +#, c-format +msgid "%s: Filter chain: %s\n" +msgstr "%sï¼šéŽæ¿¾éˆï¼š%s\n" + +#: src/xz/message.c +#, c-format +msgid "Try '%s --help' for more information." +msgstr "嘗試「%s --helpã€å–得更多資訊。" + +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Error printing the help text (error code %d)" +msgstr "輸出說明文字時發生錯誤(錯誤碼 %d)" + +#: src/xz/message.c +#, c-format +msgid "Usage: %s [OPTION]... [FILE]...\n" +msgstr "用法:%s [OPTION]... [FILE]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Compress or decompress FILEs in the .xz format." +msgstr "用 .xz æ ¼å¼å£“縮,或解壓縮 .xz æ ¼å¼ä¸­çš„ <檔案>。" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Mandatory arguments to long options are mandatory for short options too." +msgstr "é•·é¸é …的必填引數,å°çŸ­é¸é …也是必填。" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation mode:" +msgstr "æ“作模å¼ï¼š" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force compression" +msgstr "強制壓縮" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force decompression" +msgstr "強制解壓縮" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "test compressed file integrity" +msgstr "測試壓縮後檔案的完整性" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "list information about .xz files" +msgstr "列出更多 .xz 檔案的資訊" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Operation modifiers:" +msgstr "æ“作修飾元:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "keep (don't delete) input files" +msgstr "ä¿ç•™ï¼ˆä¸è¦åˆªé™¤ï¼‰è¼¸å…¥æª”案" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "force overwrite of output file and (de)compress links" +msgstr "強制覆蓋輸出檔案並壓縮/解壓縮連çµ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "write to standard output and don't delete input files" +msgstr "輸出到標準輸出,且ä¸åˆªé™¤è¼¸å…¥æª”案" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't synchronize the output file to the storage device before removing the input file" +msgstr "移除輸入檔案å‰ï¼Œä¸è¦å°‡è¼¸å‡ºæª”æ¡ˆåŒæ­¥è‡³å„²å­˜è£ç½®" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "decompress only the first stream, and silently ignore possible remaining input data" +msgstr "僅解壓縮第一個串æµï¼Œå†å®‰éœåœ°å¿½ç•¥å¯èƒ½å‰©é¤˜çš„輸入資料" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "do not create sparse files when decompressing" +msgstr "ä¸è¦åœ¨è§£å£“ç¸®æ™‚å»ºç«‹ç¨€ç–æª”案" + +#: src/xz/message.c +msgid ".SUF" +msgstr ".SUF" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use the suffix '.SUF' on compressed files" +msgstr "在壓縮後的檔案加入「.SUFã€å¾Œç¶´" + +#: src/xz/message.c +msgid "FILE" +msgstr "FILE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "read filenames to process from FILE; if FILE is omitted, filenames are read from the standard input; filenames must be terminated with the newline character" +msgstr "從 FILE 讀å–è¦è™•ç†çš„æª”案å稱,若未指定 FILE,\tå‰‡å¾žæ¨™æº–è¼¸å…¥è®€å–æª”案å稱。檔案å稱必須以æ›è¡Œå­—å…ƒçµå°¾" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "like --files but use the null character as terminator" +msgstr "類似 --files 但使用 null 字元作為終止字元" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Basic file format and compression options:" +msgstr "基本檔案格å¼èˆ‡å£“縮é¸é …:" + +#: src/xz/message.c +msgid "FORMAT" +msgstr "FORMAT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "file format to encode or decode; possible values are 'auto' (default), 'xz', 'lzma', 'lzip', and 'raw'" +msgstr "è¦ç·¨è§£ç¢¼çš„æª”案格å¼ï¼Œå¯ä»¥è¼¸å…¥çš„值有「autoã€ï¼ˆé è¨­å€¼ï¼‰ã€\t「xzã€ã€ã€Œlzmaã€ã€ã€Œlzipã€å’Œã€Œrawã€" + +#: src/xz/message.c +msgid "NAME" +msgstr "NAME" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "integrity check type: 'none' (use with caution), 'crc32', 'crc64' (default), or 'sha256'" +msgstr "完整性檢查類型:「noneã€ï¼ˆå°å¿ƒä½¿ç”¨ï¼‰ã€ã€Œcrc32ã€ã€\t「crc64ã€ï¼ˆé è¨­å€¼ï¼‰æˆ–「sha256ã€" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "don't verify the integrity check when decompressing" +msgstr "解壓縮時ä¸é€²è¡Œå®Œæ•´æ€§æª¢æŸ¥" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression preset; default is 6; take compressor *and* decompressor memory usage into account before using 7-9!" +msgstr "壓縮設定檔。é è¨­å€¼ç‚º 6,使用 7-9 壓縮等級å‰ï¼Œ\t請務必考é‡å£“縮與解壓縮的記憶體用é‡ï¼" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "try to improve compression ratio by using more CPU time; does not affect decompressor memory requirements" +msgstr "嘗試使用更多 CPU 時間來改善壓縮率\t(ä¸å½±éŸ¿è§£å£“縮器的記憶體需求)" + +#. TRANSLATORS: Short for NUMBER. A longer string is fine but +#. wider than 5 columns makes --long-help a few lines longer. +#: src/xz/message.c +msgid "NUM" +msgstr "NUM" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use at most NUM threads; the default is 0 which uses as many threads as there are processor cores" +msgstr "使用最多 NUM 個執行緒。é è¨­ç‚º 0,å³ä½¿ç”¨æ‰€æœ‰çš„處ç†å™¨æ ¸å¿ƒ" + +#: src/xz/message.c +msgid "SIZE" +msgstr "SIZE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after every SIZE bytes of input; use this to set the block size for threaded compression" +msgstr "æ¯è™•ç† SIZE ä½å…ƒçµ„的輸入資料後,就開始一個新的 .xz å€å¡Šã€‚\t使用這個設定多執行緒壓縮的å€å¡Šå¤§å°" + +#: src/xz/message.c +msgid "BLOCKS" +msgstr "BLOCKS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start a new .xz block after the given comma-separated intervals of uncompressed data; optionally, specify a filter chain number (0-9) followed by a ':' before the uncompressed data size" +msgstr "在指定的未壓縮資料間隔(以逗號分隔)後開始新的 .xz å€å¡Šï¼Œ\tå¯ä»¥é¸æ“‡åœ¨æœªå£“縮資料大å°å‰åŠ ä¸ŠéŽæ¿¾éˆç·¨è™Ÿï¼ˆ0-9)\t和冒號「:ã€" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "when compressing, if more than NUM milliseconds has passed since the previous flush and reading more input would block, all pending data is flushed out" +msgstr "å£“ç¸®æ™‚ï¼Œè‹¥è‡ªä¸Šæ¬¡æŽ’æ¸…å¾Œå·²è¶…éŽ NUM 毫秒,\tä¸”è®€å–æ›´å¤šè¼¸å…¥æœƒé€ æˆé˜»å¡žï¼Œå‰‡å°‡æ‰€æœ‰å¾…處ç†è³‡æ–™æŽ’清" + +#: src/xz/message.c +msgid "LIMIT" +msgstr "LIMIT" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, no-c-format +msgid "set memory usage limit for compression, decompression, threaded decompression, or all of these; LIMIT is in bytes, % of RAM, or 0 for defaults" +msgstr "設定壓縮ã€è§£å£“縮ã€å¤šåŸ·è¡Œç·’解壓縮或所有這些模å¼çš„記憶體\t上é™ã€‚\tLIMIT 的單ä½å¯ä»¥æ˜¯ä½å…ƒçµ„ã€\t記憶體佔用百分比,\t或 0 表示é è¨­å€¼" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "if compression settings exceed the memory usage limit, give an error instead of adjusting the settings downwards" +msgstr "如果壓縮設定超éŽè¨˜æ†¶é«”用é‡ä¸Šé™ï¼Œè«‹çµ¦å‡ºéŒ¯èª¤è€Œéžä¸‹èª¿è¨­å®š" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Custom filter chain for compression (an alternative to using presets):" +msgstr "è‡ªè¨‚å£“ç¸®éŽæ¿¾éˆï¼ˆè¨­å®šæª”以外的替代é¸é …):" + +#: src/xz/message.c +msgid "FILTERS" +msgstr "FILTERS" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set the filter chain using the liblzma filter string syntax; use --filters-help for more information" +msgstr "使用 liblzma éŽæ¿¾å™¨å­—ä¸²èªžæ³•è¨­å®šéŽæ¿¾éˆã€‚輸入 --filters-help å–得更多資訊" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "set additional filter chains using the liblzma filter string syntax to use with --block-list" +msgstr "使用 liblzma éŽæ¿¾å™¨å­—串語法設定é¡å¤–çš„éŽæ¿¾éˆï¼Œä»¥é…åˆ --block-list 使用" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display more information about the liblzma filter string syntax and exit" +msgstr "顯示有關 liblzma éŽæ¿¾å™¨å­—ä¸²èªžæ³•çš„æ›´å¤šè³‡è¨Šå¾ŒçµæŸ" + +#. TRANSLATORS: Short for OPTIONS. +#: src/xz/message.c +msgid "OPTS" +msgstr "OPTS" + +#. TRANSLATORS: Use semicolon (or its fullwidth form) +#. in "(valid values; default)" even if it is weird in +#. your language. There are non-translatable strings +#. that look like "(foo, bar, baz; foo)" which list +#. the supported values and the default value. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "LZMA1 or LZMA2; OPTS is a comma-separated list of zero or more of the following options (valid values; default):" +msgstr "LZMA1 或 LZMA2。OPTS 是個以逗號分隔的列表,內有 0 或多個下述é¸é …(有效值;é è¨­å€¼ï¼‰ï¼š" + +#. TRANSLATORS: Short for PRESET. A longer string is +#. fine but wider than 4 columns makes --long-help +#. one line longer. +#: src/xz/message.c +msgid "PRE" +msgstr "PRE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "reset options to a preset" +msgstr "å°‡é¸é …é‡è¨­ç‚ºè¨­å®šæª”的值" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "dictionary size" +msgstr "字典大å°" + +#. TRANSLATORS: The word "literal" in "literal context +#. bits" means how many "context bits" to use when +#. encoding literals. A literal is a single 8-bit +#. byte. It doesn't mean "literally" here. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +msgid "number of literal context bits" +msgstr "字元上下文ä½å…ƒæ•¸" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +msgid "number of literal position bits" +msgstr "å­—å…ƒä½ç½®ä½å…ƒæ•¸" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, fuzzy +msgid "number of position bits" +msgstr "ä½ç½®ä½å…ƒçš„æ•¸é‡" + +#: src/xz/message.c +msgid "MODE" +msgstr "MODE" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "compression mode" +msgstr "壓縮模å¼" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "nice length of a match" +msgstr "符åˆé …目的最佳長度" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "match finder" +msgstr "æ¯”å°æœå°‹å™¨" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "maximum search depth; 0=automatic (default)" +msgstr "最大æœå°‹æ·±åº¦ã€‚0 表示自動(é è¨­å€¼ï¼‰" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "x86 BCJ filter (32-bit and 64-bit)" +msgstr "x86 BCJ éŽæ¿¾å™¨ï¼ˆ32 或 64 ä½å…ƒï¼‰" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM BCJ filter" +msgstr "ARM BCJ éŽæ¿¾å™¨" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM-Thumb BCJ filter" +msgstr "ARM-Thumb BCJ éŽæ¿¾å™¨" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "ARM64 BCJ filter" +msgstr "ARM64 BCJ éŽæ¿¾å™¨" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "PowerPC BCJ filter (big endian only)" +msgstr "PowerPC BCJ éŽæ¿¾å™¨ï¼ˆåªé¢å‘大端åºï¼‰" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "IA-64 (Itanium) BCJ filter" +msgstr "IA-64 (Itanium) BCJ éŽæ¿¾å™¨" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "SPARC BCJ filter" +msgstr "SPARC BCJ éŽæ¿¾å™¨" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "RISC-V BCJ filter" +msgstr "RISC-V BCJ éŽæ¿¾å™¨" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Valid OPTS for all BCJ filters:" +msgstr "å°æ‰€æœ‰ BCJ éŽæ¿¾å™¨éƒ½æœ‰æ•ˆçš„ OPTS:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "start offset for conversions (default=0)" +msgstr "轉æ›çš„èµ·å§‹ä½ç§»ï¼ˆé è¨­å€¼=0)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Delta filter; valid OPTS (valid values; default):" +msgstr "å·®ç•°éŽæ¿¾å™¨ã€‚有效 OPTS(有效值;é è¨­å€¼ï¼‰ï¼š" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "distance between bytes being subtracted from each other" +msgstr "相減ä½å…ƒçµ„之間的è·é›¢" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "Other options:" +msgstr "å…¶ä»–é¸é …:" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "suppress warnings; specify twice to suppress errors too" +msgstr "éš±è—警告,指定兩次則一併隱è—錯誤" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "be verbose; specify twice for even more verbose" +msgstr "輸出得更詳細,指定兩次則會輸出得更詳細" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "make warnings not affect the exit status" +msgstr "å³ä½¿æœ‰è­¦å‘Šä¹Ÿä¸æ”¹è®ŠçµæŸç‹€æ…‹ç¢¼" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "use machine-parsable messages (useful for scripts)" +msgstr "輸出機器å¯ä»¥è§£æžçš„訊æ¯ï¼ˆé©åˆç”¨æ–¼æŒ‡ä»¤ç¨¿ï¼‰" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the total amount of RAM and the currently active memory usage limits, and exit" +msgstr "顯示記憶體總é‡å’Œç›®å‰ç”Ÿæ•ˆçš„記憶體用é‡é™åˆ¶å¾ŒçµæŸ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the short help (lists only the basic options)" +msgstr "顯示比較短的說明文字(åªåˆ—出基本é¸é …)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this long help and exit" +msgstr "é¡¯ç¤ºè¼ƒé•·çš„èªªæ˜Žæ–‡å­—å¾ŒçµæŸ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display this short help and exit" +msgstr "é¡¯ç¤ºè¼ƒçŸ­çš„èªªæ˜Žæ–‡å­—å¾ŒçµæŸ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the long help (lists also the advanced options)" +msgstr "顯示比較長的說明文字(一併列出進階é¸é …)" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "display the version number and exit" +msgstr "é¡¯ç¤ºç‰ˆæœ¬è™Ÿç¢¼å¾ŒçµæŸ" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +msgid "With no FILE, or when FILE is -, read standard input." +msgstr "如果 FILE 沒有指定或指定為 -,則從標準輸入讀å–。" + +#. TRANSLATORS: This message indicates the bug reporting +#. address for this package. Please add another line saying +#. "\nReport translation bugs to <...>." with the email or WWW +#. address for translation bugs. Thanks! +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "Report bugs to <%s> (in English or Finnish)." +msgstr "請回報臭蟲至 <%s>(使用英文或芬蘭語)。" + +#. TRANSLATORS: The first %s is the name of this software. +#. The second <%s> is an URL. +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c src/lzmainfo/lzmainfo.c +#, c-format +msgid "%s home page: <%s>" +msgstr "%s 首é ï¼š<%s>" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE." +msgstr "æ­¤ç‚ºé–‹ç™¼ç‰ˆæœ¬ï¼Œä¸æ‰“算在生產環境使用。" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +#, c-format +msgid "Filter chains are set using the --filters=FILTERS or --filters1=FILTERS ... --filters9=FILTERS options. Each filter in the chain can be separated by spaces or '--'. Alternatively a preset %s can be specified instead of a filter chain." +msgstr "éŽæ¿¾éˆå¯é€éŽ --filters=FILTERS 或 --filters1=FILTERS ... --filters9=FILTERS é¸é …來設定。éˆä¸­çš„æ¯å€‹éŽæ¿¾å™¨å¯ä»¥ç”¨ç©ºæ ¼æˆ– '--' 分隔。您也å¯ä»¥æŒ‡å®š %s 設定檔來å–ä»£éŽæ¿¾éˆã€‚" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/xz/message.c +msgid "The supported filters and their options are:" +msgstr "支æ´çš„éŽæ¿¾å™¨å’Œé¸é …為:" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Options must be 'name=value' pairs separated with commas" +msgstr "é¸é …必須是以逗號分隔的「name=valueã€å€¼å°" + +#: src/xz/options.c +#, c-format +msgid "%s: Invalid option name" +msgstr "%s:é¸é …å稱無效" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "Invalid option value" +msgstr "é¸é …值無效" + +#: src/xz/options.c +#, c-format +msgid "Unsupported LZMA1/LZMA2 preset: %s" +msgstr "䏿”¯æ´çš„ LZMA1/LZMA2 設定檔:%s" + +#: src/xz/options.c src/liblzma/common/string_conversion.c +msgid "The sum of lc and lp must not exceed 4" +msgstr "lc å’Œ lp 的總和ä¸èƒ½è¶…éŽ 4" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Filename has an unknown suffix, skipping" +msgstr "%sï¼šæª”åæœ‰æœªçŸ¥å¾Œç¶´ï¼Œè·³éŽ" + +#: src/xz/suffix.c +#, c-format +msgid "%s: File already has '%s' suffix, skipping" +msgstr "%s:檔案已有「%sã€å¾Œç¶´ï¼Œç•¥éŽ" + +#: src/xz/suffix.c +#, c-format +msgid "%s: Invalid filename suffix" +msgstr "%s:檔å後綴無效" + +#: src/xz/util.c src/liblzma/common/string_conversion.c +msgid "Value is not a non-negative decimal integer" +msgstr "æ•¸å€¼ä¸æ˜¯éžè² æ•¸å進使•´æ•¸" + +#: src/xz/util.c +#, c-format +msgid "%s: Invalid multiplier suffix" +msgstr "%s:乘數後綴無效" + +#: src/xz/util.c +msgid "Valid suffixes are 'KiB' (2^10), 'MiB' (2^20), and 'GiB' (2^30)." +msgstr "有效的後綴有「KiBã€(2^10)ã€ã€ŒMiBã€(2^20) åŠã€ŒGiBã€(2^30)。" + +#: src/xz/util.c +#, c-format +msgid "Value of the option '%s' must be in the range [%, %]" +msgstr "é¸é …「%sã€çš„æ•¸å€¼å¿…é ˆè½åœ¨ [%, %] 範åœå…§" + +#: src/xz/util.c +msgid "Compressed data cannot be read from a terminal" +msgstr "ä¸èƒ½å¾žçµ‚端機讀入已壓縮資料" + +#: src/xz/util.c +msgid "Compressed data cannot be written to a terminal" +msgstr "ä¸èƒ½å°‡å·²å£“縮資料寫入終端機" + +#: src/lzmainfo/lzmainfo.c +#, c-format +msgid "Usage: %s [--help] [--version] [FILE]...\n" +msgstr "用法:%s [--help] [--version] [FILE]...\n" + +#. This is word wrapped at spaces. The Unicode character U+00A0 works as a non-breaking space. Tab (\t) is interpreted as a zero-width space (the tab itself is not displayed); U+200B is NOT supported. Manual word wrapping with \n is supported but requires care. +#: src/lzmainfo/lzmainfo.c +msgid "Show information stored in the .lzma file header." +msgstr "顯示儲存在 .lzma 檔案標頭中的資訊。" + +#: src/lzmainfo/lzmainfo.c +msgid "File is too small to be a .lzma file" +msgstr "檔案éŽå°ï¼Œæ•…䏿˜¯ .lzma 檔案" + +#: src/lzmainfo/lzmainfo.c +msgid "Not a .lzma file" +msgstr "䏿˜¯ .lzma 檔案" + +#: src/common/tuklib_exit.c +msgid "Writing to standard output failed" +msgstr "寫入標準輸出失敗" + +#: src/common/tuklib_exit.c +msgid "Unknown error" +msgstr "未知錯誤" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported preset" +msgstr "䏿”¯æ´çš„設定檔" + +#: src/liblzma/common/string_conversion.c +msgid "Unsupported flag in the preset" +msgstr "設定檔中包å«ä¸æ”¯æ´çš„æ——標" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown option name" +msgstr "未知é¸é …å稱" + +#: src/liblzma/common/string_conversion.c +msgid "Option value cannot be empty" +msgstr "é¸é …值ä¸èƒ½ç©ºç™½" + +#: src/liblzma/common/string_conversion.c +msgid "Value out of range" +msgstr "數值超出範åœ" + +#: src/liblzma/common/string_conversion.c +msgid "This option does not support any multiplier suffixes" +msgstr "這個é¸é …䏿”¯æ´ä»»ä½•乘數後綴" + +#. TRANSLATORS: Don't translate the +#. suffixes "KiB", "MiB", or "GiB" +#. because a user can only specify +#. untranslated suffixes. +#: src/liblzma/common/string_conversion.c +msgid "Invalid multiplier suffix (KiB, MiB, or GiB)" +msgstr "乘數後綴無效(KiBã€MiB 或 GiB)" + +#: src/liblzma/common/string_conversion.c +msgid "Unknown filter name" +msgstr "æœªçŸ¥éŽæ¿¾å™¨å稱" + +#: src/liblzma/common/string_conversion.c +msgid "This filter cannot be used in the .xz format" +msgstr "é€™å€‹éŽæ¿¾å™¨ä¸èƒ½åœ¨ .xz æ ¼å¼ä¸­ä½¿ç”¨" + +#: src/liblzma/common/string_conversion.c +msgid "Memory allocation failed" +msgstr "分é…記憶體失敗" + +#: src/liblzma/common/string_conversion.c +msgid "Empty string is not allowed, try '6' if a default value is needed" +msgstr "ä¸å…許輸入空白字串,如需é è¨­å€¼è«‹è¼¸å…¥ã€Œ6ã€" + +#: src/liblzma/common/string_conversion.c +msgid "The maximum number of filters is four" +msgstr "éŽæ¿¾å™¨æœ€å¤šåªèƒ½æŒ‡å®š 4 個" + +#: src/liblzma/common/string_conversion.c +msgid "Filter name is missing" +msgstr "ç¼ºå°‘éŽæ¿¾å™¨å稱" + +#: src/liblzma/common/string_conversion.c +msgid "Invalid filter chain ('lzma2' missing at the end?)" +msgstr "ç„¡æ•ˆçš„éŽæ¿¾éˆï¼ˆçµå°¾ç¼ºå°‘「lzma2ã€ï¼Ÿï¼‰" diff --git a/cpp/third_party/xz-5.8.3/po4a/ar.po b/cpp/third_party/xz-5.8.3/po4a/ar.po new file mode 100644 index 000000000..7c1822245 --- /dev/null +++ b/cpp/third_party/xz-5.8.3/po4a/ar.po @@ -0,0 +1,3905 @@ +# SPDX-License-Identifier: 0BSD +# Arabic translation for xz-man. +# Copyright (C) The XZ Utils authors and contributors +# This file is published under the BSD Zero Clause License. +# +# Zayed Al-Saidi , 2026. +msgid "" +msgstr "" +"Project-Id-Version: xz-man-5.8.2-pre1\n" +"POT-Creation-Date: 2025-10-31 13:23+0200\n" +"PO-Revision-Date: 2026-02-04 11:05+0400\n" +"Last-Translator: Zayed Al-Saidi \n" +"Language-Team: Arabic <(nothing)>\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Bugs: Report translation errors to the Language-Team address.\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100 >= 3 && n%100<=10 ? 3 : n%100 >= 11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 23.08.5\n" + +#. type: TH +#: ../src/xz/xz.1 +#, no-wrap +msgid "XZ" +msgstr "XZ" + +#. type: TH +#: ../src/xz/xz.1 +#, no-wrap +msgid "2025-03-08" +msgstr "2025-03-08" + +#. type: TH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "Tukaani" +msgstr "توكاني" + +#. type: TH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "XZ Utils" +msgstr "أدوات XZ" + +#. type: SH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "NAME" +msgstr "الاسم" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "xz, unxz, xzcat, lzma, unlzma, lzcat - Compress or decompress .xz and .lzma files" +msgstr "xz, unxz, xzcat, lzma, unlzma, lzcat - ضغط أو ÙÙƒ ضغط Ù…Ù„ÙØ§Øª .xz Ùˆ .lzma" + +#. type: SH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "SYNOPSIS" +msgstr "موجز" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B [I] [I]" +msgstr "B [I<خيار...>] [I<ملÙ...>]" + +#. type: SH +#: ../src/xz/xz.1 +#, no-wrap +msgid "COMMAND ALIASES" +msgstr "أسماء مستعارة للأمر" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B ÙŠÙƒØ§ÙØ¦ B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B ÙŠÙƒØ§ÙØ¦ B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B ÙŠÙƒØ§ÙØ¦ B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B ÙŠÙƒØ§ÙØ¦ B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is equivalent to B." +msgstr "B ÙŠÙƒØ§ÙØ¦ B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When writing scripts that need to decompress files, it is recommended to always use the name B with appropriate arguments (B or B) instead of the names B and B." +msgstr "عند كتابة سكربتات تحتاج Ù„ÙÙƒ ضغط Ø§Ù„Ù…Ù„ÙØ§ØªØŒ ÙŠÙوصى دائماً باستخدام الاسم B مع المعطيات المناسبة (B أو B) بدلاً من الاسمين B Ùˆ B." + +#. type: SH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 ../src/lzmainfo/lzmainfo.1 +#: ../src/scripts/xzdiff.1 ../src/scripts/xzgrep.1 ../src/scripts/xzless.1 +#: ../src/scripts/xzmore.1 +#, no-wrap +msgid "DESCRIPTION" +msgstr "الوصÙ" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B is a general-purpose data compression tool with command line syntax similar to B(1) and B(1). The native file format is the B<.xz> format, but the legacy B<.lzma> format used by LZMA Utils and raw compressed streams with no container format headers are also supported. In addition, decompression of the B<.lz> format used by B is supported." +msgstr "B أداة ضغط بيانات عامة الأغراض مع صياغة سطر أوامر مشابهة لـ B(1) Ùˆ B(1). تنسيق المل٠الأصلي هو تنسيق B<.xz>ØŒ ولكن يدعم أيضاً تنسيق B<.lzma> الموروث المستخدم ÙÙŠ LZMA Utils والتدÙقات المضغوطة الخام بدون ترويسات تنسيق الحاوية. Ø¨Ø§Ù„Ø¥Ø¶Ø§ÙØ© إلى ذلك، يدعم ÙÙƒ ضغط تنسيق B<.lz> المستخدم بواسطة B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B compresses or decompresses each I according to the selected operation mode. If no I are given or I is B<->, B reads from standard input and writes the processed data to standard output. B will refuse (display an error and skip the I) to write compressed data to standard output if it is a terminal. Similarly, B will refuse to read compressed data from standard input if it is a terminal." +msgstr "يضغط B أو ÙŠÙÙƒ ضغط كل I<ملÙ> ÙˆÙقاً لوضع التشغيل المحدد. إذا لم ØªÙØ¹Ø·ÙŽ I<Ù…Ù„ÙØ§Øª> أو كان I<الملÙ> هو B<->ØŒ يقرأ B من الدخل القياسي ويكتب البيانات المعالجة إلى الخرج القياسي. ÙŠØ±ÙØ¶ B (يعرض خطأ ويتخطى I<الملÙ>) كتابة البيانات المضغوطة إلى الخرج القياسي إذا كان طرÙية. وبالمثل، ÙŠØ±ÙØ¶ B قراءة البيانات المضغوطة من الدخل القياسي إذا كان طرÙية." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Unless B<--stdout> is specified, I other than B<-> are written to a new file whose name is derived from the source I name:" +msgstr "ما لم يحدد الخيار B<--stdout>ØŒ تÙكتب I<Ø§Ù„Ù…Ù„ÙØ§Øª> بخلا٠B<-> ÙÙŠ مل٠جديد ÙŠÙØ´ØªÙ‚ اسمه من اسم I<ملÙ> المصدر:" + +#. type: IP +#: ../src/xz/xz.1 +#, no-wrap +msgid "\\(bu" +msgstr "\\(bu" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing, the suffix of the target file format (B<.xz> or B<.lzma>) is appended to the source filename to get the target filename." +msgstr "عند الضغط، ÙŠÙلحق ملحق تنسيق المل٠الهد٠(B<.xz> أو B<.lzma>) باسم مل٠المصدر للحصول على اسم المل٠الهدÙ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When decompressing, the B<.xz>, B<.lzma>, or B<.lz> suffix is removed from the filename to get the target filename. B also recognizes the suffixes B<.txz> and B<.tlz>, and replaces them with the B<.tar> suffix." +msgstr "عند ÙÙƒ الضغط، ÙŠÙØ²Ø§Ù„ الملحق B<.xz> أو B<.lzma> أو B<.lz> من اسم المل٠للحصول على اسم المل٠الهدÙ. يتعر٠B أيضاً على الملحقات B<.txz> Ùˆ B<.tlz>ØŒ ويستبدلها بالملحق B<.tar>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the target file already exists, an error is displayed and the I is skipped." +msgstr "إذا كان المل٠الهد٠موجوداً Ø¨Ø§Ù„ÙØ¹Ù„ØŒ ÙŠÙØ¹Ø±Ø¶ خطأ ويتخطى I<الملÙ>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Unless writing to standard output, B will display a warning and skip the I if any of the following applies:" +msgstr "ما لم يكتب إلى المخرج القياسي، يعرض B تحذيراً ويتخطى I<الملÙ> ÙÙŠ حال انطباق أي مما يلي:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I is not a regular file. Symbolic links are not followed, and thus they are not considered to be regular files." +msgstr "I<الملÙ> ليس Ù…Ù„ÙØ§Ù‹ عادياً. لا ØªÙØªØ¨Ø¹ الوصلات الرمزية، وبالتالي لا ØªÙØ¹ØªØ¨Ø± Ù…Ù„ÙØ§Øª عادية." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I has more than one hard link." +msgstr "I<الملÙ> له أكثر من وصلة صلبة واحدة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I has setuid, setgid, or sticky bit set." +msgstr "I<الملÙ> عÙينت له بتات setuid أو setgid أو sticky." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The operation mode is set to compress and the I already has a suffix of the target file format (B<.xz> or B<.txz> when compressing to the B<.xz> format, and B<.lzma> or B<.tlz> when compressing to the B<.lzma> format)." +msgstr "وضع التشغيل مضبوط على الضغط Ùˆ I<الملÙ> يمتلك Ø¨Ø§Ù„ÙØ¹Ù„ ملحقاً لتنسيق المل٠الهد٠(B<.xz> أو B<.txz> عند الضغط بتنسيق B<.xz>ØŒ Ùˆ B<.lzma> أو B<.tlz> عند الضغط بتنسيق B<.lzma>)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The operation mode is set to decompress and the I doesn't have a suffix of any of the supported file formats (B<.xz>, B<.txz>, B<.lzma>, B<.tlz>, or B<.lz>)." +msgstr "وضع التشغيل مضبوط على ÙÙƒ الضغط Ùˆ I<الملÙ> لا يمتلك ملحقاً لأي من تنسيقات Ø§Ù„Ù…Ù„ÙØ§Øª المدعومة (B<.xz> أو B<.txz> أو B<.lzma> أو B<.tlz> أو B<.lz>)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "After successfully compressing or decompressing the I, B copies the owner, group, permissions, access time, and modification time from the source I to the target file. If copying the group fails, the permissions are modified so that the target file doesn't become accessible to users who didn't have permission to access the source I. B doesn't support copying other metadata like access control lists or extended attributes yet." +msgstr "بعد ضغط I<الملÙ> أو ÙÙƒ ضغطه بنجاح، ينسخ B المالك والمجموعة والأذونات ووقت الوصول ووقت التعديل من I<ملÙ> المصدر إلى المل٠الهدÙ. إذا ÙØ´Ù„ نسخ المجموعة، ØªÙØ¹Ø¯Ù„ الأذونات حتى لا يصبح المل٠الهد٠متاحاً للمستخدمين الذين لم يمتلكوا إذناً للوصول إلى I<ملÙ> المصدر. لا يدعم B نسخ البيانات الوصÙية الأخرى مثل قوائم التحكم ÙÙŠ الوصول أو السمات الممتدة بعد." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Once the target file has been successfully closed, the source I is removed unless B<--keep> was specified. The source I is never removed if the output is written to standard output or if an error occurs." +msgstr "بمجرد إغلاق المل٠الهد٠بنجاح، ÙŠÙØ­Ø°Ù I<ملÙ> المصدر ما لم ÙŠÙØ­Ø¯Ø¯ الخيار B<--keep>. لا ÙŠÙØ­Ø°Ù I<ملÙ> المصدر أبداً إذا ÙƒÙØªØ¨ المخرج إلى المخرج القياسي أو عند حدوث خطأ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Sending B or B to the B process makes it print progress information to standard error. This has only limited use since when standard error is a terminal, using B<--verbose> will display an automatically updating progress indicator." +msgstr "إرسال B أو B إلى عملية B يجعلها تطبع معلومات التقدم إلى الخطأ القياسي. هذا له استخدام محدود لأنه عندما يكون الخطأ القياسي هو الطرÙية، ÙØ¥Ù† استخدام B<--verbose> يعرض مؤشر تقدم يحدث آلياً." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Memory usage" +msgstr "استخدام الذاكرة" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The memory usage of B varies from a few hundred kilobytes to several gigabytes depending on the compression settings. The settings used when compressing a file determine the memory requirements of the decompressor. Typically the decompressor needs 5\\ % to 20\\ % of the amount of memory that the compressor needed when creating the file. For example, decompressing a file created with B currently requires 65\\ MiB of memory. Still, it is possible to have B<.xz> files that require several gigabytes of memory to decompress." +msgstr "يختل٠استخدام الذاكرة لـ B من بضع مئات الكيلوبايتات إلى عدة جيجابايتات اعتماداً على إعدادات الضغط. تحدد الإعدادات المستخدمة عند ضغط المل٠متطلبات الذاكرة لبرنامج ÙÙƒ الضغط. عادةً يحتاج برنامج ÙÙƒ الضغط من 5% إلى 20% من كمية الذاكرة التي احتاج إليها الضاغط عند إنشاء الملÙ. على سبيل المثال، يتطلب ÙÙƒ ضغط مل٠أÙنشئ باستخدام B حالياً 65 ميجابايت من الذاكرة. ومع ذلك، من الممكن وجود Ù…Ù„ÙØ§Øª B<.xz> تتطلب عدة جيجابايتات من الذاكرة Ù„ÙÙƒ ضغطها." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Especially users of older systems may find the possibility of very large memory usage annoying. To prevent uncomfortable surprises, B has a built-in memory usage limiter, which is disabled by default. While some operating systems provide ways to limit the memory usage of processes, relying on it wasn't deemed to be flexible enough (for example, using B(1) to limit virtual memory tends to cripple B(2))." +msgstr "قد يجد مستخدمو الأنظمة القديمة خصوصاً احتمال استهلاك الذاكرة بشكل كبير جداً أمراً مزعجاً. لمنع Ø§Ù„Ù…ÙØ§Ø¬Ø¢Øª غير المريحة، يمتلك B محدد استهلاك ذاكرة مدمجاً، وهو معطل بشكل مبدئي. ÙÙŠ حين ØªÙˆÙØ± بعض أنظمة التشغيل طرقاً للحد من استهلاك الذاكرة للعمليات، لم ÙŠÙØ¹ØªØ¨Ø± الاعتماد عليها مرناً بما يكÙÙŠ (على سبيل المثال، استخدام B(1) للحد من الذاكرة Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© يؤدي إلى إضعا٠B(2))." + +#. TRANSLATORS: Don't translate the uppercase XZ_DEFAULTS. +#. It's a name of an environment variable. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The memory usage limiter can be enabled with the command line option B<--memlimit=>I. Often it is more convenient to enable the limiter by default by setting the environment variable B, for example, B. It is possible to set the limits separately for compression and decompression by using B<--memlimit-compress=>I and B<--memlimit-decompress=>I. Using these two options outside B is rarely useful because a single run of B cannot do both compression and decompression and B<--memlimit=>I (or B<-M> I) is shorter to type on the command line." +msgstr "يمكن ØªÙØ¹ÙŠÙ„ محدد استهلاك الذاكرة عبر خيار سطر الأوامر B<--memlimit=>I. غالباً ما يكون من الأنسب ØªÙØ¹ÙŠÙ„ المحدد بشكل مبدئي عن طريق ضبط متغير البيئة BØŒ مثلاً: B. يمكن ضبط الحدود بشكل Ù…Ù†ÙØµÙ„ للضغط ÙˆÙÙƒ الضغط باستخدام B<--memlimit-compress=>I Ùˆ B<--memlimit-decompress=>I. نادراً ما يكون استخدام هذين الخيارين خارج B Ù…Ùيداً لأن تشغيلاً واحداً لبرنامج B لا يمكنه القيام بالضغط ÙˆÙÙƒ الضغط معاً، كما أن الخيار B<--memlimit=>I (أو B<-M> I) أسهل ÙÙŠ الكتابة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the specified memory usage limit is exceeded when decompressing, B will display an error and decompressing the file will fail. If the limit is exceeded when compressing, B will try to scale the settings down so that the limit is no longer exceeded (except when using B<--format=raw> or B<--no-adjust>). This way the operation won't fail unless the limit is very small. The scaling of the settings is done in steps that don't match the compression level presets, for example, if the limit is only slightly less than the amount required for B, the settings will be scaled down only a little, not all the way down to B." +msgstr "إذا تم تجاوز حد استهلاك الذاكرة المحدد عند ÙÙƒ الضغط، يعرض B خطأ ÙˆÙŠÙØ´Ù„ ÙÙƒ ضغط الملÙ. إذا تم تجاوز الحد عند الضغط، يحاول B Ø®ÙØ¶ الإعدادات بحيث لا يتم تجاوز الحد (إلا عند استخدام B<--format=raw> أو B<--no-adjust>). بهذه الطريقة لن ØªÙØ´Ù„ العملية إلا إذا كان الحد صغيراً جداً. يتم Ø®ÙØ¶ الإعدادات بخطوات لا تطابق مستويات الضغط المعدة مسبقاً؛ Ùمثلاً إذا كان الحد أقل بقليل من الكمية المطلوبة للخيار BØŒ ØªÙØ®Ùض الإعدادات قليلاً Ùقط، وليس إلى مستوى B." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Concatenation and padding with .xz files" +msgstr "الدمج والحشو مع Ù…Ù„ÙØ§Øª .xz" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "It is possible to concatenate B<.xz> files as is. B will decompress such files as if they were a single B<.xz> file." +msgstr "من الممكن دمج Ù…Ù„ÙØ§Øª B<.xz> كما هي. سيÙÙƒ B ضغط هذه Ø§Ù„Ù…Ù„ÙØ§Øª كما لو كانت Ù…Ù„ÙØ§Ù‹ واحداً بصيغة B<.xz>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "It is possible to insert padding between the concatenated parts or after the last part. The padding must consist of null bytes and the size of the padding must be a multiple of four bytes. This can be useful, for example, if the B<.xz> file is stored on a medium that measures file sizes in 512-byte blocks." +msgstr "من الممكن إدراج حشو بين الأجزاء المدمجة أو بعد الجزء الأخير. يجب أن يتكون الحشو من بايتات ØµÙØ±ÙŠØ© ويجب أن يكون حجم الحشو Ù…Ø¶Ø§Ø¹ÙØ§Ù‹ لأربعة بايتات. يمكن أن يكون هذا Ù…Ùيداً، مثلاً، إذا كان مل٠B<.xz> مخزناً على وسيط يقيس أحجام Ø§Ù„Ù…Ù„ÙØ§Øª بكتل سعة 512 بايت." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Concatenation and padding are not allowed with B<.lzma> files or raw streams." +msgstr "الدمج والحشو غير مسموح بهما مع Ù…Ù„ÙØ§Øª B<.lzma> أو التدÙقات الخام." + +#. type: SH +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "OPTIONS" +msgstr "خيارات" + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Integer suffixes and special values" +msgstr "لواحق الأعداد والقيم الخاصة" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers. There must be no space between the integer and the suffix." +msgstr "ÙÙŠ معظم الأماكن التي ÙŠÙØªÙˆÙ‚ع Ùيها معامل عددي، ØªÙØ¯Ø¹Ù… لاحقة اختيارية للإشارة بسهولة إلى الأعداد الكبيرة. يجب ألا توجد Ù…Ø³Ø§ÙØ© بين العدد واللاحقة." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Multiply the integer by 1,024 (2^10). B, B, B, B, and B are accepted as synonyms for B." +msgstr "ضرب العدد ÙÙŠ 1,024 (2^10). تÙقبل B Ùˆ B Ùˆ B Ùˆ B Ùˆ B ÙƒÙ…Ø±Ø§Ø¯ÙØ§Øª لـ B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Multiply the integer by 1,048,576 (2^20). B, B, B, and B are accepted as synonyms for B." +msgstr "ضرب العدد ÙÙŠ 1,048,576 (2^20). تÙقبل B Ùˆ B Ùˆ B Ùˆ B ÙƒÙ…Ø±Ø§Ø¯ÙØ§Øª لـ B." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Multiply the integer by 1,073,741,824 (2^30). B, B, B, and B are accepted as synonyms for B." +msgstr "ضرب العدد ÙÙŠ 1,073,741,824 (2^30). تÙقبل B Ùˆ B Ùˆ B Ùˆ B ÙƒÙ…Ø±Ø§Ø¯ÙØ§Øª لـ B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The special value B can be used to indicate the maximum integer value supported by the option." +msgstr "يمكن استخدام القيمة الخاصة B للإشارة إلى أقصى قيمة عددية يدعمها الخيار." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Operation mode" +msgstr "وضع التشغيل" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If multiple operation mode options are given, the last one takes effect." +msgstr "إذا Ø£ÙØ¹Ø·ÙŠØª عدة خيارات لوضع التشغيل، ÙØ¥Ù† الأخير هو الذي يسري Ù…ÙØ¹ÙˆÙ„Ù‡." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-z>, B<--compress>" +msgstr "B<-z>, B<--compress>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress. This is the default operation mode when no operation mode option is specified and no other operation mode is implied from the command name (for example, B implies B<--decompress>)." +msgstr "يضغط. هذا هو وضع التشغيل الـ B<مبدئي> عند عدم تحديد خيار وضع تشغيل وعدم استنتاج وضع تشغيل آخر من اسم الأمر (على سبيل المثال، B يقتضي B<--decompress>)." + +#. The DESCRIPTION section already says this but it's good to repeat it +#. here because the default behavior is a bit dangerous and new users +#. in a hurry may skip reading the DESCRIPTION section. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "After successful compression, the source file is removed unless writing to standard output or B<--keep> was specified." +msgstr "بعد الضغط بنجاح، ÙŠÙØ­Ø°Ù مل٠المصدر ما لم ÙŠÙØ­Ø¯Ø¯ المخرج القياسي أو الخيار B<--keep>." + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-d>, B<--decompress>, B<--uncompress>" +msgstr "B<-d>, B<--decompress>, B<--uncompress>" + +#. The DESCRIPTION section already says this but it's good to repeat it +#. here because the default behavior is a bit dangerous and new users +#. in a hurry may skip reading the DESCRIPTION section. +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Decompress. After successful decompression, the source file is removed unless writing to standard output or B<--keep> was specified." +msgstr "ÙŠÙÙƒ الضغط. بعد ÙÙƒ الضغط بنجاح، يزال المل٠المصدر ما لم يكن الكتابة إلى الخرج القياسي أو خيار B<--keep> محدداً." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-t>, B<--test>" +msgstr "B<-t>, B<--test>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Test the integrity of compressed I. This option is equivalent to B<--decompress --stdout> except that the decompressed data is discarded instead of being written to standard output. No files are created or removed." +msgstr "يختبر سلامة I<Ø§Ù„Ù…Ù„ÙØ§Øª> المضغوطة. هذا الخيار ÙŠÙƒØ§ÙØ¦ B<--decompress --stdout> باستثناء أن البيانات المÙكوك ضغطها تÙهمَل بدلاً من كتابتها إلى الخرج القياسي. لا تÙنشأ ولا ØªÙØ²Ø§Ù„ أي Ù…Ù„ÙØ§Øª." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-l>, B<--list>" +msgstr "B<-l>, B<--list>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Print information about compressed I. No uncompressed output is produced, and no files are created or removed. In list mode, the program cannot read the compressed data from standard input or from other unseekable sources." +msgstr "يطبع معلومات حول I<Ø§Ù„Ù…Ù„ÙØ§Øª> المضغوطة. لا ÙŠÙنتج أي خرج Ù…Ùكوك ضغطه، ولا تÙنشأ ولا ØªÙØ²Ø§Ù„ أي Ù…Ù„ÙØ§Øª. ÙÙŠ وضع القائمة، لا يستطيع البرنامج قراءة البيانات المضغوطة من الدخل القياسي أو من المصادر الأخرى التي لا تدعم البحث (unseekable)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default listing shows basic information about I, one file per line. To get more detailed information, use also the B<--verbose> option. For even more information, use B<--verbose> twice, but note that this may be slow, because getting all the extra information requires many seeks. The width of verbose output exceeds 80 characters, so piping the output to, for example, B may be convenient if the terminal isn't wide enough." +msgstr "ØªÙØ¸Ù‡Ø± القائمة المبدئية معلومات أساسية حول I<Ø§Ù„Ù…Ù„ÙØ§Øª>ØŒ بمعدل مل٠واحد لكل سطر. للحصول على معلومات أكثر ØªÙØµÙŠÙ„اً، استخدم أيضاً الخيار B<--verbose>. لمزيد من المعلومات، استخدم B<--verbose> مرتين، لكن لاحظ أن هذا قد يكون بطيئاً لأن الحصول على كل المعلومات الإضاÙية يتطلب العديد من عمليات البحث. يتجاوز عرض المخرج Ø§Ù„ØªÙØµÙŠÙ„ÙŠ 80 Ø­Ø±ÙØ§Ù‹ØŒ لذا قد يكون من المناسب تمرير المخرج إلى B مثلاً إذا لم تكن الطرÙية عريضة بما يكÙÙŠ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The exact output may vary between B versions and different locales. For machine-readable output, B<--robot --list> should be used." +msgstr "قد يختل٠المخرج الدقيق بين إصدارات B والإعدادات المحلية Ø§Ù„Ù…Ø®ØªÙ„ÙØ©. للمخرج القابل للقراءة آلياً، يجب استخدام B<--robot --list>." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Operation modifiers" +msgstr "معدلات العمليات" + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-k>, B<--keep>" +msgstr "B<-k>, B<--keep>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Don't delete the input files." +msgstr "عدم Ø­Ø°Ù Ù…Ù„ÙØ§Øª المدخلات." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Since B 5.2.6, this option also makes B compress or decompress even if the input is a symbolic link to a regular file, has more than one hard link, or has the setuid, setgid, or sticky bit set. The setuid, setgid, and sticky bits are not copied to the target file. In earlier versions this was only done with B<--force>." +msgstr "منذ B 5.2.6ØŒ يجعل هذا الخيار B يضغط أو ÙŠÙÙƒ الضغط حتى لو كان المدخل وصلاً رمزياً لمل٠عادي، أو يمتلك أكثر من وصلة صلبة، أو عÙينت له بتات setuid أو setgid أو sticky. لا تÙنسخ بتات setuid Ùˆ setgid Ùˆ sticky إلى المل٠الهدÙ. ÙÙŠ الإصدارات الأقدم، كان هذا يتم Ùقط مع الخيار B<--force>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-f>, B<--force>" +msgstr "B<-f>, B<--force>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This option has several effects:" +msgstr "هذا الخيار له عدة تأثيرات:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the target file already exists, delete it before compressing or decompressing." +msgstr "إذا كان المل٠الهد٠موجوداً Ø¨Ø§Ù„ÙØ¹Ù„ØŒ ÙŠÙØ­Ø°Ù قبل الضغط أو ÙÙƒ الضغط." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress or decompress even if the input is a symbolic link to a regular file, has more than one hard link, or has the setuid, setgid, or sticky bit set. The setuid, setgid, and sticky bits are not copied to the target file." +msgstr "الضغط أو ÙÙƒ الضغط حتى لو كان المدخل وصلاً رمزياً لمل٠عادي، أو يمتلك أكثر من وصلة صلبة، أو عÙينت له بتات setuid أو setgid أو sticky. لا تÙنسخ بتات setuid Ùˆ setgid Ùˆ sticky إلى المل٠الهدÙ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When used with B<--decompress> B<--stdout> and B cannot recognize the type of the source file, copy the source file as is to standard output. This allows B B<--force> to be used like B(1) for files that have not been compressed with B. Note that in future, B might support new compressed file formats, which may make B decompress more types of files instead of copying them as is to standard output. B<--format=>I can be used to restrict B to decompress only a single file format." +msgstr "عند استخدامه مع B<--decompress> Ùˆ B<--stdout> وتعذر على B التعر٠على نوع مل٠المصدر، ينسخ مل٠المصدر كما هو إلى المخرج القياسي. هذا يسمح باستخدام B B<--force> مثل B(1) Ù„Ù„Ù…Ù„ÙØ§Øª التي لم ØªÙØ¶ØºØ· باستخدام B. لاحظ أنه مستقبلاً، قد يدعم B تنسيقات Ù…Ù„ÙØ§Øª مضغوطة جديدة، مما قد يجعل B ÙŠÙÙƒ ضغط أنواع أكثر من Ø§Ù„Ù…Ù„ÙØ§Øª بدلاً من نسخها كما هي إلى المخرج القياسي. يمكن استخدام B<--format=>I لقصر B على ÙÙƒ ضغط تنسيق مل٠واحد Ùقط." + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-c>, B<--stdout>, B<--to-stdout>" +msgstr "B<-c>, B<--stdout>, B<--to-stdout>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Write the compressed or decompressed data to standard output instead of a file. This implies B<--keep>." +msgstr "كتابة البيانات المضغوطة أو المÙكوكة إلى المخرج القياسي بدلاً من ملÙ. هذا يتضمن الخيار B<--keep>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--single-stream>" +msgstr "B<--single-stream>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Decompress only the first B<.xz> stream, and silently ignore possible remaining input data following the stream. Normally such trailing garbage makes B display an error." +msgstr "ÙÙƒ ضغط أول تدÙÙ‚ B<.xz> Ùقط، وتجاهل أي بيانات مدخلات متبقية محتملة تتبع التدÙÙ‚ بصمت. عادة ما تتسبب هذه البيانات الزائدة ÙÙŠ عرض خطأ من قبل B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B never decompresses more than one stream from B<.lzma> files or raw streams, but this option still makes B ignore the possible trailing data after the B<.lzma> file or raw stream." +msgstr "لا يقوم B أبداً بÙÙƒ ضغط أكثر من تدÙÙ‚ واحد من Ù…Ù„ÙØ§Øª B<.lzma> أو التدÙقات الخام، لكن هذا الخيار لا يزال يجعل B يتجاهل البيانات اللاحقة المحتملة بعد مل٠B<.lzma> أو التدÙÙ‚ الخام." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This option has no effect if the operation mode is not B<--decompress> or B<--test>." +msgstr "هذا الخيار ليس له تأثير إذا لم يكن وضع التشغيل هو B<--decompress> أو B<--test>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Since B 5.7.1alpha, B<--single-stream> implies B<--keep>." +msgstr "منذ B 5.7.1alphaØŒ يتضمن B<--single-stream> الخيار B<--keep>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--no-sparse>" +msgstr "B<--no-sparse>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Disable creation of sparse files. By default, if decompressing into a regular file, B tries to make the file sparse if the decompressed data contains long sequences of binary zeros. It also works when writing to standard output as long as standard output is connected to a regular file and certain additional conditions are met to make it safe. Creating sparse files may save disk space and speed up the decompression by reducing the amount of disk I/O." +msgstr "يعطل إنشاء Ø§Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…ØªÙØ±Ù‚Ø©. الـ B<مبدئي>ØŒ عند ÙÙƒ الضغط إلى مل٠عادي، يحاول B جعل Ø§Ù„Ù…Ù„Ù Ù…ØªÙØ±Ù‚اً إذا كانت البيانات المÙكوك ضغطها تحتوي على B<تسلسل>ات طويلة من Ø§Ù„Ø£ØµÙØ§Ø± الثنائية. يعمل هذا أيضاً عند الكتابة إلى الخرج القياسي طالما كان الخرج القياسي متصلاً بمل٠عادي ÙˆØ§Ø³ØªÙŠÙØ§Ø¡ شروط إضاÙية معينة لضمان الأمان. قد ÙŠÙˆÙØ± إنشاء Ø§Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…ØªÙØ±Ù‚Ø© مساحة القرص ويسرع ÙÙƒ الضغط بتقليل كمية عمليات الإدخال والإخراج للقرص." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-S> I<.suf>, B<--suffix=>I<.suf>" +msgstr "B<-S> I<.suf>, B<--suffix=>I<.suf>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing, use I<.suf> as the suffix for the target file instead of B<.xz> or B<.lzma>. If not writing to standard output and the source file already has the suffix I<.suf>, a warning is displayed and the file is skipped." +msgstr "عند الضغط، استخدم I<.suf> كملحق للمل٠الهد٠بدلاً من B<.xz> أو B<.lzma>. إذا لم تكن الكتابة إلى المخرج القياسي وكان مل٠المصدر يمتلك Ø¨Ø§Ù„ÙØ¹Ù„ الملحق I<.suf>ØŒ ÙŠÙØ¹Ø±Ø¶ تحذير ÙˆÙŠÙØªØ®Ø·Ù‰ الملÙ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When decompressing, recognize files with the suffix I<.suf> in addition to files with the B<.xz>, B<.txz>, B<.lzma>, B<.tlz>, or B<.lz> suffix. If the source file has the suffix I<.suf>, the suffix is removed to get the target filename." +msgstr "عند ÙÙƒ الضغط، تعر٠على Ø§Ù„Ù…Ù„ÙØ§Øª ذات الملحق I<.suf> Ø¨Ø§Ù„Ø¥Ø¶Ø§ÙØ© إلى Ø§Ù„Ù…Ù„ÙØ§Øª ذات الملحقات B<.xz> أو B<.txz> أو B<.lzma> أو B<.tlz> أو B<.lz>. إذا كان لمل٠المصدر الملحق I<.suf>ØŒ ÙŠÙØ²Ø§Ù„ الملحق للحصول على اسم المل٠الهدÙ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing or decompressing raw streams (B<--format=raw>), the suffix must always be specified unless writing to standard output, because there is no default suffix for raw streams." +msgstr "عند ضغط أو ÙÙƒ ضغط التدÙقات الخام (B<--format=raw>)ØŒ يجب دائماً تحديد الملحق ما لم تكن الكتابة إلى المخرج القياسي، لأنه لا يوجد ملحق مبدئي للتدÙقات الخام." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--files>[B<=>I]" +msgstr "B<--files>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Read the filenames to process from I; if I is omitted, filenames are read from standard input. Filenames must be terminated with the newline character. A dash (B<->) is taken as a regular filename; it doesn't mean standard input. If filenames are given also as command line arguments, they are processed before the filenames read from I." +msgstr "قراءة أسماء Ø§Ù„Ù…Ù„ÙØ§Øª المطلوب معالجتها من I<ملÙ>Ø› إذا Ø­ÙØ°Ù I<ملÙ>ØŒ تÙقرأ أسماء Ø§Ù„Ù…Ù„ÙØ§Øª من المدخل القياسي. يجب إنهاء أسماء Ø§Ù„Ù…Ù„ÙØ§Øª بحر٠سطر جديد. ØªÙØ¹Ø§Ù…Ù„ الشَرطة (B<->) كاسم مل٠عادي؛ ولا تعني المدخل القياسي. إذا Ø£ÙØ¹Ø·ÙŠØª أسماء Ù…Ù„ÙØ§Øª أيضاً كمعاملات لسطر الأوامر، ÙØ³ØªØªÙ… معالجتها قبل أسماء Ø§Ù„Ù…Ù„ÙØ§Øª المقروءة من I<ملÙ>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--files0>[B<=>I]" +msgstr "B<--files0>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is identical to B<--files>[B<=>I] except that each filename must be terminated with the null character." +msgstr "هذا مطابق للخيار B<--files>[B<=>I] باستثناء أنه يجب إنهاء كل اسم Ù…Ù„Ù Ø¨Ø§Ù„Ø­Ø±Ù Ø§Ù„ØµÙØ±ÙŠ (null)." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Basic file format and compression options" +msgstr "تنسيق المل٠الأساسي وخيارات الضغط" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-F> I, B<--format=>I" +msgstr "B<-F> I, B<--format=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the file I to compress or decompress:" +msgstr "حدد I<تنسيق> المل٠للضغط أو ÙÙƒ الضغط:" + +#. TRANSLATORS: Don't translate bold string B. +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is the default. When compressing, B is equivalent to B. When decompressing, the format of the input file is automatically detected. Note that raw streams (created with B<--format=raw>) cannot be auto-detected." +msgstr "هذا هو المبدئي. عند الضغط، يكون B Ù…ÙƒØ§ÙØ¦Ø§Ù‹ لـ B. عند ÙÙƒ الضغط، ÙŠÙكتش٠تنسيق مل٠المدخلات آلياً. لاحظ أن التدÙقات الخام (التي تم إنشاؤها باستخدام B<--format=raw>) لا يمكن اكتشاÙها آلياً." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress to the B<.xz> file format, or accept only B<.xz> files when decompressing." +msgstr "الضغط بتنسيق مل٠B<.xz>ØŒ أو قبول Ù…Ù„ÙØ§Øª B<.xz> Ùقط عند ÙÙƒ الضغط." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B, B" +msgstr "B, B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress to the legacy B<.lzma> file format, or accept only B<.lzma> files when decompressing. The alternative name B is provided for backwards compatibility with LZMA Utils." +msgstr "الضغط بتنسيق مل٠B<.lzma> القديم، أو قبول Ù…Ù„ÙØ§Øª B<.lzma> Ùقط عند ÙÙƒ الضغط. تم توÙير الاسم البديل B للتواÙÙ‚ مع الإصدارات السابقة من أدوات LZMA." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Accept only B<.lz> files when decompressing. Compression is not supported." +msgstr "قبول Ù…Ù„ÙØ§Øª B<.lz> Ùقط عند ÙÙƒ الضغط. الضغط غير مدعوم." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The B<.lz> format versions 0 and 1 are supported. Version 0 files were produced by B 1.3 and older. Such files aren't common but may be found from file archives as a few source packages were released in this format. People might have old personal files in this format too. Decompression support for the format version 0 was removed in B 1.18. B 1.4 and later create files in the format version 1." +msgstr "تنسيق B<.lz> الإصداران 0 Ùˆ 1 مدعومان. Ù…Ù„ÙØ§Øª الإصدار 0 Ø£Ùنتجت بواسطة B 1.3 وما قبله. هذه Ø§Ù„Ù…Ù„ÙØ§Øª ليست شائعة ولكن يمكن العثور عليها ÙÙŠ Ø£Ø±Ø´ÙŠÙØ§Øª Ø§Ù„Ù…Ù„ÙØ§Øª حيث Ø£ÙØµØ¯Ø±Øª بعض حزم المصدر بهذا التنسيق. قد يمتلك الأشخاص Ù…Ù„ÙØ§Øª شخصية قديمة بهذا التنسيق أيضاً. أزيل دعم ÙÙƒ الضغط لتنسيق الإصدار 0 ÙÙŠ B 1.18. يقوم B 1.4 والإصدارات الأحدث بإنشاء Ù…Ù„ÙØ§Øª بتنسيق الإصدار 1." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compress or uncompress a raw stream (no headers). This is meant for advanced users only. To decode raw streams, you need use B<--format=raw> and explicitly specify the filter chain, which normally would have been stored in the container headers." +msgstr "ضغط أو ÙÙƒ ضغط تدÙÙ‚ خام (بدون ترويسات). هذا مخصص للمستخدمين المتقدمين Ùقط. Ù„ÙÙƒ ترميز التدÙقات الخام، تحتاج لاستخدام B<--format=raw> وتحديد سلسلة المرشحات صراحة، والتي كان من Ø§Ù„Ù…ÙØªØ±Ø¶ تخزينها ÙÙŠ ترويسات الحاوية بشكل طبيعي." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-C> I, B<--check=>I" +msgstr "B<-C> I, B<--check=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the type of the integrity check. The check is calculated from the uncompressed data and stored in the B<.xz> file. This option has an effect only when compressing into the B<.xz> format; the B<.lzma> format doesn't support integrity checks. The integrity check (if any) is verified when the B<.xz> file is decompressed." +msgstr "حدد نوع ÙØ­Øµ السلامة. يتم حساب Ø§Ù„ÙØ­Øµ من البيانات غير المضغوطة ÙˆÙŠÙØ®Ø²Ù† ÙÙŠ مل٠B<.xz>. هذا الخيار له تأثير Ùقط عند الضغط بتنسيق B<.xz>Ø› تنسيق B<.lzma> لا يدعم ÙØ­ÙˆØµØ§Øª السلامة. يتم التحقق من ÙØ­Øµ السلامة (إن وجد) عند ÙÙƒ ضغط مل٠B<.xz>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Supported I types:" +msgstr "أنواع I<Ø§Ù„ÙØ­Øµ> المدعومة:" + +#. TRANSLATORS: Don't translate the bold strings B, B, +#. B, and B. The command line option --check accepts +#. only the untranslated strings. +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Don't calculate an integrity check at all. This is usually a bad idea. This can be useful when integrity of the data is verified by other means anyway." +msgstr "عدم حساب ÙØ­Øµ السلامة على الإطلاق. عادة ما تكون هذه Ùكرة سيئة. قد يكون هذا Ù…Ùيداً عندما يتم التحقق من سلامة البيانات بوسائل أخرى على أي حال." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Calculate CRC32 using the polynomial from IEEE-802.3 (Ethernet)." +msgstr "حساب CRC32 باستخدام الحدودية من IEEE-802.3 (إيثرنت)." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Calculate CRC64 using the polynomial from ECMA-182. This is the default, since it is slightly better than CRC32 at detecting damaged files and the speed difference is negligible." +msgstr "حساب CRC64 باستخدام الحدودية من ECMA-182. هذا هو المبدئي، لأنه Ø£ÙØ¶Ù„ قليلاً من CRC32 ÙÙŠ Ø§ÙƒØªØ´Ø§Ù Ø§Ù„Ù…Ù„ÙØ§Øª Ø§Ù„ØªØ§Ù„ÙØ© ÙˆÙØ§Ø±Ù‚ السرعة ضئيل." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Calculate SHA-256. This is somewhat slower than CRC32 and CRC64." +msgstr "حساب SHA-256. هذا أبطأ نوعاً ما من CRC32 Ùˆ CRC64." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Integrity of the B<.xz> headers is always verified with CRC32. It is not possible to change or disable it." +msgstr "يتم دائماً التحقق من سلامة ترويسات B<.xz> باستخدام CRC32. لا يمكن تغييره أو تعطيله." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--ignore-check>" +msgstr "B<--ignore-check>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Don't verify the integrity check of the compressed data when decompressing. The CRC32 values in the B<.xz> headers will still be verified normally." +msgstr "عدم التحقق من ÙØ­Øµ سلامة البيانات المضغوطة عند ÙÙƒ الضغط. سيستمر التحقق من قيم CRC32 ÙÙŠ ترويسات B<.xz> بشكل طبيعي." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B Possible reasons to use this option:" +msgstr "B<لا تستخدم هذا الخيار إلا إذا كنت تعر٠ما ØªÙØ¹Ù„Ù‡.> الأسباب المحتملة لاستخدام هذا الخيار:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Trying to recover data from a corrupt .xz file." +msgstr "محاولة استعادة البيانات من مل٠.xz تالÙ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Speeding up decompression. This matters mostly with SHA-256 or with files that have compressed extremely well. It's recommended to not use this option for this purpose unless the file integrity is verified externally in some other way." +msgstr "تسريع ÙÙƒ الضغط. يهم هذا غالباً مع SHA-256 أو مع Ø§Ù„Ù…Ù„ÙØ§Øª التي Ø¶ÙØºØ·Øª بشكل جيد للغاية. يوصى بعدم استخدام هذا الخيار لهذا الغرض إلا إذا تم التحقق من سلامة المل٠خارجياً بطريقة أخرى." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-0> ... B<-9>" +msgstr "B<-0> ... B<-9>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Select a compression preset level. The default is B<-6>. If multiple preset levels are specified, the last one takes effect. If a custom filter chain was already specified, setting a compression preset level clears the custom filter chain." +msgstr "اختر مستوى ضغط معداً مسبقاً. المستوى المبدئي هو B<-6>. إذا Ø­ÙØ¯Ø¯Øª عدة مستويات معدة مسبقاً، ÙØ¥Ù† الأخير هو الذي يسري Ù…ÙØ¹ÙˆÙ„Ù‡. إذا تم تحديد سلسلة مرشحات مخصصة Ø¨Ø§Ù„ÙØ¹Ù„ØŒ ÙØ¥Ù† اختيار مستوى ضغط معد مسبقاً يمسح سلسلة المرشحات المخصصة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The differences between the presets are more significant than with B(1) and B(1). The selected compression settings determine the memory requirements of the decompressor, thus using a too high preset level might make it painful to decompress the file on an old system with little RAM. Specifically, B like it often is with B(1) and B(1)." +msgstr "Ø§Ù„Ø§Ø®ØªÙ„Ø§ÙØ§Øª بين الإعدادات المسبقة أكثر وضوحاً مما هي عليه ÙÙŠ B(1) Ùˆ B(1). تحدد إعدادات الضغط المختارة متطلبات الذاكرة Ù„ÙÙƒ الضغط، لذا ÙØ¥Ù† استخدام مستوى Ù…Ø±ØªÙØ¹ جداً قد يجعل ÙÙƒ ضغط المل٠مؤلماً على نظام قديم بذاكرة وصول عشوائي قليلة. تحديداً، B<ليست Ùكرة جيدة استخدام -9 بشكل أعمى لكل شيء> كما هو الحال غالباً مع B(1) Ùˆ B(1)." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-0> ... B<-3>" +msgstr "B<-0> ... B<-3>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "These are somewhat fast presets. B<-0> is sometimes faster than B while compressing much better. The higher ones often have speed comparable to B(1) with comparable or better compression ratio, although the results depend a lot on the type of data being compressed." +msgstr "ØªÙØ¹Ø¯ هذه عمليات ضبط مسبق سريعة نوعاً ما. يكون المستوى B<-0> أحياناً أسرع من B مع توÙير ضغط Ø£ÙØ¶Ù„ بكثير. وغالباً ما تملك المستويات الأعلى سرعة ØªÙØ¶Ø§Ù‡ÙŠ B(1) مع نسبة ضغط مماثلة أو Ø£ÙØ¶Ù„ØŒ رغم أن النتائج تعتمد كثيراً على نوع البيانات الجاري ضغطها." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-4> ... B<-6>" +msgstr "B<-4> ... B<-6>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Good to very good compression while keeping decompressor memory usage reasonable even for old systems. B<-6> is the default, which is usually a good choice for distributing files that need to be decompressible even on systems with only 16\\ MiB RAM. (B<-5e> or B<-6e> may be worth considering too. See B<--extreme>.)" +msgstr "ضغط جيد إلى جيد جداً مع Ø§Ù„Ø­ÙØ§Ø¸ على استهلاك ذاكرة ÙÙƒ الضغط معقولاً حتى للأنظمة القديمة. B<-6> هو المبدئي، وهو عادة خيار جيد لتوزيع Ø§Ù„Ù…Ù„ÙØ§Øª التي يجب أن تكون قابلة Ù„ÙÙƒ الضغط حتى على أنظمة بذاكرة 16\\ ميجابايت Ùقط. (قد يكون من الجدير بالذكر التÙكير ÙÙŠ B<-5e> أو B<-6e> أيضاً. انظر B<--extreme>.)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-7 ... -9>" +msgstr "B<-7 ... -9>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "These are like B<-6> but with higher compressor and decompressor memory requirements. These are useful only when compressing files bigger than 8\\ MiB, 16\\ MiB, and 32\\ MiB, respectively." +msgstr "هذه تشبه B<-6> ولكن مع متطلبات ذاكرة أعلى للضغط ÙˆÙÙƒ الضغط. هذه Ù…Ùيدة Ùقط عند ضغط Ù…Ù„ÙØ§Øª أكبر من 8\\ ميجابايت، Ùˆ 16\\ ميجابايت، Ùˆ 32\\ ميجابايت على التوالي." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "On the same hardware, the decompression speed is approximately a constant number of bytes of compressed data per second. In other words, the better the compression, the faster the decompression will usually be. This also means that the amount of uncompressed output produced per second can vary a lot." +msgstr "على Ù†ÙØ³ العتاد، سرعة ÙÙƒ الضغط هي تقريباً عدد ثابت من بايتات البيانات المضغوطة ÙÙŠ الثانية. بمعنى آخر، كلما كان الضغط Ø£ÙØ¶Ù„ØŒ كان ÙÙƒ الضغط أسرع عادة. يعني هذا أيضاً أن كمية المخرج غير المضغوط المنتج ÙÙŠ الثانية يمكن أن تختل٠كثيراً." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The following table summarises the features of the presets:" +msgstr "يلخص الجدول التالي مميزات الإعدادات المسبقة:" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Preset" +msgstr "المستوى" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "DictSize" +msgstr "حجم القاموس" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "CompCPU" +msgstr "معالج الضغط" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "CompMem" +msgstr "ذاكرة الضغط" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "DecMem" +msgstr "ذاكرة ÙÙƒ الضغط" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-0" +msgstr "-0" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "256 KiB" +msgstr "256 كيلوبايت" + +#. type: TP +#: ../src/xz/xz.1 ../src/scripts/xzgrep.1 +#, no-wrap +msgid "0" +msgstr "0" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "3 MiB" +msgstr "3 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "1 MiB" +msgstr "1 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-1" +msgstr "-1" + +#. type: TP +#: ../src/xz/xz.1 ../src/scripts/xzgrep.1 +#, no-wrap +msgid "1" +msgstr "1" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "9 MiB" +msgstr "9 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "2 MiB" +msgstr "2 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-2" +msgstr "-2" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "2" +msgstr "2" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "17 MiB" +msgstr "17 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-3" +msgstr "-3" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "4 MiB" +msgstr "4 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "3" +msgstr "3" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "32 MiB" +msgstr "32 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "5 MiB" +msgstr "5 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-4" +msgstr "-4" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "4" +msgstr "4" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "48 MiB" +msgstr "48 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-5" +msgstr "-5" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "8 MiB" +msgstr "8 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "5" +msgstr "5" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "94 MiB" +msgstr "94 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-6" +msgstr "-6" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "6" +msgstr "6" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-7" +msgstr "-7" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "16 MiB" +msgstr "16 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "186 MiB" +msgstr "186 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-8" +msgstr "-8" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "370 MiB" +msgstr "370 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "33 MiB" +msgstr "33 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-9" +msgstr "-9" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "64 MiB" +msgstr "64 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "674 MiB" +msgstr "674 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "65 MiB" +msgstr "65 ميجابايت" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Column descriptions:" +msgstr "وص٠الأعمدة:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "DictSize is the LZMA2 dictionary size. It is waste of memory to use a dictionary bigger than the size of the uncompressed file. This is why it is good to avoid using the presets B<-7> ... B<-9> when there's no real need for them. At B<-6> and lower, the amount of memory wasted is usually low enough to not matter." +msgstr "DictSize هو حجم قاموس LZMA2. من هدر الذاكرة استخدام قاموس أكبر من حجم المل٠غير المضغوط. لهذا السبب من الجيد تجنب استخدام الإعدادات المسبقة B<-7> ... B<-9> عندما لا تكون هناك حاجة حقيقية لها. ÙÙŠ المستوى B<-6> وما دونه، تكون كمية الذاكرة المهدرة عادة Ù…Ù†Ø®ÙØ¶Ø© بما يكÙÙŠ بحيث لا تهم." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "CompCPU is a simplified representation of the LZMA2 settings that affect compression speed. The dictionary size affects speed too, so while CompCPU is the same for levels B<-6> ... B<-9>, higher levels still tend to be a little slower. To get even slower and thus possibly better compression, see B<--extreme>." +msgstr "CompCPU هو تمثيل مبسط لإعدادات LZMA2 التي تؤثر على سرعة الضغط. يؤثر حجم القاموس على السرعة أيضاً، لذا بينما CompCPU هو Ù†ÙØ³Ù‡ للمستويات B<-6> ... B<-9>ØŒ ÙØ¥Ù† المستويات الأعلى لا تزال تميل إلى أن تكون أبطأ قليلاً. للحصول على ضغط أبطأ وبالتالي ربما Ø£ÙØ¶Ù„ØŒ انظر B<--extreme>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "CompMem contains the compressor memory requirements in the single-threaded mode. It may vary slightly between B versions." +msgstr "CompMem يحتوي على متطلبات ذاكرة الضغط ÙÙŠ وضع الخيط الواحد. قد يختل٠قليلاً بين إصدارات B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "DecMem contains the decompressor memory requirements. That is, the compression settings determine the memory requirements of the decompressor. The exact decompressor memory usage is slightly more than the LZMA2 dictionary size, but the values in the table have been rounded up to the next full MiB." +msgstr "DecMem يحتوي على متطلبات ذاكرة ÙÙƒ الضغط. أي أن إعدادات الضغط تحدد متطلبات الذاكرة Ù„ÙÙƒ الضغط. استهلاك ذاكرة ÙÙƒ الضغط Ø§Ù„ÙØ¹Ù„ÙŠ هو أكثر بقليل من حجم قاموس LZMA2ØŒ ولكن تم تقريب القيم ÙÙŠ الجدول إلى أقرب ميجابايت كاملة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Memory requirements of the multi-threaded mode are significantly higher than that of the single-threaded mode. With the default value of B<--block-size>, each thread needs 3*3*DictSize plus CompMem or DecMem. For example, four threads with preset B<-6> needs 660\\(en670\\ MiB of memory." +msgstr "متطلبات الذاكرة لوضع الخيوط المتعددة أعلى بكثير من وضع الخيط الواحد. مع القيمة المبدئية لـ B<--block-size>ØŒ يحتاج كل خيط إلى 3*3*DictSize Ø¨Ø§Ù„Ø¥Ø¶Ø§ÙØ© إلى CompMem أو DecMem. على سبيل المثال، أربعة خيوط مع المستوى B<-6> تحتاج من 660 إلى 670 ميجابايت من الذاكرة." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-e>, B<--extreme>" +msgstr "B<-e>, B<--extreme>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Use a slower variant of the selected compression preset level (B<-0> ... B<-9>) to hopefully get a little bit better compression ratio, but with bad luck this can also make it worse. Decompressor memory usage is not affected, but compressor memory usage increases a little at preset levels B<-0> ... B<-3>." +msgstr "استخدم نوعاً أبطأ من مستوى الضغط المختار (B<-0> ... B<-9>) على أمل الحصول على نسبة ضغط Ø£ÙØ¶Ù„ قليلاً، ولكن مع سوء الحظ قد يجعل هذا الأمر أسوأ. لا يتأثر استهلاك ذاكرة ÙÙƒ الضغط، ولكن استهلاك ذاكرة الضغط يزداد قليلاً ÙÙŠ المستويات B<-0> ... B<-3>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Since there are two presets with dictionary sizes 4\\ MiB and 8\\ MiB, the presets B<-3e> and B<-5e> use slightly faster settings (lower CompCPU) than B<-4e> and B<-6e>, respectively. That way no two presets are identical." +msgstr "بما أن هناك مستويين بحجم قاموس 4 ميجابايت Ùˆ 8 ميجابايت، ÙØ¥Ù† المستويين B<-3e> Ùˆ B<-5e> يستخدمان إعدادات أسرع قليلاً (CompCPU أقل) من B<-4e> Ùˆ B<-6e> على التوالي. بهذه الطريقة لا توجد مستويات متطابقة." + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-0e" +msgstr "-0e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "8" +msgstr "8" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-1e" +msgstr "-1e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "13 MiB" +msgstr "13 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-2e" +msgstr "-2e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "25 MiB" +msgstr "25 ميجابايت" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-3e" +msgstr "-3e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "7" +msgstr "7" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-4e" +msgstr "-4e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-5e" +msgstr "-5e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-6e" +msgstr "-6e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-7e" +msgstr "-7e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-8e" +msgstr "-8e" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "-9e" +msgstr "-9e" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "For example, there are a total of four presets that use 8\\ MiB dictionary, whose order from the fastest to the slowest is B<-5>, B<-6>, B<-5e>, and B<-6e>." +msgstr "على سبيل المثال، هناك إجمالي أربعة إعدادات مسبقة تستخدم قاموساً بحجم 8 ميجابايت، وترتيبها من الأسرع إلى الأبطأ هو B<-5> Ùˆ B<-6> Ùˆ B<-5e> Ùˆ B<-6e>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--fast>" +msgstr "B<--fast>" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--best>" +msgstr "B<--best>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "These are somewhat misleading aliases for B<-0> and B<-9>, respectively. These are provided only for backwards compatibility with LZMA Utils. Avoid using these options." +msgstr "هذه أسماء بديلة مضللة نوعاً ما لـ B<-0> Ùˆ B<-9> على التوالي. تم توÙيرها Ùقط للتواÙÙ‚ مع الإصدارات السابقة من أدوات LZMA. تجنب استخدام هذه الخيارات." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--block-size=>I" +msgstr "B<--block-size=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing to the B<.xz> format, split the input data into blocks of I bytes. The blocks are compressed independently from each other, which helps with multi-threading and makes limited random-access decompression possible. This option is typically used to override the default block size in multi-threaded mode, but this option can be used in single-threaded mode too." +msgstr "عند الضغط بتنسيق B<.xz>ØŒ قم بتقسيم بيانات المدخلات إلى كتل بحجم I بايت. ØªÙØ¶ØºØ· الكتل بشكل مستقل عن بعضها البعض، مما يساعد ÙÙŠ تعدد الخيوط ويجعل ÙÙƒ الضغط العشوائي المحدود ممكناً. يستخدم هذا الخيار عادةً لتجاوز حجم الكتلة المبدئي ÙÙŠ وضع تعدد الخيوط، ولكن يمكن استخدامه ÙÙŠ وضع الخيط الواحد أيضاً." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In multi-threaded mode about three times I bytes will be allocated in each thread for buffering input and output. The default I is three times the LZMA2 dictionary size or 1 MiB, whichever is more. Typically a good value is 2\\(en4 times the size of the LZMA2 dictionary or at least 1 MiB. Using I less than the LZMA2 dictionary size is waste of RAM because then the LZMA2 dictionary buffer will never get fully used. In multi-threaded mode, the sizes of the blocks are stored in the block headers. This size information is required for multi-threaded decompression." +msgstr "ÙÙŠ وضع تعدد الخيوط، يتم تخصيص حوالي ثلاثة أضعا٠I بايت ÙÙŠ كل خيط لتخزين المدخلات والمخرجات مؤقتاً. الحجم I المبدئي هو ثلاثة أضعا٠حجم قاموس LZMA2 أو 1 ميجابايت، أيهما أكثر. عادة ما تكون القيمة الجيدة من 2 إلى 4 أضعا٠حجم قاموس LZMA2 أو على الأقل 1 ميجابايت. استخدام حجم I أقل من حجم قاموس LZMA2 هو هدر لذاكرة الوصول العشوائي لأن ذاكرة قاموس LZMA2 المؤقتة لن ØªÙØ³ØªØ®Ø¯Ù… بالكامل أبداً. ÙÙŠ وضع تعدد الخيوط، ØªÙØ®Ø²Ù† أحجام الكتل ÙÙŠ ترويسات الكتل. معلومات الحجم هذه مطلوبة Ù„ÙÙƒ الضغط المتعدد الخيوط." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In single-threaded mode no block splitting is done by default. Setting this option doesn't affect memory usage. No size information is stored in block headers, thus files created in single-threaded mode won't be identical to files created in multi-threaded mode. The lack of size information also means that B won't be able decompress the files in multi-threaded mode." +msgstr "ÙÙŠ وضع الخيط الواحد لا يتم تقسيم الكتل بشكل مبدئي. ضبط هذا الخيار لا يؤثر على استهلاك الذاكرة. لا ØªÙØ®Ø²Ù† معلومات الحجم ÙÙŠ ترويسات الكتل، وبالتالي ÙØ¥Ù† Ø§Ù„Ù…Ù„ÙØ§Øª المنشأة ÙÙŠ وضع الخيط الواحد لن تكون متطابقة مع Ø§Ù„Ù…Ù„ÙØ§Øª المنشأة ÙÙŠ وضع تعدد الخيوط. نقص معلومات الحجم يعني أيضاً أن B لن يتمكن من ÙÙƒ ضغط Ø§Ù„Ù…Ù„ÙØ§Øª ÙÙŠ وضع تعدد الخيوط." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--block-list=>I" +msgstr "B<--block-list=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing to the B<.xz> format, start a new block with an optional custom filter chain after the given intervals of uncompressed data." +msgstr "عند الضغط بتنسيق B<.xz>ØŒ ابدأ كتلة جديدة مع سلسلة مرشحات مخصصة اختيارية بعد Ùواصل زمنية معينة من البيانات غير المضغوطة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I are a comma-separated list. Each item consists of an optional filter chain number between 0 and 9 followed by a colon (B<:>) and a required size of uncompressed data. Omitting an item (two or more consecutive commas) is a shorthand to use the size and filters of the previous item." +msgstr "I<العناصر> هي قائمة Ù…ÙØµÙˆÙ„Ø© Ø¨ÙØ§ØµÙ„Ø©. يتكون كل عنصر من رقم سلسلة مرشحات اختياري بين 0 Ùˆ 9 تليها نقطتان (B<:>) وحجم مطلوب للبيانات غير المضغوطة. حذ٠عنصر (ÙØ§ØµÙ„تان متتاليتان أو أكثر) هو اختصار لاستخدام حجم ومرشحات العنصر السابق." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the input file is bigger than the sum of the sizes in I, the last item is repeated until the end of the file. A special value of B<0> may be used as the last size to indicate that the rest of the file should be encoded as a single block." +msgstr "إذا كان مل٠المدخلات أكبر من مجموع الأحجام ÙÙŠ I<العناصر>ØŒ ÙØ³ÙŠØªÙ… تكرار العنصر الأخير حتى نهاية الملÙ. يمكن استخدام القيمة الخاصة B<0> كآخر حجم للإشارة إلى وجوب ترميز بقية المل٠ككتلة واحدة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "An alternative filter chain for each block can be specified in combination with the B<--filters1=>I \\&...\\& B<--filters9=>I options. These options define filter chains with an identifier between 1\\(en9. Filter chain 0 can be used to refer to the default filter chain, which is the same as not specifying a filter chain. The filter chain identifier can be used before the uncompressed size, followed by a colon (B<:>). For example, if one specifies B<--block-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB> then blocks will be created using:" +msgstr "يمكن تحديد سلسلة مرشحات بديلة لكل كتلة بالاشتراك مع الخيارات B<--filters1=>I \\&...\\& B<--filters9=>I. تعر٠هذه الخيارات سلاسل المرشحات بمعر٠بين 1 Ùˆ 9. يمكن استخدام سلسلة المرشحات 0 للإشارة إلى سلسلة المرشحات المبدئية، وهو ما يماثل عدم تحديد سلسلة مرشحات. يمكن استخدام معر٠سلسلة المرشحات قبل الحجم غير المضغوط، متبوعاً بنقطتين (B<:>). على سبيل المثال، إذا حدد أحدهم B<--block-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB> ÙØ³ÙŠØªÙ… إنشاء الكتل باستخدام:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The filter chain specified by B<--filters1> and 2 MiB input" +msgstr "سلسلة المرشحات المحددة بواسطة B<--filters1> Ùˆ 2 ميجابايت من المدخلات" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The filter chain specified by B<--filters3> and 2 MiB input" +msgstr "سلسلة المرشحات المحددة بواسطة B<--filters3> Ùˆ 2 ميجابايت من المدخلات" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The filter chain specified by B<--filters2> and 4 MiB input" +msgstr "سلسلة المرشحات المحددة بواسطة B<--filters2> Ùˆ 4 ميجابايت من المدخلات" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default filter chain and 2 MiB input" +msgstr "سلسلة المرشحات المبدئية Ùˆ 2 ميجابايت من المدخلات" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default filter chain and 4 MiB input for every block until end of input." +msgstr "سلسلة المرشحات المبدئية Ùˆ 4 ميجابايت من المدخلات لكل كتلة حتى نهاية المدخلات." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If one specifies a size that exceeds the encoder's block size (either the default value in threaded mode or the value specified with B<--block-size=>I), the encoder will create additional blocks while keeping the boundaries specified in I. For example, if one specifies B<--block-size=10MiB> B<--block-list=5MiB,10MiB,8MiB,12MiB,24MiB> and the input file is 80 MiB, one will get 11 blocks: 5, 10, 8, 10, 2, 10, 10, 4, 10, 10, and 1 MiB." +msgstr "إذا حدد أحدهم حجماً يتجاوز حجم كتلة المرمّز (سواء القيمة المبدئية ÙÙŠ وضع تعدد الخيوط أو القيمة المحددة باستخدام B<--block-size=>I)ØŒ ÙØ³ÙŠÙ‚وم المرمّز بإنشاء كتل إضاÙية مع Ø§Ù„Ø­ÙØ§Ø¸ على الحدود المحددة ÙÙŠ I<العناصر>. على سبيل المثال، إذا حدد أحدهم B<--block-size=10MiB> Ùˆ B<--block-list=5MiB,10MiB,8MiB,12MiB,24MiB> وكان مل٠المدخلات 80 ميجابايت، ÙØ³ÙŠØ­ØµÙ„ على 11 كتلة: 5ØŒ 10ØŒ 8ØŒ 10ØŒ 2ØŒ 10ØŒ 10ØŒ 4ØŒ 10ØŒ 10ØŒ Ùˆ 1 ميجابايت." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In multi-threaded mode the sizes of the blocks are stored in the block headers. This isn't done in single-threaded mode, so the encoded output won't be identical to that of the multi-threaded mode." +msgstr "ÙÙŠ وضع تعدد الخيوط ØªÙØ®Ø²Ù† أحجام الكتل ÙÙŠ ترويسات الكتل. لا يتم ذلك ÙÙŠ وضع الخيط الواحد، لذا لن يكون المخرج المرمّز مطابقاً لمخرج وضع تعدد الخيوط." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--flush-timeout=>I" +msgstr "B<--flush-timeout=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing, if more than I milliseconds (a positive integer) has passed since the previous flush and reading more input would block, all the pending input data is flushed from the encoder and made available in the output stream. This can be useful if B is used to compress data that is streamed over a network. Small I values make the data available at the receiving end with a small delay, but large I values give better compression ratio." +msgstr "عند الضغط، إذا مر أكثر من I ميلي ثانية (عدد صحيح موجب) منذ Ø§Ù„ØªÙØ±ÙŠØº السابق وكان قراءة المزيد من المدخلات سيؤدي إلى Ø§Ù„ØªÙˆÙ‚ÙØŒ ÙØ³ÙŠØªÙ… ØªÙØ±ÙŠØº جميع بيانات المدخلات المعلقة من المرمّز وجعلها متاحة ÙÙŠ تدÙÙ‚ المخرجات. يمكن أن يكون هذا Ù…Ùيداً إذا استخدم B لضغط البيانات التي تتدÙÙ‚ عبر الشبكة. تجعل قيم I الصغيرة البيانات متاحة ÙÙŠ طر٠الاستلام بتأخير بسيط، لكن قيم I الكبيرة تعطي نسبة ضغط Ø£ÙØ¶Ù„." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This feature is disabled by default. If this option is specified more than once, the last one takes effect. The special I value of B<0> can be used to explicitly disable this feature." +msgstr "هذه الميزة معطلة بشكل مبدئي. إذا Ø­ÙØ¯Ø¯ هذا الخيار أكثر من مرة، ÙØ¥Ù† الأخير هو الذي يسري Ù…ÙØ¹ÙˆÙ„Ù‡. يمكن استخدام قيمة I الخاصة B<0> لتعطيل هذه الميزة صراحة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This feature is not available on non-POSIX systems." +msgstr "هذه الميزة غير Ù…ØªÙˆÙØ±Ø© ÙÙŠ الأنظمة غير المتواÙقة مع POSIX." + +#. FIXME +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B Currently B is unsuitable for decompressing the stream in real time due to how B does buffering." +msgstr "B<هذه الميزة لا تزال تجريبية.> حالياً يعد B غير مناسب Ù„ÙÙƒ ضغط التدÙÙ‚ ÙÙŠ الوقت Ø§Ù„ÙØ¹Ù„ÙŠ نظراً لكيÙية قيام B بالتخزين المؤقت." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--no-sync>" +msgstr "B<--no-sync>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Do not synchronize the target file and its directory to the storage device before removing the source file. This can improve performance if compressing or decompressing many small files. However, if the system crashes soon after the deletion, it is possible that the target file was not written to the storage device but the delete operation was. In that case neither the original source file nor the target file is available." +msgstr "عدم مزامنة المل٠الهد٠ودليله مع جهاز التخزين قبل حذ٠مل٠المصدر. يمكن لهذا أن يحسن الأداء عند ضغط أو ÙÙƒ ضغط العديد من Ø§Ù„Ù…Ù„ÙØ§Øª الصغيرة. ومع ذلك، إذا تعطل النظام بعد Ø§Ù„Ø­Ø°Ù Ø¨ÙØªØ±Ø© وجيزة، Ùمن المحتمل ألا يكون المل٠الهد٠قد ÙƒÙØªØ¨ على جهاز التخزين رغم تنÙيذ عملية الحذÙ. ÙÙŠ هذه الحالة، لن ÙŠØªÙˆÙØ± مل٠المصدر الأصلي ولا المل٠الهدÙ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This option has an effect only when B is going to remove the source file. In other cases synchronization is never done." +msgstr "هذا الخيار له تأثير Ùقط عندما يهم B بحذ٠مل٠المصدر. ÙÙŠ الحالات الأخرى لا تتم المزامنة أبداً." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The synchronization and B<--no-sync> were added in B 5.7.1alpha." +msgstr "Ø£Ø¶ÙŠÙØª المزامنة Ùˆ B<--no-sync> ÙÙŠ B 5.7.1alpha." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--memlimit-compress=>I" +msgstr "B<--memlimit-compress=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Set a memory usage limit for compression. If this option is specified multiple times, the last one takes effect." +msgstr "تعيين حد استهلاك الذاكرة للضغط. إذا Ø­ÙØ¯Ø¯ هذا الخيار عدة مرات، ÙØ¥Ù† الأخير هو الذي يسري Ù…ÙØ¹ÙˆÙ„Ù‡." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the compression settings exceed the I, B will attempt to adjust the settings downwards so that the limit is no longer exceeded and display a notice that automatic adjustment was done. The adjustments are done in this order: reducing the number of threads, switching to single-threaded mode if even one thread in multi-threaded mode exceeds the I, and finally reducing the LZMA2 dictionary size." +msgstr "إذا تجاوزت إعدادات الضغط I<الحد>ØŒ ÙØ³ÙŠØ­Ø§ÙˆÙ„ B ضبط الإعدادات نحو الأسÙÙ„ بحيث لا يتم تجاوز الحد وعرض إشعار بأنه تم إجراء ضبط آلي. يتم الضبط بهذا الترتيب: تقليل عدد الخيوط، والتحويل إلى وضع الخيط الواحد إذا كان خيط واحد ÙÙŠ وضع تعدد الخيوط يتجاوز I<الحد>ØŒ وأخيراً تقليل حجم قاموس LZMA2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When compressing with B<--format=raw> or if B<--no-adjust> has been specified, only the number of threads may be reduced since it can be done without affecting the compressed output." +msgstr "عند الضغط باستخدام B<--format=raw> أو إذا تم تحديد B<--no-adjust>ØŒ يمكن Ùقط تقليل عدد الخيوط لأنه يمكن القيام بذلك دون التأثير على المخرج المضغوط." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If the I cannot be met even with the adjustments described above, an error is displayed and B will exit with exit status 1." +msgstr "إذا تعذر الالتزام بـ I<الحد> حتى مع عمليات الضبط الموضحة أعلاه، ÙØ³ÙŠÙعرض خطأ ويخرج B بحالة الخروج 1." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I can be specified in multiple ways:" +msgstr "يمكن تحديد I<الحد> بعدة طرق:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I can be an absolute value in bytes. Using an integer suffix like B can be useful. Example: B<--memlimit-compress=80MiB>" +msgstr "يمكن أن يكون I<الحد> قيمة مطلقة بالبايت. استخدام لاحقة عددية مثل B قد يكون Ù…Ùيداً. مثال: B<--memlimit-compress=80MiB>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I can be specified as a percentage of total physical memory (RAM). This can be useful especially when setting the B environment variable in a shell initialization script that is shared between different computers. That way the limit is automatically bigger on systems with more memory. Example: B<--memlimit-compress=70%>" +msgstr "يمكن تحديد I<الحد> كنسبة مئوية من إجمالي الذاكرة الÙيزيائية (RAM). يمكن أن يكون هذا Ù…Ùيداً خاصة عند ضبط متغير البيئة B ÙÙŠ نص برمجي لبدء تشغيل Ø§Ù„ØµØ¯ÙØ© مشترك بين حواسيب Ù…Ø®ØªÙ„ÙØ©. بهذه الطريقة يكون الحد أكبر آلياً على الأنظمة ذات الذاكرة الأكبر. مثال: B<--memlimit-compress=70%>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The I can be reset back to its default value by setting it to B<0>. This is currently equivalent to setting the I to B (no memory usage limit)." +msgstr "يمكن إعادة I<الحد> إلى قيمته المبدئية بضبطه على B<0>. هذا يعادل حالياً ضبط I<الحد> على B (لا يوجد حد لاستهلاك الذاكرة)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "For 32-bit B there is a special case: if the I would be over B<4020\\ MiB>, the I is set to B<4020\\ MiB>. On MIPS32 B<2000\\ MiB> is used instead. (The values B<0> and B aren't affected by this. A similar feature doesn't exist for decompression.) This can be helpful when a 32-bit executable has access to 4\\ GiB address space (2 GiB on MIPS32) while hopefully doing no harm in other situations." +msgstr "بالنسبة لنسخة B ذات 32 بت، هناك حالة خاصة: إذا كان I<الحد> سيتجاوز B<4020\\ MiB>ØŒ ÙØ³ÙŠØªÙ… ضبط I<الحد> على B<4020\\ MiB>. ÙÙŠ MIPS32 يتم استخدام B<2000\\ MiB> بدلاً من ذلك. (القيم B<0> Ùˆ B لا تتأثر بهذا. لا توجد ميزة مماثلة Ù„ÙÙƒ الضغط). يمكن أن يكون هذا Ù…Ùيداً عندما يكون لمل٠تنÙيذي 32 بت إمكانية الوصول إلى مساحة عنوان 4 جيجابايت (2 جيجابايت ÙÙŠ MIPS32) مع الأمل ÙÙŠ عدم إلحاق ضرر ÙÙŠ الحالات الأخرى." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "See also the section B." +msgstr "انظر أيضاً قسم B<استهلاك الذاكرة>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--memlimit-decompress=>I" +msgstr "B<--memlimit-decompress=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Set a memory usage limit for decompression. This also affects the B<--list> mode. If the operation is not possible without exceeding the I, B will display an error and decompressing the file will fail. See B<--memlimit-compress=>I for possible ways to specify the I." +msgstr "تعيين حد استهلاك الذاكرة Ù„ÙÙƒ الضغط. يؤثر هذا أيضاً على وضع B<--list>. إذا كانت العملية غير ممكنة دون تجاوز I<الحد>ØŒ ÙØ³ÙŠÙ‚وم B بعرض خطأ ÙˆÙŠÙØ´Ù„ ÙÙƒ ضغط الملÙ. انظر B<--memlimit-compress=>I للتعر٠على الطرق الممكنة لتحديد I<الحد>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--memlimit-mt-decompress=>I" +msgstr "B<--memlimit-mt-decompress=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Set a memory usage limit for multi-threaded decompression. This can only affect the number of threads; this will never make B refuse to decompress a file. If I is too low to allow any multi-threading, the I is ignored and B will continue in single-threaded mode. Note that if also B<--memlimit-decompress> is used, it will always apply to both single-threaded and multi-threaded modes, and so the effective I for multi-threading will never be higher than the limit set with B<--memlimit-decompress>." +msgstr "تعيين حد استهلاك الذاكرة Ù„ÙÙƒ الضغط المتعدد الخيوط. يمكن أن يؤثر هذا Ùقط على عدد الخيوط؛ لن يجعل هذا B ÙŠØ±ÙØ¶ ÙÙƒ ضغط مل٠أبداً. إذا كان I<الحد> Ù…Ù†Ø®ÙØ¶Ø§Ù‹ جداً بحيث لا يسمح بتعدد الخيوط، ÙØ³ÙŠØªÙ… تجاهل I<الحد> وسيقوم B بالاستمرار ÙÙŠ وضع الخيط الواحد. لاحظ أنه ÙÙŠ حال استخدام B<--memlimit-decompress> أيضاً، ÙØ³ÙŠØªÙ… تطبيقه دائماً على وضعي الخيط الواحد وتعدد الخيوط، وبالتالي لن يكون I<الحد> Ø§Ù„ÙØ¹Ù„ÙŠ لتعدد الخيوط أعلى من الحد المحدد بواسطة B<--memlimit-decompress>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "In contrast to the other memory usage limit options, B<--memlimit-mt-decompress=>I has a system-specific default I. B can be used to see the current value." +msgstr "على عكس خيارات حدود استهلاك الذاكرة الأخرى، يمتلك B<--memlimit-mt-decompress=>I حداً مبدئياً خاصاً بالنظام. يمكن استخدام B لرؤية القيمة الحالية." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This option and its default value exist because without any limit the threaded decompressor could end up allocating an insane amount of memory with some input files. If the default I is too low on your system, feel free to increase the I but never set it to a value larger than the amount of usable RAM as with appropriate input files B will attempt to use that amount of memory even with a low number of threads. Running out of memory or swapping will not improve decompression performance." +msgstr "يوجد هذا الخيار وقيمته المبدئية لأنه بدون أي حد يمكن أن ينتهي الأمر ببرنامج ÙÙƒ الضغط المتعدد الخيوط بتخصيص كمية جنونية من الذاكرة مع بعض Ù…Ù„ÙØ§Øª المدخلات. إذا كان I<الحد> المبدئي Ù…Ù†Ø®ÙØ¶Ø§Ù‹ جداً على نظامك، Ùلا تتردد ÙÙŠ زيادة I<الحد> ولكن لا تضبطه أبداً على قيمة أكبر من كمية ذاكرة الوصول العشوائي القابلة للاستخدام، حيث سيحاول B مع Ù…Ù„ÙØ§Øª المدخلات المناسبة استخدام تلك الكمية من الذاكرة حتى مع وجود عدد قليل من الخيوط. Ù†ÙØ§Ø° الذاكرة أو استخدام مساحة التبادل لن يحسن أداء ÙÙƒ الضغط." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "See B<--memlimit-compress=>I for possible ways to specify the I. Setting I to B<0> resets the I to the default system-specific value." +msgstr "انظر B<--memlimit-compress=>I للتعر٠على الطرق الممكنة لتحديد I<الحد>. ضبط I<الحد> على B<0> يعيد I<الحد> إلى القيمة المبدئية الخاصة بالنظام." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-M> I, B<--memlimit=>I, B<--memory=>I" +msgstr "B<-M> I, B<--memlimit=>I, B<--memory=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "This is equivalent to specifying B<--memlimit-compress=>I B<--memlimit-decompress=>I B<--memlimit-mt-decompress=>I." +msgstr "هذا يعادل تحديد B<--memlimit-compress=>I Ùˆ B<--memlimit-decompress=>I Ùˆ B<--memlimit-mt-decompress=>I." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--no-adjust>" +msgstr "B<--no-adjust>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display an error and exit if the memory usage limit cannot be met without adjusting settings that affect the compressed output. That is, this prevents B from switching the encoder from multi-threaded mode to single-threaded mode and from reducing the LZMA2 dictionary size. Even when this option is used the number of threads may be reduced to meet the memory usage limit as that won't affect the compressed output." +msgstr "عرض خطأ والخروج إذا تعذر الالتزام بحد استهلاك الذاكرة دون ضبط الإعدادات التي تؤثر على المخرج المضغوط. أي أن هذا يمنع B من تحويل المرمّز من وضع تعدد الخيوط إلى وضع الخيط الواحد ومن تقليل حجم قاموس LZMA2. حتى عند استخدام هذا الخيار، قد يتم تقليل عدد الخيوط للالتزام بحد استهلاك الذاكرة لأن ذلك لن يؤثر على المخرج المضغوط." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Automatic adjusting is always disabled when creating raw streams (B<--format=raw>)." +msgstr "الضبط الآلي معطل دائماً عند إنشاء تدÙقات خام (B<--format=raw>)." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-T> I, B<--threads=>I" +msgstr "B<-T> I, B<--threads=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the number of worker threads to use. Setting I to a special value B<0> makes B use up to as many threads as the processor(s) on the system support. The actual number of threads can be fewer than I if the input file is not big enough for threading with the given settings or if using more threads would exceed the memory usage limit." +msgstr "حدد عدد خيوط العمل المراد استخدامها. ضبط I على القيمة الخاصة B<0> يجعل B يستخدم عدداً من الخيوط يصل إلى ما يدعمه المعالج (أو المعالجات) ÙÙŠ النظام. قد يكون عدد الخيوط Ø§Ù„ÙØ¹Ù„ÙŠ أقل من I إذا لم يكن مل٠المدخلات كبيراً بما يكÙÙŠ لتعدد الخيوط مع الإعدادات المعطاة أو إذا كان استخدام المزيد من الخيوط سيتجاوز حد استهلاك الذاكرة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The single-threaded and multi-threaded compressors produce different output. Single-threaded compressor will give the smallest file size but only the output from the multi-threaded compressor can be decompressed using multiple threads. Setting I to B<1> will use the single-threaded mode. Setting I to any other value, including B<0>, will use the multi-threaded compressor even if the system supports only one hardware thread. (B 5.2.x used single-threaded mode in this situation.)" +msgstr "ينتج ضاغط الخيط الواحد وضاغط تعدد الخيوط مخرجات Ù…Ø®ØªÙ„ÙØ©. سيعطي ضاغط الخيط الواحد أصغر حجم مل٠ولكن Ùقط مخرجات ضاغط تعدد الخيوط يمكن ÙÙƒ ضغطها باستخدام عدة خيوط. ضبط I على B<1> سيستخدم وضع الخيط الواحد. ضبط I على أي قيمة أخرى، بما ÙÙŠ ذلك B<0>ØŒ سيستخدم ضاغط تعدد الخيوط حتى لو كان النظام يدعم خيطاً عتادياً واحداً Ùقط. (كان B 5.2.x يستخدم وضع الخيط الواحد ÙÙŠ هذه الحالة)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "To use multi-threaded mode with only one thread, set I to B<+1>. The B<+> prefix has no effect with values other than B<1>. A memory usage limit can still make B switch to single-threaded mode unless B<--no-adjust> is used. Support for the B<+> prefix was added in B 5.4.0." +msgstr "لاستخدام وضع تعدد الخيوط مع خيط واحد Ùقط، اضبط I على B<+1>. السابقة B<+> ليس لها تأثير مع قيم أخرى غير B<1>. لا يزال بإمكان حد استهلاك الذاكرة أن يجعل B يتحول إلى وضع الخيط الواحد ما لم يتم استخدام B<--no-adjust>. Ø£ÙØ¶ÙŠÙ دعم السابقة B<+> ÙÙŠ B 5.4.0." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If an automatic number of threads has been requested and no memory usage limit has been specified, then a system-specific default soft limit will be used to possibly limit the number of threads. It is a soft limit in sense that it is ignored if the number of threads becomes one, thus a soft limit will never stop B from compressing or decompressing. This default soft limit will not make B switch from multi-threaded mode to single-threaded mode. The active limits can be seen with B." +msgstr "إذا تم طلب عدد آلي من الخيوط ولم يتم تحديد حد لاستهلاك الذاكرة، ÙØ³ÙŠØªÙ… استخدام حد مرن مبدئي خاص بالنظام لاحتمال تقليل عدد الخيوط. هو حد مرن بمعنى أنه يتم تجاهله إذا أصبح عدد الخيوط واحداً، وبالتالي ÙØ¥Ù† الحد المرن لن يمنع B أبداً من الضغط أو ÙÙƒ الضغط. هذا الحد المرن المبدئي لن يجعل B يتحول من وضع تعدد الخيوط إلى وضع الخيط الواحد. يمكن رؤية الحدود النشطة باستخدام B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Currently the only threading method is to split the input into blocks and compress them independently from each other. The default block size depends on the compression level and can be overridden with the B<--block-size=>I option." +msgstr "حالياً الطريقة الوحيدة لتعدد الخيوط هي تقسيم المدخلات إلى كتل وضغطها بشكل مستقل عن بعضها البعض. يعتمد حجم الكتلة المبدئي على مستوى الضغط ويمكن تجاوزه باستخدام الخيار B<--block-size=>I." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Threaded decompression only works on files that contain multiple blocks with size information in block headers. All large enough files compressed in multi-threaded mode meet this condition, but files compressed in single-threaded mode don't even if B<--block-size=>I has been used." +msgstr "يعمل ÙÙƒ الضغط المتعدد الخيوط Ùقط على Ø§Ù„Ù…Ù„ÙØ§Øª التي تحتوي على كتل متعددة مع معلومات الحجم ÙÙŠ ترويسات الكتل. جميع Ø§Ù„Ù…Ù„ÙØ§Øª الكبيرة بما يكÙÙŠ والمضغوطة ÙÙŠ وضع تعدد الخيوط تÙÙŠ بهذا الشرط، لكن Ø§Ù„Ù…Ù„ÙØ§Øª المضغوطة ÙÙŠ وضع الخيط الواحد لا تÙÙŠ به حتى لو تم استخدام B<--block-size=>I." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default value for I is B<0>. In B 5.4.x and older the default is B<1>." +msgstr "القيمة المبدئية لـ I هي B<0>. ÙÙŠ B 5.4.x والإصدارات الأقدم كانت القيمة المبدئية هي B<1>." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Custom compressor filter chains" +msgstr "سلاسل مرشحات ضاغط مخصصة" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "A custom filter chain allows specifying the compression settings in detail instead of relying on the settings associated to the presets. When a custom filter chain is specified, preset options (B<-0> \\&...\\& B<-9> and B<--extreme>) earlier on the command line are forgotten. If a preset option is specified after one or more custom filter chain options, the new preset takes effect and the custom filter chain options specified earlier are forgotten." +msgstr "تسمح سلسلة المرشحات المخصصة بتحديد إعدادات الضغط Ø¨Ø§Ù„ØªÙØµÙŠÙ„ بدلاً من الاعتماد على الإعدادات المرتبطة بالمستويات المعدة مسبقاً. عند تحديد سلسلة مرشحات مخصصة، يتم نسيان خيارات المستويات المسبقة (B<-0> \\&...\\& B<-9> Ùˆ B<--extreme>) المذكورة سابقاً ÙÙŠ سطر الأوامر. إذا تم تحديد خيار مستوى مسبق بعد واحد أو أكثر من خيارات سلسلة المرشحات المخصصة، ÙØ¥Ù† المستوى المسبق الجديد يسري Ù…ÙØ¹ÙˆÙ„Ù‡ ويتم نسيان خيارات سلسلة المرشحات المخصصة المحددة سابقاً." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "A filter chain is comparable to piping on the command line. When compressing, the uncompressed input goes to the first filter, whose output goes to the next filter (if any). The output of the last filter gets written to the compressed file. The maximum number of filters in the chain is four, but typically a filter chain has only one or two filters." +msgstr "سلسلة المرشحات تشبه الأنابيب (piping) ÙÙŠ سطر الأوامر. عند الضغط، تذهب المدخلات غير المضغوطة إلى المرشح الأول، والذي يذهب مخرجه إلى المرشح التالي (إن وجد). ÙŠÙكتب مخرج المرشح الأخير ÙÙŠ المل٠المضغوط. الحد الأقصى لعدد المرشحات ÙÙŠ السلسلة هو أربعة، ولكن عادةً ما تحتوي سلسلة المرشحات على مرشح واحد أو اثنين Ùقط." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Many filters have limitations on where they can be in the filter chain: some filters can work only as the last filter in the chain, some only as a non-last filter, and some work in any position in the chain. Depending on the filter, this limitation is either inherent to the filter design or exists to prevent security issues." +msgstr "تمتلك العديد من المرشحات قيوداً على مكان وجودها ÙÙŠ سلسلة المرشحات: بعض المرشحات يمكن أن تعمل Ùقط كآخر مرشح ÙÙŠ السلسلة، وبعضها Ùقط كمرشح غير أخير، وبعضها يعمل ÙÙŠ أي موضع ÙÙŠ السلسلة. اعتماداً على المرشح، يكون هذا القيد إما متأصلاً ÙÙŠ تصميم المرشح أو موجوداً لمنع المشكلات الأمنية." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "A custom filter chain can be specified in two different ways. The options B<--filters=>I and B<--filters1=>I \\&...\\& B<--filters9=>I allow specifying an entire filter chain in one option using the liblzma filter string syntax. Alternatively, a filter chain can be specified by using one or more individual filter options in the order they are wanted in the filter chain. That is, the order of the individual filter options is significant! When decoding raw streams (B<--format=raw>), the filter chain must be specified in the same order as it was specified when compressing. Any individual filter or preset options specified before the full chain option (B<--filters=>I) will be forgotten. Individual filters specified after the full chain option will reset the filter chain." +msgstr "يمكن تحديد سلسلة مرشحات مخصصة بطريقتين Ù…Ø®ØªÙ„ÙØªÙŠÙ†. تسمح الخيارات B<--filters=>I Ùˆ B<--filters1=>I \\&...\\& B<--filters9=>I بتحديد سلسلة مرشحات كاملة ÙÙŠ خيار واحد باستخدام صيغة نص مرشح liblzma. بدلاً من ذلك، يمكن تحديد سلسلة مرشحات باستخدام خيار مرشح ÙØ±Ø¯ÙŠ ÙˆØ§Ø­Ø¯ أو أكثر بالترتيب المطلوب ÙÙŠ سلسلة المرشحات. أي أن ترتيب خيارات المرشحات Ø§Ù„ÙØ±Ø¯ÙŠØ© مهم! عند ÙÙƒ ترميز التدÙقات الخام (B<--format=raw>)ØŒ يجب تحديد سلسلة المرشحات Ø¨Ù†ÙØ³ الترتيب الذي Ø­ÙØ¯Ø¯Øª به عند الضغط. سيتم نسيان أي مرشح ÙØ±Ø¯ÙŠ Ø£Ùˆ خيارات مستوى مسبق محددة قبل خيار السلسلة الكاملة (B<--filters=>I). المرشحات Ø§Ù„ÙØ±Ø¯ÙŠØ© المحددة بعد خيار السلسلة الكاملة ستعيد ضبط سلسلة المرشحات." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Both the full and individual filter options take filter-specific I as a comma-separated list. Extra commas in I are ignored. Every option has a default value, so specify those you want to change." +msgstr "تأخذ كل من خيارات المرشح الكاملة ÙˆØ§Ù„ÙØ±Ø¯ÙŠØ© I<خيارات> خاصة بالمرشح كقائمة Ù…ÙØµÙˆÙ„Ø© Ø¨ÙØ§ØµÙ„Ø©. الÙواصل الزائدة ÙÙŠ I<الخيارات> يتم تجاهلها. كل خيار له قيمة مبدئية، لذا حدد Ùقط تلك التي تريد تغييرها." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "To see the whole filter chain and I, use B (that is, use B<--verbose> twice). This works also for viewing the filter chain options used by presets." +msgstr "لرؤية سلسلة المرشحات بالكامل Ùˆ I<الخيارات>ØŒ استخدم B (أي استخدم B<--verbose> مرتين). يعمل هذا أيضاً لعرض خيارات سلسلة المرشحات المستخدمة بواسطة المستويات المسبقة." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--filters=>I" +msgstr "B<--filters=>I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the full filter chain or a preset in a single option. Each filter can be separated by spaces or two dashes (B<-->). I may need to be quoted on the shell command line so it is parsed as a single option. To denote I, use B<:> or B<=>. A preset can be prefixed with a B<-> and followed with zero or more flags. The only supported flag is B to apply the same options as B<--extreme>." +msgstr "حدد سلسلة المرشحات الكاملة أو مستوى مسبقاً ÙÙŠ خيار واحد. يمكن ÙØµÙ„ كل مرشح Ø¨Ù…Ø³Ø§ÙØ§Øª أو شرطتين (B<-->). قد تحتاج I<المرشحات> لوضعها بين علامتي اقتباس ÙÙŠ سطر أوامر Ø§Ù„ØµØ¯ÙØ© ليتم تحليلها كخيار واحد. للإشارة إلى I<الخيارات>ØŒ استخدم B<:> أو B<=>. يمكن أن يسبق المستوى المسبق B<-> ويتبعه ØµÙØ± أو أكثر من الأعلام. العلم الوحيد المدعوم هو B لتطبيق Ù†ÙØ³ خيارات B<--extreme>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--filters1>=I ... B<--filters9>=I" +msgstr "B<--filters1>=I ... B<--filters9>=I" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify up to nine additional filter chains that can be used with B<--block-list>." +msgstr "حدد ما يصل إلى تسع سلاسل مرشحات إضاÙية يمكن استخدامها مع B<--block-list>." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "For example, when compressing an archive with executable files followed by text files, the executable part could use a filter chain with a BCJ filter and the text part only the LZMA2 filter." +msgstr "على سبيل المثال، عند ضغط أرشي٠يحتوي على Ù…Ù„ÙØ§Øª تنÙيذية تليها Ù…Ù„ÙØ§Øª نصية، يمكن للجزء التنÙيذي استخدام سلسلة مرشحات مع مرشح BCJ والجزء النصي يستخدم مرشح LZMA2 Ùقط." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--filters-help>" +msgstr "B<--filters-help>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display a help message describing how to specify presets and custom filter chains in the B<--filters> and B<--filters1=>I \\&...\\& B<--filters9=>I options, and exit successfully." +msgstr "عرض رسالة مساعدة تص٠كيÙية تحديد المستويات المسبقة وسلاسل المرشحات المخصصة ÙÙŠ الخيارات B<--filters> Ùˆ B<--filters1=>I \\&...\\& B<--filters9=>IØŒ والخروج بنجاح." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--lzma1>[B<=>I]" +msgstr "B<--lzma1>[B<=>I]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--lzma2>[B<=>I]" +msgstr "B<--lzma2>[B<=>I]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Add LZMA1 or LZMA2 filter to the filter chain. These filters can be used only as the last filter in the chain." +msgstr "Ø¥Ø¶Ø§ÙØ© مرشح LZMA1 أو LZMA2 إلى سلسلة المرشحات. يمكن استخدام هذه المرشحات Ùقط كآخر مرشح ÙÙŠ السلسلة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "LZMA1 is a legacy filter, which is supported almost solely due to the legacy B<.lzma> file format, which supports only LZMA1. LZMA2 is an updated version of LZMA1 to fix some practical issues of LZMA1. The B<.xz> format uses LZMA2 and doesn't support LZMA1 at all. Compression speed and ratios of LZMA1 and LZMA2 are practically the same." +msgstr "LZMA1 هو مرشح قديم، ومدعوم تقريباً Ùقط بسبب تنسيق مل٠B<.lzma> القديم، الذي يدعم LZMA1 Ùقط. LZMA2 هو نسخة محدثة من LZMA1 لإصلاح بعض المشكلات العملية ÙÙŠ LZMA1. يستخدم تنسيق B<.xz> مرشح LZMA2 ولا يدعم LZMA1 على الإطلاق. سرعة ونسب ضغط LZMA1 Ùˆ LZMA2 متماثلة تقريباً." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "LZMA1 and LZMA2 share the same set of I:" +msgstr "يشترك LZMA1 Ùˆ LZMA2 ÙÙŠ Ù†ÙØ³ مجموعة I<الخيارات>:" + +#. TRANSLATORS: Don't translate bold strings like B, B, +#. B, B, B, or B because those are command line +#. options. On the other hand, do translate the italic strings like +#. I, I, and I, because such italic strings are +#. placeholders which a user replaces with an actual value. +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Reset all LZMA1 or LZMA2 I to I. I consist of an integer, which may be followed by single-letter preset modifiers. The integer can be from B<0> to B<9>, matching the command line options B<-0> \\&...\\& B<-9>. The only supported modifier is currently B, which matches B<--extreme>. If no B is specified, the default values of LZMA1 or LZMA2 I are taken from the preset B<6>." +msgstr "إعادة ضبط جميع I<خيارات> LZMA1 أو LZMA2 إلى I. يتكون I من عدد صحيح، قد يتبعه معدلات مستوى مسبق من حر٠واحد. يمكن أن يكون العدد الصحيح من B<0> إلى B<9>ØŒ بما يطابق خيارات سطر الأوامر B<-0> \\&...\\& B<-9>. المعدل الوحيد المدعوم حالياً هو BØŒ الذي يطابق B<--extreme>. إذا لم يتم تحديد BØŒ ÙØ³ÙŠØªÙ… أخذ القيم المبدئية لـ I<خيارات> LZMA1 أو LZMA2 من المستوى المسبق B<6>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Dictionary (history buffer) I indicates how many bytes of the recently processed uncompressed data is kept in memory. The algorithm tries to find repeating byte sequences (matches) in the uncompressed data, and replace them with references to the data currently in the dictionary. The bigger the dictionary, the higher is the chance to find a match. Thus, increasing dictionary I usually improves compression ratio, but a dictionary bigger than the uncompressed file is waste of memory." +msgstr "يشير I<حجم> القاموس (مخزن التاريخ المؤقت) إلى عدد بايتات البيانات غير المضغوطة التي تمت معالجتها مؤخراً والمحÙوظة ÙÙŠ الذاكرة. تحاول الخوارزمية العثور على تسلسلات بايت متكررة (تطابقات) ÙÙŠ البيانات غير المضغوطة، واستبدالها بمراجع للبيانات الموجودة حالياً ÙÙŠ القاموس. كلما كبر القاموس، زادت ÙØ±ØµØ© العثور على تطابق. وبالتالي، ÙØ¥Ù† زيادة I<حجم> القاموس يحسن عادةً نسبة الضغط، ولكن القاموس الأكبر من المل٠غير المضغوط هو هدر للذاكرة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Typical dictionary I is from 64\\ KiB to 64\\ MiB. The minimum is 4\\ KiB. The maximum for compression is currently 1.5\\ GiB (1536\\ MiB). The decompressor already supports dictionaries up to one byte less than 4\\ GiB, which is the maximum for the LZMA1 and LZMA2 stream formats." +msgstr "I<حجم> القاموس النموذجي يتراوح من 64\\ كيلوبايت إلى 64\\ ميجابايت. الحد الأدنى هو 4\\ كيلوبايت. الحد الأقصى للضغط حالياً هو 1.5\\ جيجابايت (1536\\ ميجابايت). يدعم برنامج ÙÙƒ الضغط Ø¨Ø§Ù„ÙØ¹Ù„ قواميس تصل إلى أقل من 4\\ جيجابايت ببايب واحد، وهو الحد الأقصى لتنسيقات تدÙÙ‚ LZMA1 Ùˆ LZMA2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Dictionary I and match finder (I) together determine the memory usage of the LZMA1 or LZMA2 encoder. The same (or bigger) dictionary I is required for decompressing that was used when compressing, thus the memory usage of the decoder is determined by the dictionary size used when compressing. The B<.xz> headers store the dictionary I either as 2^I or 2^I + 2^(I-1), so these I are somewhat preferred for compression. Other I will get rounded up when stored in the B<.xz> headers." +msgstr "يحدد I<حجم> القاموس وباحث التطابق (I) معاً مقدار استهلاك الذاكرة Ù„Ù…Ø´ÙØ± LZMA1 أو LZMA2. يتطلب ÙÙƒ الضغط Ù†ÙØ³ I<حجم> القاموس (أو أكبر) الذي Ø§Ø³ØªÙØ®Ø¯Ù… عند الضغط، وبالتالي ÙØ¥Ù† استهلاك الذاكرة Ù„ÙÙƒ الترميز يحدده حجم القاموس المستخدم أثناء الضغط. تخزن ترويسات B<.xz> I<حجم> القاموس إما كـ 2^I أو 2^I + 2^(I-1)ØŒ لذا تÙÙØ¶Ù„ هذه I<الأحجام> نوعاً ما للضغط. الأحجام الأخرى تÙقرب للأعلى عند تخزينها ÙÙŠ ترويسات B<.xz>." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the number of literal context bits. The minimum is 0 and the maximum is 4; the default is 3. In addition, the sum of I and I must not exceed 4." +msgstr "حدد عدد بتات سياق الحرو٠(literal context bits). الحد الأدنى 0 والأقصى 4Ø› الإعداد المبدئي هو 3. Ø¨Ø§Ù„Ø¥Ø¶Ø§ÙØ© إلى ذلك، يجب ألا يتجاوز مجموع I Ùˆ I العدد 4." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "All bytes that cannot be encoded as matches are encoded as literals. That is, literals are simply 8-bit bytes that are encoded one at a time." +msgstr "كل البايتات التي لا يمكن تشÙيرها كتطابقات ØªÙØ´Ùر كحرو٠(literals). أي أن الحرو٠هي ببساطة بايتات من 8 بت ØªÙØ´Ùر كل واحدة على حدة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The literal coding makes an assumption that the highest I bits of the previous uncompressed byte correlate with the next byte. For example, in typical English text, an upper-case letter is often followed by a lower-case letter, and a lower-case letter is usually followed by another lower-case letter. In the US-ASCII character set, the highest three bits are 010 for upper-case letters and 011 for lower-case letters. When I is at least 3, the literal coding can take advantage of this property in the uncompressed data." +msgstr "ÙŠÙØªØ±Ø¶ ترميز الحرو٠أن أعلى بتات I من البايت السابق غير المضغوط ترتبط بالبايت التالي. على سبيل المثال، ÙÙŠ النص الإنجليزي المعتاد، غالباً ما يتبع الحر٠الكبير حر٠صغير، والحر٠الصغير يتبعه عادةً حر٠صغير آخر. ÙÙŠ مجموعة محار٠US-ASCIIØŒ أعلى ثلاثة بتات هي 010 للحرو٠الكبيرة Ùˆ 011 للحرو٠الصغيرة. عندما تكون I على الأقل 3ØŒ يستÙيد ترميز الحرو٠من هذه الخاصية ÙÙŠ البيانات غير المضغوطة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The default value (3) is usually good. If you want maximum compression, test B. Sometimes it helps a little, and sometimes it makes compression worse. If it makes it worse, test B too." +msgstr "القيمة المبدئية (3) جيدة عادةً. إذا أردت أقصى ضغط، اختبر B. أحياناً تساعد قليلاً، وأحياناً تجعل الضغط أسوأ. إذا جعلته أسوأ، اختبر B أيضاً." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the number of literal position bits. The minimum is 0 and the maximum is 4; the default is 0." +msgstr "حدد عدد بتات موضع الحرو٠(literal position bits). الحد الأدنى 0 والأقصى 4Ø› الإعداد المبدئي هو 0." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I affects what kind of alignment in the uncompressed data is assumed when encoding literals. See I below for more information about alignment." +msgstr "تؤثر I على نوع المحاذاة Ø§Ù„Ù…ÙØªØ±Ø¶Ø© ÙÙŠ البيانات غير المضغوطة عند تشÙير الحروÙ. انظر I أدناه لمزيد من المعلومات حول المحاذاة." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the number of position bits. The minimum is 0 and the maximum is 4; the default is 2." +msgstr "حدد عدد بتات الموضع (position bits). الحد الأدنى 0 والأقصى 4Ø› الإعداد المبدئي هو 2." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I affects what kind of alignment in the uncompressed data is assumed in general. The default means four-byte alignment (2^I=2^2=4), which is often a good choice when there's no better guess." +msgstr "تؤثر I على نوع المحاذاة Ø§Ù„Ù…ÙØªØ±Ø¶Ø© ÙÙŠ البيانات غير المضغوطة بشكل عام. الإعداد المبدئي يعني محاذاة من أربعة بايتات (2^I=2^2=4)ØŒ وهو غالباً خيار جيد عند عدم وجود تخمين Ø£ÙØ¶Ù„." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When the alignment is known, setting I accordingly may reduce the file size a little. For example, with text files having one-byte alignment (US-ASCII, ISO-8859-*, UTF-8), setting B can improve compression slightly. For UTF-16 text, B is a good choice. If the alignment is an odd number like 3 bytes, B might be the best choice." +msgstr "عندما تكون المحاذاة Ù…Ø¹Ø±ÙˆÙØ©ØŒ ÙØ¥Ù† ضبط I ÙˆÙقاً لذلك قد يقلل حجم المل٠قليلاً. على سبيل المثال، مع Ù…Ù„ÙØ§Øª النصوص ذات محاذاة البايت الواحد (US-ASCIIØŒ ISO-8859-*ØŒ UTF-8)ØŒ ÙØ¥Ù† ضبط B يحسن الضغط قليلاً. لنصوص UTF-16ØŒ يعد B خياراً جيداً. إذا كانت المحاذاة رقماً ÙØ±Ø¯ÙŠØ§Ù‹ مثل 3 بايتات، Ùقد يكون B هو الخيار Ø§Ù„Ø£ÙØ¶Ù„." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Even though the assumed alignment can be adjusted with I and I, LZMA1 and LZMA2 still slightly favor 16-byte alignment. It might be worth taking into account when designing file formats that are likely to be often compressed with LZMA1 or LZMA2." +msgstr "على الرغم من إمكانية تعديل المحاذاة Ø§Ù„Ù…ÙØªØ±Ø¶Ø© باستخدام I Ùˆ IØŒ لا يزال LZMA1 Ùˆ LZMA2 ÙŠÙØ¶Ù„ان قليلاً محاذاة 16 بايت. قد يكون من الجيد أخذ ذلك ÙÙŠ الاعتبار عند تصميم تنسيقات Ø§Ù„Ù…Ù„ÙØ§Øª التي ÙŠÙØ±Ø¬Ø­ ضغطها غالباً باستخدام LZMA1 أو LZMA2." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Match finder has a major effect on encoder speed, memory usage, and compression ratio. Usually Hash Chain match finders are faster than Binary Tree match finders. The default depends on the I: 0 uses B, 1\\(en3 use B, and the rest use B." +msgstr "لباحث التطابق تأثير كبير على سرعة Ø§Ù„Ù…Ø´ÙØ±ØŒ واستهلاك الذاكرة، ونسبة الضغط. عادةً ما تكون باحثات سلسلة الهاش (Hash Chain) أسرع من باحثات الشجرة الثنائية (Binary Tree). يعتمد الإعداد المبدئي على الإعداد المسبق (I): 0 يستخدم BØŒ ومن 1 إلى 3 تستخدم BØŒ والبقية تستخدم B." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The following match finders are supported. The memory usage formulas below are rough approximations, which are closest to the reality when I is a power of two." +msgstr "باحثات التطابق التالية مدعومة. صيغ استهلاك الذاكرة أدناه هي تقريبات خشنة، تكون أقرب للواقع عندما يكون I أسّاً للعدد اثنين." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Hash Chain with 2- and 3-byte hashing" +msgstr "سلسلة هاش مع هاش 2 Ùˆ 3 بايت" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum value for I: 3" +msgstr "أقل قيمة لـ I: 3" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Memory usage:" +msgstr "استهلاك الذاكرة:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 7.5 (if I E= 16 MiB);" +msgstr "I * 7.5 (إذا كان I E= 16 ميجابايت)Ø›" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 5.5 + 64 MiB (if I E 16 MiB)" +msgstr "I * 5.5 + 64 ميجابايت (إذا كان I E 16 ميجابايت)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Hash Chain with 2-, 3-, and 4-byte hashing" +msgstr "سلسلة هاش مع هاش 2 Ùˆ 3 Ùˆ 4 بايت" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum value for I: 4" +msgstr "أقل قيمة لـ I: 4" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 7.5 (if I E= 32 MiB);" +msgstr "I * 7.5 (إذا كان I E= 32 ميجابايت)Ø›" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 6.5 (if I E 32 MiB)" +msgstr "I * 6.5 (إذا كان I E 32 ميجابايت)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Binary Tree with 2-byte hashing" +msgstr "شجرة ثنائية مع هاش 2 بايت" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Minimum value for I: 2" +msgstr "أقل قيمة لـ I: 2" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Memory usage: I * 9.5" +msgstr "استهلاك الذاكرة: I * 9.5" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Binary Tree with 2- and 3-byte hashing" +msgstr "شجرة ثنائية مع هاش 2 Ùˆ 3 بايت" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 11.5 (if I E= 16 MiB);" +msgstr "I * 11.5 (إذا كان I E= 16 ميجابايت)Ø›" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 9.5 + 64 MiB (if I E 16 MiB)" +msgstr "I * 9.5 + 64 ميجابايت (إذا كان I E 16 ميجابايت)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B" +msgstr "B" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Binary Tree with 2-, 3-, and 4-byte hashing" +msgstr "شجرة ثنائية مع هاش 2 Ùˆ 3 Ùˆ 4 بايت" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 11.5 (if I E= 32 MiB);" +msgstr "I * 11.5 (إذا كان I E= 32 ميجابايت)Ø›" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I * 10.5 (if I E 32 MiB)" +msgstr "I * 10.5 (إذا كان I E 32 ميجابايت)" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression I specifies the method to analyze the data produced by the match finder. Supported I are B and B. The default is B for I 0\\(en3 and B for I 4\\(en9." +msgstr "يحدد I<نمط> الضغط طريقة تحليل البيانات الناتجة عن باحث التطابق. الأنماط المدعومة هي B Ùˆ B. النمط المبدئي هو B للإعدادات المسبقة 0-3 Ùˆ B للإعدادات المسبقة 4-9." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Usually B is used with Hash Chain match finders and B with Binary Tree match finders. This is also what the I do." +msgstr "عادةً ما ÙŠÙØ³ØªØ®Ø¯Ù… B مع باحثات سلسلة الهاش Ùˆ B مع باحثات الشجرة الثنائية. وهذا ما ØªÙØ¹Ù„Ù‡ الإعدادات المسبقة أيضاً." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify what is considered to be a nice length for a match. Once a match of at least I bytes is found, the algorithm stops looking for possibly better matches." +msgstr "حدد ما ÙŠÙØ¹ØªØ¨Ø± طولاً جيداً (nice) للتطابق. بمجرد العثور على تطابق بطول I بايت على الأقل، تتوق٠الخوارزمية عن البحث عن تطابقات Ø£ÙØ¶Ù„ محتملة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "I can be 2\\(en273 bytes. Higher values tend to give better compression ratio at the expense of speed. The default depends on the I." +msgstr "يمكن أن يتراوح I بين 2-273 بايت. تميل القيم الأعلى لإعطاء نسبة ضغط Ø£ÙØ¶Ù„ على حساب السرعة. يعتمد الإعداد المبدئي على الإعداد المسبق." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the maximum search depth in the match finder. The default is the special value of 0, which makes the compressor determine a reasonable I from I and I." +msgstr "حدد أقصى عمق للبحث ÙÙŠ باحث التطابق. القيمة المبدئية هي القيمة الخاصة 0ØŒ التي تجعل الضاغط يحدد عمقاً (I) معقولاً بناءً على I Ùˆ I." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Reasonable I for Hash Chains is 4\\(en100 and 16\\(en1000 for Binary Trees. Using very high values for I can make the encoder extremely slow with some files. Avoid setting the I over 1000 unless you are prepared to interrupt the compression in case it is taking far too long." +msgstr "العمق (I) المعقول لسلاسل الهاش هو 4-100 وللأشجار الثنائية هو 16-1000. استخدام قيم عالية جداً لـ I قد يجعل Ø§Ù„Ù…Ø´ÙØ± بطيئاً للغاية مع بعض Ø§Ù„Ù…Ù„ÙØ§Øª. تجنب ضبط I Ùوق 1000 إلا إذا كنت مستعداً لمقاطعة عملية الضغط ÙÙŠ حال استغرقت وقتاً طويلاً جداً." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When decoding raw streams (B<--format=raw>), LZMA2 needs only the dictionary I. LZMA1 needs also I, I, and I." +msgstr "عند ÙÙƒ ترميز التدÙقات الخام (B<--format=raw>)ØŒ يحتاج LZMA2 Ùقط إلى I<حجم> القاموس. يحتاج LZMA1 أيضاً إلى I Ùˆ I Ùˆ I." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--x86>[B<=>I]" +msgstr "B<--x86>[B<=>I<خيارات>]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--arm>[B<=>I]" +msgstr "B<--arm>[B<=>I<خيارات>]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--armthumb>[B<=>I]" +msgstr "B<--armthumb>[B<=>I<خيارات>]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--arm64>[B<=>I]" +msgstr "B<--arm64>[B<=>I<خيارات>]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--powerpc>[B<=>I]" +msgstr "B<--powerpc>[B<=>I<خيارات>]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--ia64>[B<=>I]" +msgstr "B<--ia64>[B<=>I<خيارات>]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--sparc>[B<=>I]" +msgstr "B<--sparc>[B<=>I<خيارات>]" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--riscv>[B<=>I]" +msgstr "B<--riscv>[B<=>I<خيارات>]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Add a branch/call/jump (BCJ) filter to the filter chain. These filters can be used only as a non-last filter in the filter chain." +msgstr "أض٠مرشح ÙØ±Ø¹/استدعاء/Ù‚ÙØ² (BCJ) إلى تسلسل المرشحات. يمكن استخدام هذه المرشحات Ùقط كمرشح غير أخير ÙÙŠ تسلسل المرشحات." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "A BCJ filter converts relative addresses in the machine code to their absolute counterparts. This doesn't change the size of the data but it increases redundancy, which can help LZMA2 to produce 0\\(en15\\ % smaller B<.xz> file. The BCJ filters are always reversible, so using a BCJ filter for wrong type of data doesn't cause any data loss, although it may make the compression ratio slightly worse. The BCJ filters are very fast and use an insignificant amount of memory." +msgstr "يقوم مرشح BCJ بتحويل العناوين النسبية ÙÙŠ كود الآلة إلى نظرائها المطلقة. هذا لا يغير حجم البيانات ولكنه يزيد التكرار، مما يساعد LZMA2 على إنتاج مل٠B<.xz> أصغر بنسبة 0-15%. مرشحات BCJ دائماً قابلة للعكس، لذا ÙØ¥Ù† استخدام مرشح BCJ لنوع خاطئ من البيانات لا يسبب أي Ùقدان للبيانات، رغم أنه قد يجعل نسبة الضغط أسوأ قليلاً. مرشحات BCJ سريعة جداً وتستهلك كمية ضئيلة من الذاكرة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "These BCJ filters have known problems related to the compression ratio:" +msgstr "هناك مشاكل Ù…Ø¹Ø±ÙˆÙØ© لمرشحات BCJ تتعلق بنسبة الضغط:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Some types of files containing executable code (for example, object files, static libraries, and Linux kernel modules) have the addresses in the instructions filled with filler values. These BCJ filters will still do the address conversion, which will make the compression worse with these files." +msgstr "بعض أنواع Ø§Ù„Ù…Ù„ÙØ§Øª التي تحتوي على كود قابل للتنÙيذ (مثل Ù…Ù„ÙØ§Øª الكائنات، والمكتبات الساكنة، ووحدات نواة Linux) تحتوي على عناوين ÙÙŠ التعليمات مملوءة بقيم حشو. ستستمر مرشحات BCJ هذه ÙÙŠ إجراء تحويل العناوين، مما يجعل الضغط أسوأ مع هذه Ø§Ù„Ù…Ù„ÙØ§Øª." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "If a BCJ filter is applied on an archive, it is possible that it makes the compression ratio worse than not using a BCJ filter. For example, if there are similar or even identical executables then filtering will likely make the files less similar and thus compression is worse. The contents of non-executable files in the same archive can matter too. In practice one has to try with and without a BCJ filter to see which is better in each situation." +msgstr "إذا Ø·ÙØ¨Ù‚ مرشح BCJ على Ø£Ø±Ø´ÙŠÙØŒ Ùمن المحتمل أن يجعل نسبة الضغط أسوأ مما لو لم ÙŠÙØ³ØªØ®Ø¯Ù…. على سبيل المثال، إذا كانت هناك Ù…Ù„ÙØ§Øª تنÙيذية متشابهة أو حتى متطابقة، ÙØ¥Ù† الترشيح سيجعل Ø§Ù„Ù…Ù„ÙØ§Øª أقل تشابهاً وبالتالي يكون الضغط أسوأ. محتويات Ø§Ù„Ù…Ù„ÙØ§Øª غير القابلة للتنÙيذ ÙÙŠ Ù†ÙØ³ الأرشي٠قد تؤثر أيضاً. ÙÙŠ الممارسة العملية، يجب التجربة مع وبدون مرشح BCJ Ù„Ù…Ø¹Ø±ÙØ© أيهما Ø£ÙØ¶Ù„ ÙÙŠ كل حالة." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Different instruction sets have different alignment: the executable file must be aligned to a multiple of this value in the input data to make the filter work." +msgstr "مجموعات التعليمات Ø§Ù„Ù…Ø®ØªÙ„ÙØ© لها محاذاة Ù…Ø®ØªÙ„ÙØ©: يجب محاذاة المل٠القابل للتنÙيذ إلى مضاع٠لهذه القيمة ÙÙŠ بيانات الإدخال ليعمل المرشح." + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Filter" +msgstr "المرشح" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Alignment" +msgstr "المحاذاة" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Notes" +msgstr "ملاحظات" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "x86" +msgstr "x86" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "32-bit or 64-bit x86" +msgstr "32-بت أو 64-بت x86" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "ARM" +msgstr "ARM" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "ARM-Thumb" +msgstr "ARM-Thumb" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "ARM64" +msgstr "ARM64" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "4096-byte alignment is best" +msgstr "محاذاة 4096 بايت هي Ø§Ù„Ø£ÙØ¶Ù„" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "PowerPC" +msgstr "PowerPC" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Big endian only" +msgstr "Big endian Ùقط" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "IA-64" +msgstr "IA-64" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "16" +msgstr "16" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "Itanium" +msgstr "Itanium" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "SPARC" +msgstr "SPARC" + +#. type: tbl table +#: ../src/xz/xz.1 +#, no-wrap +msgid "RISC-V" +msgstr "RISC-V" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Since the BCJ-filtered data is usually compressed with LZMA2, the compression ratio may be improved slightly if the LZMA2 options are set to match the alignment of the selected BCJ filter. Examples:" +msgstr "بما أن البيانات المرشحة بـ BCJ ØªÙØ¶ØºØ· عادةً باستخدام LZMA2ØŒ Ùقد تتحسن نسبة الضغط قليلاً إذا Ø¶ÙØ¨Ø·Øª خيارات LZMA2 لتناسب محاذاة مرشح BCJ المختار. أمثلة:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "IA-64 filter has 16-byte alignment so B is good with LZMA2 (2^4=16)." +msgstr "مرشح IA-64 له محاذاة 16 بايت، لذا B جيد مع LZMA2 (2^4=16)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "RISC-V code has 2-byte or 4-byte alignment depending on whether the file contains 16-bit compressed instructions (the C extension). When 16-bit instructions are used, B or B is good. When 16-bit instructions aren't present, B is the best. B can be used to check if \"RVC\" appears on the \"Flags\" line." +msgstr "كود RISC-V له محاذاة 2 بايت أو 4 بايت اعتماداً على ما إذا كان المل٠يحتوي على تعليمات مضغوطة بـ 16 بت (ملحق C). عند استخدام تعليمات 16 بت، يكون B أو B جيداً. عند عدم وجود تعليمات 16 بت، يكون B هو Ø§Ù„Ø£ÙØ¶Ù„. يمكن استخدام B للتحقق مما إذا كانت \"RVC\" تظهر ÙÙŠ سطر \"Flags\"." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "ARM64 is always 4-byte aligned so B is the best." +msgstr "ARM64 دائماً محاذى لـ 4 بايت لذا B هو Ø§Ù„Ø£ÙØ¶Ù„." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The x86 filter is an exception. It's usually good to stick to LZMA2's defaults (B) when compressing x86 executables." +msgstr "مرشح x86 استثناء. من الجيد عادةً الالتزام بإعدادات LZMA2 المبدئية (B) عند ضغط Ù…Ù„ÙØ§Øª x86 التنÙيذية." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "All BCJ filters support the same I:" +msgstr "كل مرشحات BCJ تدعم Ù†ÙØ³ الـ I<خيارات>:" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI<إزاحة>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the start I that is used when converting between relative and absolute addresses. The I must be a multiple of the alignment of the filter (see the table above). The default is zero. In practice, the default is good; specifying a custom I is almost never useful." +msgstr "حدد I<إزاحة> البداية المستخدمة عند التحويل بين العناوين النسبية والمطلقة. يجب أن تكون الـ I<إزاحة> Ù…Ø¶Ø§Ø¹ÙØ§Ù‹ لمحاذاة المرشح (انظر الجدول أعلاه). القيمة المبدئية هي ØµÙØ±. عملياً، القيمة المبدئية جيدة؛ تحديد I<إزاحة> مخصصة ليس Ù…Ùيداً تقريباً." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--delta>[B<=>I]" +msgstr "B<--delta>[B<=>I<خيارات>]" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Add the Delta filter to the filter chain. The Delta filter can be only used as a non-last filter in the filter chain." +msgstr "أض٠مرشح دلتا إلى تسلسل المرشحات. يمكن استخدام مرشح دلتا Ùقط كمرشح غير أخير ÙÙŠ تسلسل المرشحات." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Currently only simple byte-wise delta calculation is supported. It can be useful when compressing, for example, uncompressed bitmap images or uncompressed PCM audio. However, special purpose algorithms may give significantly better results than Delta + LZMA2. This is true especially with audio, which compresses faster and better, for example, with B(1)." +msgstr "حالياً، الحساب البسيط للدلتا لكل بايت هو المدعوم Ùقط. يمكن أن يكون Ù…Ùيداً عند ضغط صور bitmap غير المضغوطة أو صوت PCM غير المضغوط مثلاً. ومع ذلك، قد تعطي خوارزميات مخصصة نتائج Ø£ÙØ¶Ù„ بكثير من دلتا + LZMA2. هذا ينطبق بشكل خاص على الصوت، الذي ÙŠÙØ¶ØºØ· بشكل أسرع ÙˆØ£ÙØ¶Ù„ باستخدام B(1) مثلاً." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Supported I:" +msgstr "الـ I<خيارات> المدعومة:" + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "BI" +msgstr "BI<Ù…Ø³Ø§ÙØ©>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Specify the I of the delta calculation in bytes. I must be 1\\(en256. The default is 1." +msgstr "حدد I<Ù…Ø³Ø§ÙØ©> حساب الدلتا بالبايت. يجب أن تكون الـ I<Ù…Ø³Ø§ÙØ©> 1-256. القيمة المبدئية هي 1." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "For example, with B and eight-byte input A1 B1 A2 B3 A3 B5 A4 B7, the output will be A1 B1 01 02 01 02 01 02." +msgstr "على سبيل المثال، مع B ومدخلات من ثمانية بايتات A1 B1 A2 B3 A3 B5 A4 B7ØŒ سيكون المخرج A1 B1 01 02 01 02 01 02." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "Other options" +msgstr "خيارات أخرى" + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-q>, B<--quiet>" +msgstr "B<-q>, B<--quiet>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Suppress warnings and notices. Specify this twice to suppress errors too. This option has no effect on the exit status. That is, even if a warning was suppressed, the exit status to indicate a warning is still used." +msgstr "اكتم التحذيرات والملاحظات. حدد هذا الخيار مرتين لكتم الأخطاء أيضاً. ليس لهذا الخيار تأثير على حالة الخروج. أي أنه حتى لو ÙƒÙØªÙ… التحذير، ÙØ³ØªØ¸Ù„ حالة الخروج التي تشير لوعود تحذير مستخدمة." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-v>, B<--verbose>" +msgstr "B<-v>, B<--verbose>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Be verbose. If standard error is connected to a terminal, B will display a progress indicator. Specifying B<--verbose> twice will give even more verbose output." +msgstr "كن مسهباً. إذا كان الخطأ القياسي متصلاً بطرÙية، سيعرض B مؤشر تقدم. تحديد B<--verbose> مرتين سيعطي مخرجات أكثر إسهاباً." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The progress indicator shows the following information:" +msgstr "يعرض مؤشر التقدم المعلومات التالية:" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Completion percentage is shown if the size of the input file is known. That is, the percentage cannot be shown in pipes." +msgstr "تظهر نسبة الإكمال إذا كان حجم مل٠الإدخال Ù…Ø¹Ø±ÙˆÙØ§Ù‹. أي أن النسبة لا يمكن عرضها ÙÙŠ الأنابيب (pipes)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of compressed data produced (compressing) or consumed (decompressing)." +msgstr "كمية البيانات المضغوطة المنتجة (عند الضغط) أو المستهلكة (عند ÙÙƒ الضغط)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Amount of uncompressed data consumed (compressing) or produced (decompressing)." +msgstr "كمية البيانات غير المضغوطة المستهلكة (عند الضغط) أو المنتجة (عند ÙÙƒ الضغط)." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression ratio, which is calculated by dividing the amount of compressed data processed so far by the amount of uncompressed data processed so far." +msgstr "نسبة الضغط، ÙˆØªÙØ­Ø³Ø¨ بقسمة كمية البيانات المضغوطة المعالجة حتى الآن على كمية البيانات غير المضغوطة المعالجة حتى الآن." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Compression or decompression speed. This is measured as the amount of uncompressed data consumed (compression) or produced (decompression) per second. It is shown after a few seconds have passed since B started processing the file." +msgstr "سرعة الضغط أو ÙÙƒ الضغط. تÙقاس بكمية البيانات غير المضغوطة المستهلكة (ضغط) أو المنتجة (ÙÙƒ ضغط) ÙÙŠ الثانية. تظهر بعد مرور بضع ثوان٠على بدء B ÙÙŠ معالجة الملÙ." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Elapsed time in the format M:SS or H:MM:SS." +msgstr "الوقت المنقضي بتنسيق M:SS أو H:MM:SS." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Estimated remaining time is shown only when the size of the input file is known and a couple of seconds have already passed since B started processing the file. The time is shown in a less precise format which never has any colons, for example, 2 min 30 s." +msgstr "يظهر الوقت المتبقي المقدر Ùقط عندما يكون حجم مل٠الإدخال Ù…Ø¹Ø±ÙˆÙØ§Ù‹ وبعد مرور ثانيتين على بدء B ÙÙŠ معالجة الملÙ. يظهر الوقت بتنسيق أقل دقة لا يحتوي أبداً على نقطتين رأسيتين، مثلاً، 2 min 30 s." + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "When standard error is not a terminal, B<--verbose> will make B print the filename, compressed size, uncompressed size, compression ratio, and possibly also the speed and elapsed time on a single line to standard error after compressing or decompressing the file. The speed and elapsed time are included only when the operation took at least a few seconds. If the operation didn't finish, for example, due to user interruption, also the completion percentage is printed if the size of the input file is known." +msgstr "عندما لا يكون الخطأ القياسي طرÙية، سيجعل B<--verbose> أداة B تطبع اسم Ø§Ù„Ù…Ù„ÙØŒ والحجم المضغوط، والحجم غير المضغوط، ونسبة الضغط، وربما أيضاً السرعة والوقت المنقضي ÙÙŠ سطر واحد إلى الخطأ القياسي بعد ضغط أو ÙÙƒ ضغط الملÙ. ØªÙØ¯Ø±Ø¬ السرعة والوقت المنقضي Ùقط عندما تستغرق العملية بضع ثوان٠على الأقل. إذا لم تنته٠العملية، بسبب مقاطعة المستخدم مثلاً، ØªÙØ·Ø¨Ø¹ أيضاً نسبة الإكمال إذا كان حجم مل٠الإدخال Ù…Ø¹Ø±ÙˆÙØ§Ù‹." + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-Q>, B<--no-warn>" +msgstr "B<-Q>, B<--no-warn>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Don't set the exit status to 2 even if a condition worth a warning was detected. This option doesn't affect the verbosity level, thus both B<--quiet> and B<--no-warn> have to be used to not display warnings and to not alter the exit status." +msgstr "لا تضبط حالة الخروج على 2 حتى لو Ø§ÙƒØªÙØ´Ùت حالة تستحق التحذير. لا يؤثر هذا الخيار على مستوى الإسهاب، لذا يجب استخدام كل من B<--quiet> Ùˆ B<--no-warn> معاً لعدم عرض التحذيرات وعدم تغيير حالة الخروج." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--robot>" +msgstr "B<--robot>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Print messages in a machine-parsable format. This is intended to ease writing frontends that want to use B instead of liblzma, which may be the case with various scripts. The output with this option enabled is meant to be stable across B releases. See the section B for details." +msgstr "اطبع الرسائل بتنسيق قابل للتحليل آلياً. الهد٠من ذلك هو تسهيل كتابة واجهات تريد استخدام B بدلاً من liblzmaØŒ كما قد يكون الحال مع السكربتات Ø§Ù„Ù…Ø®ØªÙ„ÙØ©. المخرجات مع تمكين هذا الخيار ÙŠÙÙØªØ±Ø¶ أن تكون مستقرة عبر إصدارات B. انظر قسم B Ù„Ù„ØªÙØ§ØµÙŠÙ„." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<--info-memory>" +msgstr "B<--info-memory>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display, in human-readable format, how much physical memory (RAM) and how many processor threads B thinks the system has and the memory usage limits for compression and decompression, and exit successfully." +msgstr "اعرض، بتنسيق قابل للقراءة البشرية، مقدار الذاكرة Ø§Ù„ÙØ¹Ù„ية (RAM) وعدد خيوط المعالج التي يعتقد B أن النظام يمتلكها وحدود استهلاك الذاكرة للضغط ÙˆÙÙƒ الضغط، واخرج بنجاح." + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-h>, B<--help>" +msgstr "B<-h>, B<--help>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display a help message describing the most commonly used options, and exit successfully." +msgstr "اعرض رسالة مساعدة تص٠الخيارات الأكثر استخداماً، واخرج بنجاح." + +#. type: TP +#: ../src/xz/xz.1 +#, no-wrap +msgid "B<-H>, B<--long-help>" +msgstr "B<-H>, B<--long-help>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display a help message describing all features of B, and exit successfully" +msgstr "اعرض رسالة مساعدة ØªØµÙ ÙƒØ§ÙØ© ميزات BØŒ واخرج بنجاح" + +#. type: TP +#: ../src/xz/xz.1 ../src/xzdec/xzdec.1 +#, no-wrap +msgid "B<-V>, B<--version>" +msgstr "B<-V>, B<--version>" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "Display the version number of B and liblzma in human readable format. To get machine-parsable output, specify B<--robot> before B<--version>." +msgstr "اعرض رقم إصدار B Ùˆ liblzma بتنسيق قابل للقراءة البشرية. للحصول على مخرج قابل للتحليل آلياً، حدد B<--robot> قبل B<--version>." + +#. type: SH +#: ../src/xz/xz.1 +#, no-wrap +msgid "ROBOT MODE" +msgstr "نمط الروبوت" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "The robot mode is activated with the B<--robot> option. It makes the output of B easier to parse by other programs. Currently B<--robot> is supported only together with B<--list>, B<--filters-help>, B<--info-memory>, and B<--version>. It will be supported for compression and decompression in the future." +msgstr "ÙŠÙÙØ¹Ù„ نمط الروبوت باستخدام خيار B<--robot>. Ùهو يجعل مخرجات B أسهل ÙÙŠ التحليل بواسطة البرامج الأخرى. حالياً B<--robot> مدعوم Ùقط مع B<--list> Ùˆ B<--filters-help> Ùˆ B<--info-memory> Ùˆ B<--version>. ÙˆØ³ÙŠÙØ¯Ø¹Ù… للضغط ÙˆÙÙƒ الضغط مستقبلاً." + +#. type: SS +#: ../src/xz/xz.1 +#, no-wrap +msgid "List mode" +msgstr "نمط القائمة" + +#. type: Plain text +#: ../src/xz/xz.1 +msgid "B uses tab-separated output. The first column of every line has a string that indicates the type of the information found on that line:" +msgstr "تستخدم B مخرجات Ù…ÙØµÙˆÙ„Ø© بعلامات جدولة (tabs). يحتوي العمود الأول من كل سطر على سلسلة نصية تشير إلى نوع المعلومات الموجودة ÙÙŠ ذلك السطر:" + +#. TRANSLATORS: The bold strings B, B, B, B, +#. B